Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/cors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,35 @@ describe('isCorsDisabled', () => {
})

describe('addCorsHeaders', () => {
it.each([
undefined,
'default',
{ headers: { 'Access-Control-Allow-Origin': 'https://example.com' } },
] as const)(
'preserves network error responses with CORS config %j',
(config) => {
const response = Response.error()
const result = addCorsHeaders(response, config)

expect(result).toBe(response)
expect(result.type).toBe('error')
expect(result.status).toBe(0)
expect(result.headers.get('Access-Control-Allow-Origin')).toBeNull()
},
)

it.each([400, 500])(
'still adds CORS headers to HTTP %i responses',
async (status) => {
const response = new Response('upstream failure', { status })
const result = addCorsHeaders(response)

expect(result.status).toBe(status)
expect(result.headers.get('Access-Control-Allow-Origin')).toBe('*')
expect(await result.text()).toBe('upstream failure')
},
)

it('adds default CORS headers to response', () => {
const response = new Response('ok')
const result = addCorsHeaders(response, true)
Expand Down
7 changes: 4 additions & 3 deletions src/cors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,20 @@ export function buildCorsHeaders(config?: CorsConfig): Record<string, string> {
* Returns a new `Response` with CORS headers appended.
*
* Creates a clone of the original response and sets each CORS header on it.
* If CORS is disabled (`'disabled'` or the deprecated `false`), returns the original response unchanged.
* If CORS is disabled (`'disabled'` or the deprecated `false`), or the response
* represents a network error, returns the original response unchanged.
*
* @param response - The original response to augment.
* @param config - The CORS configuration.
* @returns A new `Response` with CORS headers set, or the original response if CORS is disabled.
* @returns A new `Response` with CORS headers set, or the original response if CORS is disabled or it represents a network error.
*
* @internal
*/
export function addCorsHeaders(
response: Response,
config?: CorsConfig,
): Response {
if (isCorsDisabled(config)) return response
if (isCorsDisabled(config) || response.type === 'error') return response

const corsHeaders = buildCorsHeaders(config)
const newResponse = new Response(response.body, response)
Expand Down
18 changes: 18 additions & 0 deletions src/with-supabase.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,24 @@ describe('withSupabase', () => {
})
})

it.each(['handler', 'pipeline'] as const)(
'preserves network error responses in %s composition',
async (composition) => {
const response = Response.error()
const config = { auth: 'none', env: baseEnv } as const
const next = async () => response
const handler =
composition === 'pipeline'
? pipeline([withSupabase(config)], next)
: withSupabase(config, next)

const result = await handler(new Request('http://localhost'))

expect(result).toBe(response)
expect(result.type).toBe('error')
},
)

it('adds CORS headers to success response', async () => {
const handler = withSupabase({ auth: 'none', env: baseEnv }, async () =>
Response.json({ ok: true }),
Expand Down
Loading