Skip to content

Shared Kit (_shared)

Every Edge Function is built from the same reusable utilities in supabase/functions/_shared/. Unit tests are co-located in _shared/tests/ (auth.test.ts, cors.test.ts, errors.test.ts, response.test.ts). @supabase/supabase-js is pinned to 2.30.0.

Modules

FileKey exportsUse
cors.tscorsHeaders, handleCors(req)First line of every EF: returns a preflight Response or null.
auth.tsrequireAuth(req), requireAdmin(req), optionalAuth(req), AuthResult, OptionalAuthResultResolve { user, serviceClient }; enforce JWT / admin role.
errors.tsAppError + ValidationError, AuthError, ForbiddenError, NotFoundError, ConflictError, RateLimitError, UnprocessableError, PartialSuccessError, DatabaseError, TimeoutErrorTyped, status-mapped errors. Throw these; err() maps them.
response.tsok(data, init?), err(functionName, error)Uniform JSON responses; err() produces safe messages + structured logs.
logging.tsLogger, LoggerConfigStructured JSON logs with an event field on INFO/WARN.
error-handler.tsisRetryableError, formatErrorResponse, logErrorCorrelation-id error formatting + retry classification (Type B).
database.tsgetSupabaseClient, insertLogEntry, insertCronExecution, insertCacheOperation, getActiveCronJobs, batchInsert, batchUpdate, getJobByNameOps-table helpers used by public_page_ops_* Type B functions.
cloudflare.tscloudflare (purge API), PurgeResultCloudflare cache purge/invalidation from EFs.
config-cache.tsconfigCache, FeatureConfigIn-memory feature-config cache for hot paths.
retry.tsretryWithBackoff<T>(...)Exponential-backoff retry for external calls (Type B / webhooks).

Typed errors → HTTP status

Canonical usage

ts
import { handleCors } from '../_shared/cors.ts'
import { requireAuth } from '../_shared/auth.ts'
import { ValidationError } from '../_shared/errors.ts'
import { ok, err } from '../_shared/response.ts'

Deno.serve(async (req) => {
  const preflight = handleCors(req); if (preflight) return preflight
  try {
    const { user, serviceClient } = await requireAuth(req)
    const body = await req.json()
    if (!body.action) throw new ValidationError('action is required.')
    // ...business logic (complex parts in helpers.ts)
    return ok({ result })
  } catch (e) {
    return err('manage-profile', e)
  }
})

manage-profile/index.ts is the closest current reference for the auth block. See Backend architecture for the Type A / B / Webhook model and Adding an Edge Function for the full recipe.