* feat: add NestJS adapter
Ships `@supabase/server/adapters/nestjs`:
- `withSupabase(opts)` — class guard for `@UseGuards()` and
`useGlobalGuards()`, supporting Express and Fastify
- `@SupabaseCtx(key?, ...pipes)` — param decorator returning the full
SupabaseContext or a single field, with NestJS pipes applied to the
extracted value
- 401s thrown as `HttpException` with `{ message, code }`; the
underlying `AuthError` is exposed on `cause`
Adds `@nestjs/common` as an optional peer dep (`^10 || ^11`), wires the
new export in package.json / jsr.json / tsdown.config.ts, and enables
`experimentalDecorators` + `emitDecoratorMetadata` in tsconfig. Test
setup uses unplugin-swc via vitest.config.ts so integration tests can
boot a real Nest app on both Express and Fastify.
Docs: README quickstart + docs/adapters/nestjs.md.
* refactor(nestjs): address PR review feedback
- Scope `experimentalDecorators` + `emitDecoratorMetadata` to
`src/adapters/nestjs/tsconfig.json` (extends root) and exclude the
adapter from the root project so the options aren't enforced
repo-wide. `typecheck` now runs both projects.
- Convert `vitest.config.ts` to the `projects` syntax so the
`unplugin-swc` transform applies only to the nestjs project; the unit
project runs unchanged with esbuild.
- Throw `HttpException` (500, `unsupported_context`) instead of
returning true on non-HTTP execution contexts so misuse fails loudly
on the first request rather than silently no-op'ing on every
RPC/WebSocket message.
- Remove the "skip if context already set" branch so handler-level
guards can tighten what a global guard set. Previously the outer
(global) guard always won under Nest's global → controller → handler
order, so a stricter handler-level guard could be silently bypassed.
Tests updated; `@SupabaseCtx` decorator unchanged.
- Drop unused `CanActivate` import from integration.test.ts.
* docs(nestjs): update guard behavior section to match new semantics
The guard no longer skips when a prior context exists — it always
re-evaluates. Rewrite the doc section to match the JSDoc wording and
the inner-rejects/inner-overwrites tests.
4.7 KiB
Adapters
You're in the adapter source folder. Framework adapters wrap withSupabase and createSupabaseContext for a specific framework's middleware contract — Hono middleware, H3 event handlers, and so on. Implementations live next to this README under <name>/; reference docs live at docs/adapters/<name>.md.
Available adapters
| Framework | Import | Framework version | Docs |
|---|---|---|---|
| Hono | @supabase/server/adapters/hono |
^4.0.0 |
docs/adapters/hono.md |
| H3 / Nuxt | @supabase/server/adapters/h3 |
^2.0.0 |
docs/adapters/h3.md |
| Elysia | @supabase/server/adapters/elysia |
^1.4.0 |
docs/adapters/elysia.md |
| NestJS | @supabase/server/adapters/nestjs |
^10.0.0 || ^11.0.0 |
docs/adapters/nestjs.md |
The framework version reflects what the adapter is tested against. It must match the corresponding entry in package.json#peerDependencies — if you bump the peer-dep range, update this table too.
Community-maintained
Every adapter listed above is community-maintained. Hono, H3, and Elysia all originated as community contributions. Adapters live in this repo and ship with the core package, so users get them with a single npm install @supabase/server — no separate package per framework.
The Supabase team reviews PRs, runs security and regression triage, and ships releases. The original contributor of an adapter is the de-facto domain expert and is expected to be the first responder on framework-version bumps and bug reports for that adapter.
Contributing a new adapter
Before you start, read CONTRIBUTING.md and agree with it. That covers the development setup, code style, commit conventions, and PR process. The points below are additional requirements specific to adapter contributions.
Code quality bar:
- Tests for every auth mode. Cover
'user','publishable','secret','none', the array form, and the failure paths (missing token, invalid JWT, missing apikey). The Hono adapter'shono/middleware.test.tsis the canonical reference — your test file should look structurally similar. - Strict TypeScript. No
any, no// @ts-ignore. Public types must be exported from the adapter'sindex.tsso consumers can extend them. - No new runtime dependencies beyond the framework you're adapting. The framework itself goes in
peerDependencies(andpeerDependenciesMetaif optional). Don't pull in a wrapper, polyfill, or utility lib just to make the adapter shorter. - Match the existing adapter shape. Export
withSupabase(config, handler)returning the framework's native middleware/handler type. UseverifyAuth,createContextClient, andcreateAdminClientfrom@supabase/server/core— never re-implement auth or env handling inside an adapter. - Wire up the build outputs. Add the adapter entry to
package.json#exports,jsr.json(if applicable), andtsdown.config.ts#entryso it ships in the published artifact. - Docs are required. Add
docs/adapters/<name>.mdmirroring the structure ofdocs/adapters/hono.md— at minimum: setup, basic example, per-route auth, CORS note. - Update both adapter tables. Add a row to the table in this
src/adapters/README.mdand the mirror table in the top-levelREADME.md. Keep the framework-version column accurate againstpackage.json#peerDependencies. PRs that touch an existing adapter must update the version column if the peer-dep range changed.
The Supabase team will review the PR against these requirements. Once merged, the adapter ships in the next release as part of @supabase/server — no separate package, no extra install for users. As the original contributor, you're expected to be the first responder on framework-version bumps and bug reports for your adapter.
Designing an adapter
The existing adapters at hono/middleware.ts, h3/middleware.ts, and elysia/plugin.ts (siblings of this README) are the canonical templates. The shape every adapter exposes is withSupabase(config, handler) returning a framework-native middleware. Keep all auth logic in @supabase/server/core — adapters should only translate request/response shapes between the framework and the core primitives.