@supabase/server 0.2.0 → 1.0.0-rc.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -92
- package/dist/adapters/h3/index.cjs +3 -3
- package/dist/adapters/h3/index.d.cts +3 -3
- package/dist/adapters/h3/index.d.mts +3 -3
- package/dist/adapters/h3/index.mjs +3 -3
- package/dist/adapters/hono/index.cjs +2 -2
- package/dist/adapters/hono/index.d.cts +2 -2
- package/dist/adapters/hono/index.d.mts +2 -2
- package/dist/adapters/hono/index.mjs +2 -2
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.d.cts +25 -9
- package/dist/core/index.d.mts +25 -9
- package/dist/core/index.mjs +1 -1
- package/dist/{create-supabase-context-C_8SbO5w.cjs → create-supabase-context-B-2NDJhL.cjs} +10 -9
- package/dist/{create-supabase-context-DXD5rxi1.mjs → create-supabase-context-BBZtr3D2.mjs} +10 -9
- package/dist/{errors-Dyj5Cjt6.d.cts → errors-0dbzn5gA.d.mts} +1 -1
- package/dist/{errors-m42mkqhD.d.mts → errors-CZFEYnV_.d.cts} +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +3 -3
- package/dist/{types-DKe8uOwI.d.mts → types-B2yXZjmG.d.mts} +40 -23
- package/dist/{types-DqhOaSlC.d.cts → types-u7fYLtzC.d.cts} +40 -23
- package/dist/{verify-auth-C4zqDlfj.cjs → verify-auth-BKZK83Y8.cjs} +66 -34
- package/dist/{verify-auth-CxFZy9rl.mjs → verify-auth-CZQd36s0.mjs} +66 -34
- package/docs/adapters/h3.md +180 -0
- package/docs/{hono-adapter.md → adapters/hono.md} +14 -25
- package/docs/api-reference.md +28 -15
- package/docs/auth-modes.md +38 -34
- package/docs/core-primitives.md +13 -13
- package/docs/environment-variables.md +17 -17
- package/docs/error-handling.md +4 -4
- package/docs/getting-started.md +17 -17
- package/docs/security.md +15 -15
- package/docs/ssr-frameworks.md +148 -172
- package/docs/typescript-generics.md +6 -6
- package/package.json +5 -3
- package/skills/supabase-server/SKILL.md +51 -44
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supabase/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-rc.53",
|
|
4
4
|
"description": "Server-side utilities for Supabase. Handles auth, client creation, and context injection so you write business logic, not boilerplate.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"edge",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "tsdown",
|
|
57
57
|
"dev": "tsdown --watch",
|
|
58
|
+
"docs": "typedoc",
|
|
58
59
|
"format": "prettier --write .",
|
|
59
60
|
"lint": "eslint src",
|
|
60
61
|
"lint:fix": "eslint src --fix",
|
|
@@ -74,8 +75,8 @@
|
|
|
74
75
|
},
|
|
75
76
|
"peerDependencies": {
|
|
76
77
|
"@supabase/supabase-js": "^2.0.0",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
78
|
+
"h3": "^2.0.0",
|
|
79
|
+
"hono": "^4.0.0"
|
|
79
80
|
},
|
|
80
81
|
"peerDependenciesMeta": {
|
|
81
82
|
"h3": {
|
|
@@ -96,6 +97,7 @@
|
|
|
96
97
|
"pretty-quick": "^4.2.2",
|
|
97
98
|
"simple-git-hooks": "^2.13.1",
|
|
98
99
|
"tsdown": "^0.20.3",
|
|
100
|
+
"typedoc": "^0.28.19",
|
|
99
101
|
"typescript": "^5.9.3",
|
|
100
102
|
"typescript-eslint": "^8.56.1",
|
|
101
103
|
"vitest": "^4.0.18"
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-server
|
|
3
|
-
description: Use when writing server-side code
|
|
3
|
+
description: Use when planning or writing server-side code that uses `@supabase/server` — Edge Functions, Hono apps, webhook handlers, or any backend that creates Supabase clients or validates inbound auth. Trigger **before** writing or modifying any file that imports from `@supabase/server` (or sub-paths like `@supabase/server/core`); calls `withSupabase`, `createSupabaseContext`, `createAdminClient`, `createContextClient`, `verifyAuth`, `verifyCredentials`, or `extractCredentials`; configures an `auth:` mode (`'none'` | `'publishable'` | `'secret'` | `'user'`, or keyed variants like `'secret:*'`); or lives under `supabase/functions/` and authenticates an inbound request. Also trigger during planning — if a plan mentions any of the above, load the skill before drafting code; do not extrapolate `auth:` values or auth modes from neighboring functions. Also trigger when you see legacy patterns to migrate to this package — `Deno.serve`, `createClient(Deno.env.get('SUPABASE_URL'))`, imports from `esm.sh/@supabase` or `deno.land/std`, usage of `SUPABASE_ANON_KEY` / `SUPABASE_SERVICE_ROLE_KEY`, or the deprecated `allow:` config option / removed `'always'` / `'public'` mode values / removed `authType` field.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# @supabase/server
|
|
7
7
|
|
|
8
|
-
> **Beta
|
|
8
|
+
> **v1.0 — 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. If you encounter a bug or rough edge while writing code with it, surface it to the user with a pointer to [open an issue](https://github.com/supabase/server/issues).
|
|
9
9
|
|
|
10
10
|
> **This is a brand new package.** There is no information available online yet — no blog posts, no Stack Overflow answers, no tutorials. Do not search the web for usage examples. Rely exclusively on the documentation files listed below and the source code in this repository.
|
|
11
11
|
|
|
12
|
+
> **The config option is `auth`, not `allow`.** `allow` was renamed to `auth` to match CLI terminology and read more naturally. The legacy `allow` key still works (with a one-time `console.warn`) but is deprecated and will be removed in a future major release. **Always emit `auth` in new code** — e.g. `withSupabase({ auth: 'user' }, ...)`. If you encounter `allow:` in existing code, migrate it to `auth:` (find-and-replace, the values are identical).
|
|
13
|
+
|
|
14
|
+
> **Auth mode values: `'none'` (not `'always'`), `'publishable'` (not `'public'`).** The four valid values are `'user'`, `'publishable'`, `'secret'`, `'none'`. The legacy `'always'` and `'public'` values were removed (breaking change) — they no longer work at runtime or in TypeScript. Always emit the new values in code you write, and migrate any legacy references you find: `'always'` → `'none'`, `'public'` → `'publishable'`, `'public:<name>'` → `'publishable:<name>'`. Runtime checks like `ctx.authType === 'public'` must also be updated to `ctx.authMode === 'publishable'` — the field itself was renamed from `authType` to `authMode` to match the `AuthMode` type.
|
|
15
|
+
|
|
12
16
|
> **Do not use legacy Supabase keys.** The `anon` key and `service_role` key (env vars `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY`) are legacy and will be deprecated. Do not use them unless the user explicitly asks. Always use the new API keys:
|
|
13
17
|
>
|
|
14
18
|
> | Legacy (avoid) | New (use this) |
|
|
@@ -16,15 +20,15 @@ description: Use when writing server-side code with Supabase — Edge Functions,
|
|
|
16
20
|
> | `SUPABASE_ANON_KEY` | `SUPABASE_PUBLISHABLE_KEY(S)` (`sb_publishable_...`) |
|
|
17
21
|
> | `SUPABASE_SERVICE_ROLE_KEY` | `SUPABASE_SECRET_KEY(S)` (`sb_secret_...`) |
|
|
18
22
|
>
|
|
19
|
-
> Do not call `createClient(url, anonKey)` directly — use `@supabase/server` auth modes (`
|
|
23
|
+
> Do not call `createClient(url, anonKey)` directly — use `@supabase/server` auth modes (`auth: 'user'`, `auth: 'secret'`, etc.) which handle key resolution automatically. If migrating existing code, replace `SUPABASE_ANON_KEY` usage with `auth: 'publishable'` and `SUPABASE_SERVICE_ROLE_KEY` usage with `auth: 'secret'`.
|
|
20
24
|
|
|
21
25
|
Server-side utilities for Supabase. Handles auth, client creation, and context injection so you write business logic, not boilerplate.
|
|
22
26
|
|
|
23
27
|
## What this package does
|
|
24
28
|
|
|
25
29
|
- Wraps fetch handlers with credential verification, CORS, and pre-configured Supabase clients
|
|
26
|
-
- Supports 4 auth modes: `user` (JWT), `
|
|
27
|
-
- Array syntax (`
|
|
30
|
+
- Supports 4 auth modes: `user` (JWT), `publishable` (publishable key), `secret` (secret key), `none` (no credentials required)
|
|
31
|
+
- Array syntax (`auth: ['user', 'secret']`) is first-match-wins. A present-but-invalid JWT rejects with `InvalidCredentialsError` — it does not silently downgrade to the next mode.
|
|
28
32
|
- Provides composable core primitives for custom auth flows and framework integration
|
|
29
33
|
- Includes a Hono adapter for per-route auth
|
|
30
34
|
|
|
@@ -38,14 +42,14 @@ Server-side utilities for Supabase. Handles auth, client creation, and context i
|
|
|
38
42
|
|
|
39
43
|
## Quick starts
|
|
40
44
|
|
|
41
|
-
> **Supabase Edge Functions: disable `verify_jwt` for non-user auth.** By default, Supabase Edge Functions require a valid JWT on every request. If your function uses `
|
|
45
|
+
> **Supabase Edge Functions: disable `verify_jwt` for non-user auth.** By default, Supabase Edge Functions require a valid JWT on every request. If your function uses `auth: 'publishable'`, `auth: 'secret'`, or `auth: 'none'`, you must disable the platform-level JWT check in `supabase/config.toml`, otherwise the request will be rejected before it reaches your handler:
|
|
42
46
|
>
|
|
43
47
|
> ```toml
|
|
44
48
|
> [functions.my-function]
|
|
45
49
|
> verify_jwt = false
|
|
46
50
|
> ```
|
|
47
51
|
>
|
|
48
|
-
> Functions using `
|
|
52
|
+
> Functions using `auth: 'user'` can leave `verify_jwt` enabled (the default) since callers already provide a valid JWT.
|
|
49
53
|
|
|
50
54
|
### Supabase Edge Functions (Deno)
|
|
51
55
|
|
|
@@ -56,7 +60,7 @@ Environment variables are auto-injected by the platform — zero config. **All i
|
|
|
56
60
|
import { withSupabase } from 'npm:@supabase/server'
|
|
57
61
|
|
|
58
62
|
export default {
|
|
59
|
-
fetch: withSupabase({
|
|
63
|
+
fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => {
|
|
60
64
|
const { data } = await ctx.supabase.from('todos').select()
|
|
61
65
|
return Response.json(data)
|
|
62
66
|
}),
|
|
@@ -70,7 +74,7 @@ import { createSupabaseContext } from 'npm:@supabase/server'
|
|
|
70
74
|
export default {
|
|
71
75
|
fetch: async (req: Request) => {
|
|
72
76
|
const { data: ctx, error } = await createSupabaseContext(req, {
|
|
73
|
-
|
|
77
|
+
auth: 'user',
|
|
74
78
|
})
|
|
75
79
|
if (error) {
|
|
76
80
|
return Response.json(
|
|
@@ -92,7 +96,7 @@ Requires `nodejs_compat` compatibility flag in `wrangler.toml`, or pass env over
|
|
|
92
96
|
import { withSupabase } from '@supabase/server'
|
|
93
97
|
|
|
94
98
|
export default {
|
|
95
|
-
fetch: withSupabase({
|
|
99
|
+
fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => {
|
|
96
100
|
const { data } = await ctx.supabase.from('todos').select()
|
|
97
101
|
return Response.json(data)
|
|
98
102
|
}),
|
|
@@ -101,7 +105,7 @@ export default {
|
|
|
101
105
|
|
|
102
106
|
### Hono
|
|
103
107
|
|
|
104
|
-
CORS is not handled by the adapter — use `hono/cors` middleware. See `docs/hono
|
|
108
|
+
CORS is not handled by the adapter — use `hono/cors` middleware. See `docs/adapters/hono.md`.
|
|
105
109
|
|
|
106
110
|
```ts
|
|
107
111
|
// Node.js / Bun
|
|
@@ -109,7 +113,7 @@ import { Hono } from 'hono'
|
|
|
109
113
|
import { withSupabase } from '@supabase/server/adapters/hono'
|
|
110
114
|
|
|
111
115
|
const app = new Hono()
|
|
112
|
-
app.use('*', withSupabase({
|
|
116
|
+
app.use('*', withSupabase({ auth: 'user' }))
|
|
113
117
|
|
|
114
118
|
app.get('/todos', async (c) => {
|
|
115
119
|
const { supabase } = c.var.supabaseContext
|
|
@@ -126,7 +130,7 @@ import { Hono } from 'npm:hono'
|
|
|
126
130
|
import { withSupabase } from 'npm:@supabase/server/adapters/hono'
|
|
127
131
|
|
|
128
132
|
const app = new Hono()
|
|
129
|
-
app.use('*', withSupabase({
|
|
133
|
+
app.use('*', withSupabase({ auth: 'user' }))
|
|
130
134
|
|
|
131
135
|
app.get('/todos', async (c) => {
|
|
132
136
|
const { supabase } = c.var.supabaseContext
|
|
@@ -137,12 +141,13 @@ app.get('/todos', async (c) => {
|
|
|
137
141
|
export default { fetch: app.fetch }
|
|
138
142
|
```
|
|
139
143
|
|
|
140
|
-
###
|
|
144
|
+
### Cookie-based environments (compose with `@supabase/ssr`)
|
|
141
145
|
|
|
142
|
-
|
|
146
|
+
For Next.js / SvelteKit / Remix, **compose `@supabase/server` with [`@supabase/ssr`](https://github.com/supabase/ssr)** — they are not replacements for each other. `@supabase/ssr` owns cookies and refresh-token rotation (its middleware is required, otherwise the access token cookie goes stale and verification fails). In your Server Component or Route Handler, use `@supabase/ssr`'s `createServerClient` to read the (middleware-refreshed) session, hand the access token to `verifyCredentials` from `@supabase/server/core`, then build the typed clients with `createContextClient` + `createAdminClient`. See `docs/ssr-frameworks.md` for the full adapter pattern.
|
|
143
147
|
|
|
144
148
|
```ts
|
|
145
149
|
// Key imports for building the adapter
|
|
150
|
+
import { createServerClient } from '@supabase/ssr'
|
|
146
151
|
import {
|
|
147
152
|
verifyCredentials,
|
|
148
153
|
createContextClient,
|
|
@@ -161,7 +166,7 @@ import { withSupabase } from 'npm:@supabase/server'
|
|
|
161
166
|
|
|
162
167
|
// Only accept the "automations" named secret key
|
|
163
168
|
export default {
|
|
164
|
-
fetch: withSupabase({
|
|
169
|
+
fetch: withSupabase({ auth: 'secret:automations' }, async (req, ctx) => {
|
|
165
170
|
const body = await req.json()
|
|
166
171
|
const { data } = await ctx.supabaseAdmin
|
|
167
172
|
.from('scheduled_tasks')
|
|
@@ -187,26 +192,26 @@ await fetch('https://<project>.supabase.co/functions/v1/my-function', {
|
|
|
187
192
|
})
|
|
188
193
|
```
|
|
189
194
|
|
|
190
|
-
Use `
|
|
195
|
+
Use `auth: 'secret'` to accept any secret key, or `auth: 'secret:name'` to require a specific named key.
|
|
191
196
|
|
|
192
|
-
## When to use `
|
|
197
|
+
## When to use `auth: 'none'`
|
|
193
198
|
|
|
194
|
-
> **`
|
|
199
|
+
> **`auth: 'none'` disables all authentication.** The handler runs for every request with no credential checks. Only use it when auth is genuinely unnecessary — health checks, public status pages, or endpoints with no sensitive data and no side effects.
|
|
195
200
|
|
|
196
|
-
**Before using `
|
|
201
|
+
**Before using `auth: 'none'`, confirm with the user whether the endpoint is truly public.** If not, propose an alternative:
|
|
197
202
|
|
|
198
|
-
- **Another service or cron job calls this function** — use `
|
|
199
|
-
- **An external webhook provider calls this function** — use `
|
|
203
|
+
- **Another service or cron job calls this function** — use `auth: 'secret'` or `auth: 'secret:<name>'` instead. The caller sends the secret key in the `apikey` header.
|
|
204
|
+
- **An external webhook provider calls this function** — use `auth: 'secret'` and have the provider send the secret key, or implement the provider's own signature verification inside the handler.
|
|
200
205
|
|
|
201
|
-
**Never use `
|
|
206
|
+
**Never use `auth: 'none'` for endpoints that read or write user data without verifying who the caller is.**
|
|
202
207
|
|
|
203
|
-
**On `
|
|
208
|
+
**On `auth: ['user', 'none']`.** A stale or malformed JWT on such an endpoint is rejected with `InvalidCredentialsError` — it is not silently downgraded to anonymous. Callers that might hold a cached/expired token should either omit the `Authorization` header entirely or refresh before calling. If the goal is "anonymous unless a valid user is signed in," this is the correct behavior; if the goal is truly "accept anything," use `auth: 'none'` on its own.
|
|
204
209
|
|
|
205
210
|
## Edge Function recipes
|
|
206
211
|
|
|
207
212
|
### Function-to-function calls
|
|
208
213
|
|
|
209
|
-
One Edge Function can call another using the admin client. The called function uses `
|
|
214
|
+
One Edge Function can call another using the admin client. The called function uses `auth: 'secret'` and the caller invokes it via `ctx.supabaseAdmin.functions.invoke()`.
|
|
210
215
|
|
|
211
216
|
**Config** (`supabase/config.toml`):
|
|
212
217
|
|
|
@@ -221,7 +226,7 @@ verify_jwt = false # called with secret key, not a user JWT
|
|
|
221
226
|
import { withSupabase } from 'npm:@supabase/server'
|
|
222
227
|
|
|
223
228
|
export default {
|
|
224
|
-
fetch: withSupabase({
|
|
229
|
+
fetch: withSupabase({ auth: 'secret' }, async (req, ctx) => {
|
|
225
230
|
const { orderId } = await req.json()
|
|
226
231
|
const { data } = await ctx.supabaseAdmin
|
|
227
232
|
.from('orders')
|
|
@@ -240,7 +245,7 @@ export default {
|
|
|
240
245
|
import { withSupabase } from 'npm:@supabase/server'
|
|
241
246
|
|
|
242
247
|
export default {
|
|
243
|
-
fetch: withSupabase({
|
|
248
|
+
fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {
|
|
244
249
|
const { orderId } = await req.json()
|
|
245
250
|
|
|
246
251
|
// Calls process-order with the secret key automatically
|
|
@@ -291,11 +296,11 @@ select net.http_post(
|
|
|
291
296
|
);
|
|
292
297
|
```
|
|
293
298
|
|
|
294
|
-
The receiving function uses `
|
|
299
|
+
The receiving function uses `auth: 'secret'` (see example above). `pg_net` is asynchronous — the HTTP request is queued and executed in the background. Check `net._http_response` for results.
|
|
295
300
|
|
|
296
301
|
### Stripe webhook
|
|
297
302
|
|
|
298
|
-
External webhook providers like Stripe cannot send your Supabase API keys. Use `
|
|
303
|
+
External webhook providers like Stripe cannot send your Supabase API keys. Use `auth: 'none'` to skip credential checks, then verify the webhook signature inside the handler.
|
|
299
304
|
|
|
300
305
|
**Config** (`supabase/config.toml`):
|
|
301
306
|
|
|
@@ -320,7 +325,7 @@ import Stripe from 'npm:stripe'
|
|
|
320
325
|
const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!)
|
|
321
326
|
|
|
322
327
|
export default {
|
|
323
|
-
fetch: withSupabase({
|
|
328
|
+
fetch: withSupabase({ auth: 'none' }, async (req, ctx) => {
|
|
324
329
|
const body = await req.text()
|
|
325
330
|
const sig = req.headers.get('stripe-signature')!
|
|
326
331
|
|
|
@@ -390,14 +395,14 @@ Uses the latest API keys, works across runtimes (Deno, Node.js, Cloudflare), and
|
|
|
390
395
|
import { withSupabase } from 'npm:@supabase/server'
|
|
391
396
|
|
|
392
397
|
export default {
|
|
393
|
-
fetch: withSupabase({
|
|
398
|
+
fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => {
|
|
394
399
|
const { data } = await ctx.supabase.from('orders').select('*')
|
|
395
400
|
return Response.json(data)
|
|
396
401
|
}),
|
|
397
402
|
}
|
|
398
403
|
```
|
|
399
404
|
|
|
400
|
-
The migration mapping: `SUPABASE_ANON_KEY` with manual auth header → `
|
|
405
|
+
The migration mapping: `SUPABASE_ANON_KEY` with manual auth header → `auth: 'user'`, `SUPABASE_ANON_KEY` without auth → `auth: 'publishable'`. For `SUPABASE_SERVICE_ROLE_KEY`, it depends on intent: if the legacy code validates the incoming key to protect the endpoint (e.g., `req.headers.get('apikey') === serviceRoleKey`), use `auth: 'secret'`. If it only uses the key to create an admin client for elevated DB access, no specific auth mode is needed — `ctx.supabaseAdmin` is always available regardless of auth mode.
|
|
401
406
|
|
|
402
407
|
## Documentation
|
|
403
408
|
|
|
@@ -406,15 +411,17 @@ The full documentation lives in the `docs/` directory of the `@supabase/server`
|
|
|
406
411
|
- **If working inside the SDK repo:** `docs/` is at the project root.
|
|
407
412
|
- **If the package is installed as a dependency:** look in `node_modules/@supabase/server/docs/`.
|
|
408
413
|
|
|
409
|
-
| Question
|
|
410
|
-
|
|
|
411
|
-
| How do I create a basic endpoint?
|
|
412
|
-
| What auth modes are available? Array syntax? Named keys?
|
|
413
|
-
| How do I
|
|
414
|
-
| How do I use
|
|
415
|
-
| How do
|
|
416
|
-
| How do I
|
|
417
|
-
| How do
|
|
418
|
-
| How do I
|
|
419
|
-
|
|
|
420
|
-
|
|
|
414
|
+
| Question | Doc file |
|
|
415
|
+
| ------------------------------------------------------------------- | ------------------------------- |
|
|
416
|
+
| How do I create a basic endpoint? | `docs/getting-started.md` |
|
|
417
|
+
| What auth modes are available? Array syntax? Named keys? | `docs/auth-modes.md` |
|
|
418
|
+
| Which framework adapters exist? How do I contribute one? | `src/adapters/README.md` |
|
|
419
|
+
| How do I use this with Hono? | `docs/adapters/hono.md` |
|
|
420
|
+
| How do I use this with H3 / Nuxt? | `docs/adapters/h3.md` |
|
|
421
|
+
| How do I use low-level primitives for custom flows? | `docs/core-primitives.md` |
|
|
422
|
+
| How do environment variables work across runtimes? | `docs/environment-variables.md` |
|
|
423
|
+
| How do I handle errors? What codes exist? | `docs/error-handling.md` |
|
|
424
|
+
| How do I get typed database queries? | `docs/typescript-generics.md` |
|
|
425
|
+
| How do I use this with `@supabase/ssr` (Next.js, SvelteKit, Remix)? | `docs/ssr-frameworks.md` |
|
|
426
|
+
| What's the complete API surface? | `docs/api-reference.md` |
|
|
427
|
+
| What security decisions does this package make? | `docs/security.md` |
|