From 4836adafd69f53c9c02de9b4dca687b4cf045892 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 6 Sep 2026 15:31:29 +0000 Subject: [PATCH] chore: use Response.json in edge functions, drop two dead declarations Response.json sets the JSON content type itself, so three hand-rolled wrappers that stringified a body and spread in a Content-Type header can delegate to it. Call sites are unchanged. Two behavioural differences exist in principle, and neither is reachable here: - Response.json(undefined) throws a TypeError, where the old form produced an empty body. Both remaining wrappers are typed `unknown`, so this was worth checking: every one of the 12 call sites in import-source and the 3 in announcements passes an object literal, never a possibly-undefined value. - Response.json defers to a caller-supplied content-type, where the old form always overrode it. No getCorsHeaders in this repo returns one. Verified under Deno 2.9.6 that the content type is exactly "application/json" with no charset parameter, matching the old form byte for byte. Also deletes two declarations with no references: - _shared/cors.ts, a wildcard Access-Control-Allow-Origin header set with no importer, no import-map alias, and no config.toml entry. Every function defines its own getCorsHeaders origin allowlist instead, so this file was a misleading leftover. _shared/native-cors.test.ts is unaffected: it iterates a hardcoded list of function names and reads ..//index.ts as text, so it never enumerates _shared or asserts on this file. - the local Source type in ai/index.ts, never exported and never used. Verified on main fe679fd, from a clean npm ci: docs:check, lint, typecheck, 956 unit tests, 121 edge tests, deno check on the 4 touched function entrypoints, build, and 126 Chromium e2e tests pass. --- supabase/functions/_shared/cors.ts | 5 ----- supabase/functions/ai-stream/index.ts | 5 +---- supabase/functions/ai/index.ts | 7 ------- supabase/functions/announcements/index.ts | 5 +---- supabase/functions/import-source/index.ts | 5 +---- 5 files changed, 3 insertions(+), 24 deletions(-) delete mode 100644 supabase/functions/_shared/cors.ts diff --git a/supabase/functions/_shared/cors.ts b/supabase/functions/_shared/cors.ts deleted file mode 100644 index 3473e0b17..000000000 --- a/supabase/functions/_shared/cors.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const corsHeaders = { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type", - "Access-Control-Allow-Methods": "POST, OPTIONS", -}; diff --git a/supabase/functions/ai-stream/index.ts b/supabase/functions/ai-stream/index.ts index 3e875e808..3c5aa589c 100644 --- a/supabase/functions/ai-stream/index.ts +++ b/supabase/functions/ai-stream/index.ts @@ -81,10 +81,7 @@ function getProviderForModel(model: string): "openai" | "google" | "anthropic" | } function jsonResponse(body: Record, status: number, corsHeaders: Record) { - return new Response(JSON.stringify(body), { - status, - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }); + return Response.json(body, { status, headers: corsHeaders }); } function sse(event: string, payload: Record) { diff --git a/supabase/functions/ai/index.ts b/supabase/functions/ai/index.ts index 1cfe8b675..227c27a2b 100644 --- a/supabase/functions/ai/index.ts +++ b/supabase/functions/ai/index.ts @@ -27,13 +27,6 @@ function getCorsHeaders(origin: string | null) { type Feature = "generate" | "attack" | "brainstorm" | "factoids" | "ask" | "sparring" | "crossfire"; -type Source = { - title: string; - content: string; - origin?: string; - type: string; -}; - // Generate unique request ID for tracing function generateRequestId(): string { return `edge_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`; diff --git a/supabase/functions/announcements/index.ts b/supabase/functions/announcements/index.ts index b61382a45..af0154a95 100644 --- a/supabase/functions/announcements/index.ts +++ b/supabase/functions/announcements/index.ts @@ -23,10 +23,7 @@ function getCorsHeaders(origin: string | null) { } function json(data: unknown, status: number, corsHeaders: Record) { - return new Response(JSON.stringify(data), { - status, - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }); + return Response.json(data, { status, headers: corsHeaders }); } Deno.serve(async (req) => { diff --git a/supabase/functions/import-source/index.ts b/supabase/functions/import-source/index.ts index 9e7203b9f..e6f5977b0 100644 --- a/supabase/functions/import-source/index.ts +++ b/supabase/functions/import-source/index.ts @@ -33,10 +33,7 @@ const supabaseServiceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!; const supabase = createClient(supabaseUrl, supabaseServiceKey); function jsonResponse(body: unknown, status: number, headers: Record) { - return new Response(JSON.stringify(body), { - status, - headers: { ...headers, "Content-Type": "application/json" }, - }); + return Response.json(body, { status, headers }); } async function isUserBanned(userId: string): Promise {