Skip to content

feat: add Express 5 adapter#66

Open
bogdantarasenko wants to merge 10 commits into
supabase:mainfrom
bogdantarasenko:feat/express-adapter
Open

feat: add Express 5 adapter#66
bogdantarasenko wants to merge 10 commits into
supabase:mainfrom
bogdantarasenko:feat/express-adapter

Conversation

@bogdantarasenko
Copy link
Copy Markdown

Summary

  • Adds @supabase/server/adapters/express targeting Express 5, mirroring the Hono/H3 adapter contract. Public surface (all from src/adapters/express/index.ts): withSupabase() middleware, requireAuth() guard, withSupabaseRoute() per-route wrapper, and the WithSupabaseExpressConfig type. Resolved context lives on res.locals.supabaseContext via Express.Locals declaration merging.
  • Auth errors flow through a configurable onError option (default: next(error) — Express-idiomatic). Bridge from Express req → Fetch Request preserves headers (incl. multi-value Set-Cookie / Cookie), absolute URL composition under trust proxy, and forwards bodies for non-GET/HEAD methods. No new runtime deps — express ^5.0.0 is an optional peer.
  • Build wiring: package.json#exports, peerDependencies + peerDependenciesMeta, devDependencies, tsdown.config.ts, jsr.json. Docs at docs/adapters/express.md plus rows added to top-level README.md and src/adapters/README.md adapter tables.

Test plan

  • pnpm install resolves the new peer/dev dependencies
  • pnpm typecheck
  • pnpm lint
  • pnpm test — covers every AuthMode (user / publishable / secret / none), the array form, invalid-JWT / missing-credential failures, the res.locals.supabaseContext short-circuit path, default and custom onError, the requireAuth() guard (present / missing context / mode mismatch), and the withSupabaseRoute() wrapper (success, auth failure, async-thrown errors)
  • pnpm build produces dist/adapters/express/index.{mjs,cjs,d.mts,d.cts}
  • Verify import { withSupabase } from '@supabase/server/adapters/express' resolves from both ESM and CJS consumers
  • Smoke-test on an Express 5 app with app.set('trust proxy', true) behind a reverse proxy to confirm the bridged URL uses X-Forwarded-*

🤖 Generated with Claude Code

bogdantarasenko and others added 10 commits May 15, 2026 14:24
…dapter

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…terns

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bogdantarasenko bogdantarasenko requested review from a team as code owners May 15, 2026 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant