Files
supabase__server/package.json
bogdantarasenko 3052a6b309 feat: add NestJS adapter (#55)
* 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.
2026-05-27 11:03:56 -05:00

135 lines
3.7 KiB
JSON

{
"name": "@supabase/server",
"version": "1.1.0",
"description": "Server-side utilities for Supabase. Handles auth, client creation, and context injection so you write business logic, not boilerplate.",
"keywords": [
"edge",
"functions",
"supabase"
],
"homepage": "https://github.com/supabase/server#readme",
"bugs": {
"url": "https://github.com/supabase/server/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/supabase/server.git"
},
"license": "MIT",
"author": "supabase",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.mts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"./core": {
"types": "./dist/core/index.d.mts",
"import": "./dist/core/index.mjs",
"require": "./dist/core/index.cjs"
},
"./adapters/hono": {
"types": "./dist/adapters/hono/index.d.mts",
"import": "./dist/adapters/hono/index.mjs",
"require": "./dist/adapters/hono/index.cjs"
},
"./adapters/h3": {
"types": "./dist/adapters/h3/index.d.mts",
"import": "./dist/adapters/h3/index.mjs",
"require": "./dist/adapters/h3/index.cjs"
},
"./adapters/elysia": {
"types": "./dist/adapters/elysia/index.d.mts",
"import": "./dist/adapters/elysia/index.mjs",
"require": "./dist/adapters/elysia/index.cjs"
},
"./adapters/nestjs": {
"types": "./dist/adapters/nestjs/index.d.mts",
"import": "./dist/adapters/nestjs/index.mjs",
"require": "./dist/adapters/nestjs/index.cjs"
},
"./package.json": "./package.json"
},
"main": "./dist/index.cjs",
"types": "./dist/index.d.cts",
"sideEffects": false,
"files": [
"dist",
"docs",
"skills"
],
"engines": {
"node": ">=20"
},
"packageManager": "pnpm@11.1.2+sha512.415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499",
"scripts": {
"build": "tsdown",
"dev": "tsdown --watch",
"docs": "typedoc",
"format": "prettier --write .",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"prepare": "simple-git-hooks",
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsc --noEmit && tsc --noEmit -p src/adapters/nestjs"
},
"simple-git-hooks": {
"pre-commit": "pnpm pretty-quick --staged",
"commit-msg": "pnpm commitlint --edit \"$1\""
},
"peerDependencies": {
"@nestjs/common": "^10.0.0 || ^11.0.0",
"@supabase/supabase-js": "^2.0.0",
"h3": "^2.0.0",
"hono": "^4.0.0",
"elysia": "^1.4.0"
},
"peerDependenciesMeta": {
"@nestjs/common": {
"optional": true
},
"h3": {
"optional": true
},
"hono": {
"optional": true
},
"elysia": {
"optional": true
}
},
"devDependencies": {
"@commitlint/cli": "^20.4.2",
"@commitlint/config-conventional": "^20.4.2",
"@nestjs/common": "^11.1.19",
"@nestjs/core": "^11.1.19",
"@nestjs/platform-express": "^11.1.19",
"@nestjs/platform-fastify": "^11.1.19",
"@nestjs/testing": "^11.1.19",
"@supabase/supabase-js": "^2.105.4",
"@swc/core": "^1.15.33",
"@types/supertest": "^7.2.0",
"eslint": "^10.0.2",
"elysia": "^1.4.0",
"h3": "2.0.1-rc.20",
"hono": "^4.12.5",
"prettier": "3.8.1",
"pretty-quick": "^4.2.2",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.2",
"simple-git-hooks": "^2.13.1",
"supertest": "^7.2.2",
"tsdown": "^0.20.3",
"typedoc": "^0.28.19",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.1",
"unplugin-swc": "^1.5.9",
"vitest": "^4.0.18"
},
"dependencies": {
"jose": "^6.2.0"
}
}