{
  "markdown": "# @supabase/server\n\n[![License](https://img.shields.io/npm/l/nx.svg?style=flat-square)](./LICENSE)\n[![Package](https://img.shields.io/npm/v/@supabase/server)](https://www.npmjs.com/package/@supabase/server)\n[![pkg.pr.new](https://pkg.pr.new/badge/supabase/server)](https://pkg.pr.new/~/supabase/server)\n[![Docs](https://img.shields.io/badge/docs-supabase.github.io-3ECF8E?logo=readthedocs&logoColor=white)](https://supabase.github.io/server/)\n\n> **v1.X — Public Beta.** First stable release under SemVer: breaking changes only ship as a major bump. The package is still early — expect new adapters, ergonomic improvements, and features to land frequently in minor releases. Found a rough edge? [Open an issue](https://github.com/supabase/server/issues) or [submit a PR](https://github.com/supabase/server/blob/main/CONTRIBUTING.md).\n\n> **Coming from a `0.x` release?** See [MIGRATION.md](MIGRATION.md) for the v0 → v1 rename map (`allow` → `auth`, `'public'` → `'publishable'`, `authType` → `authMode`, `claims` → `jwtClaims`, …).\n\n`@supabase/server` gives you batteries included access to the\n[supabase-js SDK](https://github.com/supabase/supabase-js), including client\ncreation and authentication automatically scoped to the inbound requests to your\nEdge Functions and APIs.\n\n```ts\nimport { withSupabase } from '@supabase/server'\n\nexport default {\n  fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => {\n    // RLS-scoped — this user only sees their own favorites\n    const { data: myGames } = await ctx.supabase.from('favorite_games').select()\n    return Response.json(myGames)\n  }),\n}\n```\n\nOne import. One line of config. Auth is validated, clients are ready, CORS is handled. Your handler only runs on successful auth.\n\n## Installation\n\n```bash\n# Deno / Supabase Edge Functions (no install — import directly)\nimport { withSupabase } from \"npm:@supabase/server\";\n\n# npm\nnpm install @supabase/server\n\n# pnpm\npnpm add @supabase/server\n```\n\n### AI coding skills\n\nInstall the skill so your AI coding agent (Claude Code, Cursor, etc.) knows how to use this package:\n\n```bash\nnpx skills add supabase/server\n```\n\n## Quick Start\n\nImagine you're building an app where users track their favorite games. They sign in and manage their own list. Pre-login screens browse the public catalog. An admin dashboard curates featured titles. A cron job refreshes the \"popular this week\" rankings. Here's how each piece looks:\n\n### Authenticated endpoint\n\n```ts\n// A signed-in user fetches their favorite games.\nexport default {\n  fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => {\n    const { supabase, supabaseAdmin, userClaims, jwtClaims, authMode } = ctx\n    // supabase       — RLS-scoped to the authenticated user\n    // supabaseAdmin  — bypasses RLS (service role)\n    // userClaims     — user identity from JWT (id, email, role)\n    // jwtClaims      — full JWT claims\n    // authMode       — which auth mode matched\n\n    // RLS-scoped — this user only sees their own favorites\n    const { data: myGames } = await supabase.from('favorite_games').select()\n    return Response.json(myGames)\n  }),\n}\n```\n\n### Public endpoint (no auth)\n\n```ts\n// The frontend hits this before showing the login screen.\n// auth: 'none' means no credentials required.\nexport default {\n  fetch: withSupabase({ auth: 'none' }, async (_req, _ctx) => {\n    return Response.json({ status: 'ok' })\n  }),\n}\n```\n\n### Publishable-key endpoint\n\n```ts\n// The mobile app browses the game catalog before the user signs in.\n// auth: 'publishable' validates the apikey header against the 'default' publishable key —\n// gating the endpoint to your own clients while staying anonymous to the DB.\nexport default {\n  fetch: withSupabase({ auth: 'publishable' }, async (_req, ctx) => {\n    // ctx.supabase  — anonymous (anon role); RLS still applies\n    // ctx.userClaims, ctx.jwtClaims — null (no JWT)\n    // ctx.authMode === 'publishable', ctx.authKeyName === 'default'\n    const { data: catalog } = await ctx.supabase\n      .from('games')\n      .select('id, name, cover_url')\n    return Response.json(catalog)\n  }),\n}\n```\n\nThe mobile app sends the publishable key in the `apikey` header:\n\n```ts\nconst catalogEndpoint = 'https://<project>.supabase.co/functions/v1/catalog'\nconst publishableKey = 'sb_publishable_...'\n\nawait fetch(catalogEndpoint, { headers: { apikey: publishableKey } })\n```\n\n> Unlike `auth: 'secret'`, the `supabase` client here is anonymous, not admin — RLS is the source of truth for what's visible. The publishable key acts as a coarse \"this request came from a known client\" gate; it isn't a user identity.\n\n### API key protected\n\n```ts\n// An admin dashboard fetches the list of featured games to curate.\n// auth: 'secret' validates the apikey header against the 'default' secret key\n// (not a user JWT) — supabaseAdmin bypasses RLS.\nexport default {\n  fetch: withSupabase({ auth: 'secret' }, async (_req, ctx) => {\n    const { data: featuredGames } = await ctx.supabaseAdmin\n      .from('featured_games')\n      .select()\n    return Response.json(featuredGames)\n  }),\n}\n```\n\n### Dual auth (user or service)\n\n```ts\n// Users view their own play stats from the app (JWT).\n// A backend service pulls stats for any user (secret key + user_id in body).\nexport default {\n  fetch: withSupabase({ auth: ['user', 'secret'] }, async (req, ctx) => {\n    const callerIsUser = ctx.authMode === 'user'\n\n    if (callerIsUser) {\n      // RLS-scoped — the database enforces \"own stats only\"\n      const { data: myStats } = await ctx.supabase.from('play_stats').select()\n      return Response.json(myStats)\n    }\n\n    // Service path — bypass RLS to pull stats for any user\n    const { user_id } = await req.json()\n    const { data: playStats } = await ctx.supabaseAdmin\n      .from('play_stats')\n      .select()\n      .eq('user_id', user_id)\n    return Response.json(playStats)\n  }),\n}\n```\n\n### Server-to-server\n\n```ts\n// A cron job refreshes the \"popular this week\" list every hour.\n// Named key (\"cron\") so it can be rotated without touching other services.\nexport default {\n  fetch: withSupabase({ auth: 'secret:cron' }, async (_req, ctx) => {\n    const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)\n    const { data: popularThisWeek } = await ctx.supabaseAdmin.rpc(\n      'get_most_favorited_since',\n      { since: oneWeekAgo.toISOString(), limit_count: 10 },\n    )\n    await ctx.supabaseAdmin\n      .from('featured_games')\n      .upsert(\n        popularThisWeek.map((g) => ({ game_id: g.id, reason: 'popular' })),\n      )\n    return Response.json({ popularThisWeek })\n  }),\n}\n```\n\nThe cron job sends the named secret key in the `apikey` header:\n\n```ts\nconst refreshEndpoint =\n  'https://<project>.supabase.co/functions/v1/refresh-popular'\nconst cronKey = 'sb_secret_...' // the \"cron\" named secret key\n\nawait fetch(refreshEndpoint, {\n  method: 'POST',\n  headers: { apikey: cronKey },\n})\n```\n\n## Auth Modes\n\n| Mode               | Credential                      | Use case                                            |\n| ------------------ | ------------------------------- | --------------------------------------------------- |\n| `\"user\"` (default) | Valid JWT                       | Authenticated user endpoints                        |\n| `\"publishable\"`    | Valid `default` publishable key | Client-facing, key-validated endpoints              |\n| `\"secret\"`         | Valid `default` secret key      | Server-to-server, internal calls                    |\n| `\"none\"`           | None                            | Open endpoints, wrappers that handle their own auth |\n\nArray syntax (`auth: [\"user\", \"secret\"]`) accepts multiple auth methods — first match wins. An absent credential falls through to the next mode; a present-but-invalid JWT rejects the request (no silent downgrade).\n\nNamed key validation: `auth: \"publishable:web_app\"` or `auth: \"secret:automations\"` validates against a specific named key in `SUPABASE_PUBLISHABLE_KEYS` or `SUPABASE_SECRET_KEYS`. Bare `auth: \"secret\"` (or `\"publishable\"`) matches only the `default` key; use the wildcard `auth: \"secret:*\"` to accept any key in the set. See [`docs/auth-modes.md`](docs/auth-modes.md).\n\n> **Supabase Edge Functions:** By default, the platform requires a valid JWT on every request. If your function uses `auth: 'publishable'`, `auth: 'secret'`, or `auth: 'none'`, disable the platform-level JWT check in `supabase/config.toml`:\n>\n> ```toml\n> [functions.my-function]\n> verify_jwt = false\n> ```\n\n## Context\n\nEvery handler receives a `SupabaseContext`:\n\n```ts\ninterface SupabaseContext {\n  supabase: SupabaseClient // RLS-scoped (user or anon depending on auth)\n  supabaseAdmin: SupabaseClient // Bypasses RLS\n  userClaims: UserClaims | null // JWT-derived identity (for full User, call supabase.auth.getUser())\n  jwtClaims: JWTClaims | null // Present when auth is JWT\n  authMode: AuthMode // Which auth mode matched\n  authKeyName?: string // Auth key name of the API key that was used for this request (omitted for `'user'` / `'none'`)\n}\n```\n\n`supabase` is always the safe client — it respects RLS. When `authMode` is `\"user\"`, it's scoped to that user's permissions. Otherwise, it's initialized as anonymous.\n\n`supabaseAdmin` always bypasses RLS. Use it for operations that need full database access.\n\n## Config\n\n```ts\nwithSupabase(\n  {\n    auth: 'user', // who can call this function\n    cors: 'disabled', // disable CORS (default: supabase-js CORS headers)\n    env: { url: '...' }, // env overrides (optional)\n  },\n  handler,\n)\n```\n\n`cors` accepts `'default'` (the standard [supabase-js CORS headers](https://supabase.com/docs/guides/functions/cors), also the default), `'disabled'` to disable CORS handling (e.g. when using a framework that handles CORS separately), or `{ headers }` to set custom headers. The boolean (`true`/`false`) and bare `Record<string, string>` forms are deprecated but still accepted.\n\n```ts\nwithSupabase(\n  {\n    auth: 'user',\n    cors: {\n      headers: {\n        'Access-Control-Allow-Origin': 'https://myapp.com',\n        'Access-Control-Allow-Headers': 'authorization, content-type',\n      },\n    },\n  },\n  handler,\n)\n```\n\n`env` overrides environment variable resolution. Defaults to reading `SUPABASE_URL`, `SUPABASE_PUBLISHABLE_KEYS`, `SUPABASE_SECRET_KEYS`, and `SUPABASE_JWKS` from the runtime environment.\n\n`middleware` composes additional entries onto the context — they run after the Supabase context is established and contribute their own typed keys. The first-party entries live on the `@supabase/server/middleware/*` subpaths; see [Postgres](#postgres-rls-scoped-queries).\n\n> **Alpha.** The `middleware` option and the `@supabase/server/middleware/*`\n> subpaths track `@supabase/middleware` 0.x — entry shapes, context keys, and\n> config options may change between 0.x releases. Everything else in\n> `@supabase/server` is stable.\n\n## Framework Adapters\n\nAdapters wrap `withSupabase` for a specific framework's middleware contract. They ship inside `@supabase/server`, so a single `npm install @supabase/server` covers the framework you're using — no separate package per adapter.\n\n> **Adapters are a community-driven initiative.** They're developed, maintained, and evolved by contributors — including responding to upstream framework changes. See [`src/adapters/README.md`](src/adapters/README.md) for the contribution requirements (tests, types, docs, build wiring) if you'd like to add or help maintain one.\n\n| Framework | Import                             | Framework version      | Docs                                               |\n| --------- | ---------------------------------- | ---------------------- | -------------------------------------------------- |\n| Hono      | `@supabase/server/adapters/hono`   | `^4.0.0`               | [docs/adapters/hono.md](docs/adapters/hono.md)     |\n| H3 / Nuxt | `@supabase/server/adapters/h3`     | `^2.0.0`               | [docs/adapters/h3.md](docs/adapters/h3.md)         |\n| Elysia    | `@supabase/server/adapters/elysia` | `^1.4.0`               | [docs/adapters/elysia.md](docs/adapters/elysia.md) |\n| NestJS    | `@supabase/server/adapters/nestjs` | `^10.0.0 \\|\\| ^11.0.0` | [docs/adapters/nestjs.md](docs/adapters/nestjs.md) |\n\nSee the per-adapter docs above for setup, per-route auth, CORS, error handling, and other patterns.\n\n### Elysia\n\n```ts\nimport { Elysia } from 'elysia'\nimport { withSupabase } from '@supabase/server/adapters/elysia'\n\nconst app = new Elysia()\n  // Protected — plugin resolves supabaseContext before handlers run\n  .use(withSupabase({ auth: 'user' }))\n  .get('/games', async ({ supabaseContext }) => {\n    const { data: myGames } = await supabaseContext.supabase\n      .from('favorite_games')\n      .select()\n    return myGames\n  })\n  // Public — no plugin means no auth\n  .get('/health', () => ({ status: 'ok' }))\n\napp.listen(3000)\n```\n\nFor per-route auth, use scoped groups:\n\n```ts\nimport { Elysia } from 'elysia'\nimport { withSupabase } from '@supabase/server/adapters/elysia'\n\nconst app = new Elysia()\n  .get('/health', () => ({ status: 'ok' }))\n  .group('/api', (app) =>\n    app\n      .use(withSupabase({ auth: 'user' }))\n      .get('/profile', async ({ supabaseContext }) => {\n        return supabaseContext.userClaims\n      }),\n  )\n\napp.listen(3000)\n```\n\nThe adapter does not handle CORS — use `@elysiajs/cors` for that.\n\n### NestJS\n\n```ts\nimport { Controller, Get, UseGuards } from '@nestjs/common'\nimport { withSupabase, SupabaseCtx } from '@supabase/server/adapters/nestjs'\nimport type { SupabaseContext } from '@supabase/server'\n\n@Controller('games')\n@UseGuards(withSupabase({ auth: 'user' }))\nexport class GamesController {\n  @Get()\n  list(@SupabaseCtx() ctx: SupabaseContext) {\n    return ctx.supabase.from('favorite_games').select()\n  }\n}\n```\n\nSee [docs/adapters/nestjs.md](docs/adapters/nestjs.md) for per-route auth, exception filters, CORS, and more.\n\n## Primitives\n\nFor when you need more control than `withSupabase` provides — multiple routes with different auth, custom response headers, or building your own wrapper.\n\nAll primitives are available from `@supabase/server/core`.\n\n```ts\nimport {\n  verifyAuth,\n  createContextClient,\n  createAdminClient,\n} from '@supabase/server/core'\n```\n\n### verifyAuth\n\nExtracts credentials from a Request and validates against the auth config.\n\n```ts\nconst { data: auth, error } = await verifyAuth(req, { auth: 'user' })\nif (error) {\n  return Response.json({ message: error.message }, { status: error.status })\n}\n```\n\n### verifyCredentials\n\nLow-level — works with raw credentials instead of a Request. Used by SSR adapters and custom auth flows.\n\n```ts\nconst credentials = { token: myToken, apikey: null }\nconst { data: result, error } = await verifyCredentials(credentials, {\n  auth: 'user',\n})\n```\n\n### createContextClient / createAdminClient\n\n```ts\nconst userScopedClient = createContextClient(auth.token) // RLS applies as this user\nconst anonClient = createContextClient() // RLS applies as anon role\nconst adminClient = createAdminClient() // bypasses RLS entirely\n```\n\n### createSupabaseContext\n\nFull context assembly from a Request — `verifyAuth` + client creation in one call.\n\n```ts\nconst { data: ctx, error } = await createSupabaseContext(req, { auth: 'user' })\n```\n\n### resolveEnv\n\nResolves environment variables with optional overrides.\n\n```ts\nconst { data: env, error } = resolveEnv({\n  url: process.env.NEXT_PUBLIC_SUPABASE_URL,\n})\n```\n\n### Example: custom multi-route handler\n\nThe same games API and health check from the Hono example, built from primitives instead of a framework:\n\n```ts\nimport { verifyAuth, createContextClient } from '@supabase/server/core'\n\nexport default {\n  fetch: async (req) => {\n    const url = new URL(req.url)\n\n    // Public — no auth needed\n    if (url.pathname === '/health') {\n      return Response.json({ status: 'ok' })\n    }\n\n    // Protected — verify the JWT, then create a user-scoped client\n    if (url.pathname === '/games') {\n      const { data: result, error } = await verifyAuth(req, { auth: 'user' })\n      if (error)\n        return Response.json(\n          { message: error.message },\n          { status: error.status },\n        )\n\n      const userScopedClient = createContextClient(result.token)\n      const { data: myGames } = await userScopedClient\n        .from('favorite_games')\n        .select()\n      return Response.json(myGames)\n    }\n\n    return new Response('Not found', { status: 404 })\n  },\n}\n```\n\n## Postgres (RLS-scoped queries)\n\n> **Alpha.** The `middleware` option and the `@supabase/server/middleware/*`\n> subpaths track `@supabase/middleware` 0.x — entry shapes, context keys, and\n> config options may change between 0.x releases. Everything else in\n> `@supabase/server` is stable.\n\nWhen PostgREST isn't the right tool — joins, CTEs, window functions — `withPostgresClient` puts a direct Postgres connection on `ctx.postgres`, scoped to the caller by RLS:\n\n```ts\nimport { withSupabase } from '@supabase/server'\nimport { withPostgresClient } from '@supabase/server/middleware/postgres'\n\nexport default {\n  fetch: withSupabase(\n    { auth: 'user', middleware: [withPostgresClient()] },\n    async (_req, ctx) => {\n      // No WHERE clause — RLS scopes the rows to the caller.\n      const notes = await ctx.postgres.query`select id, body from notes`\n      return Response.json(notes)\n    },\n  ),\n}\n```\n\nEach query runs in its own transaction that injects the caller's claims and drops to their role, exactly like PostgREST — so `auth.uid()` resolves and your policies enforce. Only `authenticated` and `anon` are assumed; a token naming any other role (including `service_role`, and custom roles) is refused with `code: 'UNSUPPORTED_ROLE'` rather than silently downgraded to `anon`.\n\nWhen a handler legitimately needs to cross user boundaries, `withPostgresAdminClient` is the explicit opt-out — it contributes `ctx.postgresAdmin`, which bypasses RLS and needs no caller identity, so it works under `auth: 'secret'` and `auth: 'none'` too:\n\n```ts\nimport { withPostgresAdminClient } from '@supabase/server/middleware/postgres-admin'\n\nwithSupabase(\n  { auth: 'secret', middleware: [withPostgresAdminClient()] },\n  handler,\n)\n```\n\nThe pair mirrors `ctx.supabase` / `ctx.supabaseAdmin`, and they share one connection pool. Keeping them as two middleware is deliberate: bypassing RLS stays visible at the composition site, so you can grep for every handler that can do it.\n\nNeeds `pg` installed (optional peer dependency) and a raw TCP socket: Node, Deno, Bun, and the Supabase Edge runtime — **not** Workers-style isolates. Reads `SUPABASE_DB_URL` by default. Remember that `authenticated` also needs table grants, not just policies.\n\nSee [`docs/postgres.md`](docs/postgres.md) for standalone composition with `withClaims`, the grants requirement, and current limits.\n\n## Environment Variables\n\nAutomatically available in Supabase Edge Functions:\n\n| Variable                    | Format                                                        | Description                                  |\n| --------------------------- | ------------------------------------------------------------- | -------------------------------------------- |\n| `SUPABASE_URL`              | `https://<ref>.supabase.co`                                   | Your project URL                             |\n| `SUPABASE_PUBLISHABLE_KEYS` | `{\"default\":\"sb_publishable_...\",\"web\":\"sb_publishable_...\"}` | Publishable API keys (named)                 |\n| `SUPABASE_SECRET_KEYS`      | `{\"default\":\"sb_secret_...\",\"web\":\"sb_secret_...\"}`           | Secret API keys (named)                      |\n| `SUPABASE_JWKS`             | `{\"keys\":[...]}` or `[...]`                                   | Inline JSON Web Key Set for JWT verification |\n\nAlso supported (for local dev, self-hosted, or other runtimes):\n\n| Variable                   | Format               | Description                                               |\n| -------------------------- | -------------------- | --------------------------------------------------------- |\n| `SUPABASE_PUBLISHABLE_KEY` | `sb_publishable_...` | Single publishable key                                    |\n| `SUPABASE_SECRET_KEY`      | `sb_secret_...`      | Single secret key                                         |\n| `SUPABASE_JWKS_URL`        | `https://...`        | Remote JWKS endpoint (used when `SUPABASE_JWKS` is unset) |\n| `SUPABASE_DB_URL`          | `postgresql://...`   | Postgres connection string, read by `withPostgresClient`  |\n\nWhen both singular and plural forms are set, plural takes priority.\n\nFor other environments, pass overrides via the `env` config option or `resolveEnv()`. See [`docs/environment-variables.md`](docs/environment-variables.md) for details.\n\n## Runtimes\n\n`@supabase/server` runs anywhere standard Web `fetch` does — pick the row that matches your deployment target.\n\n| Target                      | Notes                                                                                                                                     |\n| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| **Supabase Edge Functions** | Zero config — environment variables are auto-injected.                                                                                    |\n| **Vercel Functions**        | Edge runtime: `export default { fetch }`. Node runtime: use a [framework adapter](#framework-adapters) or [core primitives](#primitives). |\n| **Cloudflare Workers**      | Enable `nodejs_compat` in `wrangler.toml`, or pass overrides via the `env` config option.                                                 |\n| **Deno / Bun**              | Works out of the box via `export default { fetch }`.                                                                                      |\n| **Node.js**                 | Use a [framework adapter](#framework-adapters) or [core primitives](#primitives) with your framework of choice.                           |\n\nUsing a framework? See [Framework Adapters](#framework-adapters) for Hono, H3 / Nuxt, and Elysia, or [`docs/ssr-frameworks.md`](docs/ssr-frameworks.md) for Next.js / SvelteKit / Remix (compose with [`@supabase/ssr`](https://github.com/supabase/ssr)).\n\n### Does this replace `@supabase/ssr`?\n\nNo. `@supabase/ssr` handles cookie-based session management for frameworks like Next.js and SvelteKit. `@supabase/server` handles stateless, header-based auth for Edge Functions, Workers, and other backend runtimes. The composable primitives already work in SSR environments but require more setup — see [`docs/ssr-frameworks.md`](docs/ssr-frameworks.md) for the Next.js example. The two packages coexist and are not replacements for each other. Deeper integration with `@supabase/ssr` is on the roadmap.\n\n## Exports\n\n| Export                                        | What's in it                                                                                                      |\n| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |\n| `@supabase/server`                            | `withSupabase`, `createSupabaseContext`                                                                           |\n| `@supabase/server/core`                       | `verifyAuth`, `verifyCredentials`, `extractCredentials`, `createContextClient`, `createAdminClient`, `resolveEnv` |\n| `@supabase/server/adapters/hono`              | `withSupabase` (Hono middleware)                                                                                  |\n| `@supabase/server/adapters/h3`                | `withSupabase` (H3 / Nuxt middleware)                                                                             |\n| `@supabase/server/adapters/elysia`            | `withSupabase` (Elysia plugin)                                                                                    |\n| `@supabase/server/adapters/nestjs`            | `withSupabase` (NestJS guard), `SupabaseCtx` (param decorator)                                                    |\n| `@supabase/server/middleware/client`          | **Alpha.** `withSupabaseClient` (RLS-scoped `ctx.supabase` client)                                                |\n| `@supabase/server/middleware/admin-client`    | **Alpha.** `withSupabaseAdminClient` (`ctx.supabaseAdmin`, bypasses RLS)                                          |\n| `@supabase/server/middleware/claims`          | **Alpha.** `withClaims` (JWKS-verified `ctx.jwtClaims`)                                                           |\n| `@supabase/server/middleware/required-claims` | **Alpha.** `withRequiredClaims` (user-mode auth gate, non-null `ctx.jwtClaims`)                                   |\n| `@supabase/server/middleware/postgres`        | **Alpha.** `withPostgresClient` (RLS-scoped `ctx.postgres` client)                                                |\n| `@supabase/server/middleware/postgres-admin`  | **Alpha.** `withPostgresAdminClient` (`ctx.postgresAdmin`, bypasses RLS)                                          |\n| `@supabase/server/oauth-protected-resource`   | **Alpha.** `withOAuthProtectedResource`, `fromSupabaseUrl`, `resourceMetadataResponse`, `unauthorizedResponse`    |\n| `@supabase/server/peer/supabase-js`           | Re-exported `supabase-js` types (`SupabaseClient`, `PostgrestError`, …)                                           |\n\n## Documentation\n\n| Question                                                            | Doc file                                                         |\n| ------------------------------------------------------------------- | ---------------------------------------------------------------- |\n| How do I create a basic endpoint?                                   | [`docs/getting-started.md`](docs/getting-started.md)             |\n| What auth modes are available? Array syntax? Named keys?            | [`docs/auth-modes.md`](docs/auth-modes.md)                       |\n| Which framework adapters exist? How do I contribute one?            | [`src/adapters/README.md`](src/adapters/README.md)               |\n| How do I use this with Hono?                                        | [`docs/adapters/hono.md`](docs/adapters/hono.md)                 |\n| How do I use this with H3 / Nuxt?                                   | [`docs/adapters/h3.md`](docs/adapters/h3.md)                     |\n| How do I use this with Elysia?                                      | [`docs/adapters/elysia.md`](docs/adapters/elysia.md)             |\n| How do I use this with NestJS?                                      | [`docs/adapters/nestjs.md`](docs/adapters/nestjs.md)             |\n| How do I use low-level primitives for custom flows?                 | [`docs/core-primitives.md`](docs/core-primitives.md)             |\n| How do environment variables work across runtimes?                  | [`docs/environment-variables.md`](docs/environment-variables.md) |\n| How do I handle errors? What codes exist?                           | [`docs/error-handling.md`](docs/error-handling.md)               |\n| How do I get typed database queries?                                | [`docs/typescript-generics.md`](docs/typescript-generics.md)     |\n| How do I run raw SQL scoped to the caller by RLS?                   | [`docs/postgres.md`](docs/postgres.md)                           |\n| How do I use this with `@supabase/ssr` (Next.js, SvelteKit, Remix)? | [`docs/ssr-frameworks.md`](docs/ssr-frameworks.md)               |\n| What's the complete API surface?                                    | [`docs/api-reference.md`](docs/api-reference.md)                 |\n\n## Development\n\n```bash\npnpm install\npnpm dev\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development workflow, commit conventions, and release process.\n\n## License\n\nMIT\n",
  "bytes": 27942,
  "sha": "42bd9c67da6074c230a4d6e24da7c31a7d4e382d45475da9c8dcd2c79c0bb644",
  "repo_slug": "supabase/server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/skl_supabase_server_supabase_server_d3523a51/readme"
}