@selvajs/supabase-provider 0.19.0 → 0.19.2

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 CHANGED
@@ -1,270 +1,49 @@
1
1
  # @selvajs/supabase-provider
2
2
 
3
- Supabase (Auth + Postgres + Storage) implementation of the `@selvajs/platform` interfaces.
3
+ Supabase (Auth + Postgres + Storage) implementation of the `@selvajs/platform` interfaces — `IAuthProvider`, `IDataProvider`, `IStorageProvider`.
4
4
 
5
- Runs against **either** a managed Supabase project (production) or a local Supabase CLI stack in Docker (development) — same code, different `SUPABASE_URL` and keys.
5
+ Runs against **either** a managed Supabase project or a local Supabase CLI stack in Docker — same code, different `SUPABASE_URL` and keys.
6
6
 
7
- ---
8
-
9
- ## Table of contents
10
-
11
- - [Quick start](#quick-start)
12
- - [Environment variables](#environment-variables)
13
- - [Switching to the Supabase provider](#switching-to-the-supabase-provider)
14
- - [Applying the schema](#applying-the-schema)
15
- - [Development — local Supabase stack](#development--local-supabase-stack)
16
- - [Production — hosted Supabase project](#production--hosted-supabase-project)
17
- - [Running the conformance tests](#running-the-conformance-tests)
18
- - [Architecture notes](#architecture-notes)
19
-
20
- ---
21
-
22
- ## Quick start
23
-
24
- 1. Install the package in the workspace (already listed in `pnpm-workspace.yaml`).
25
- 2. Provision Supabase — either local (`npx supabase start`) or hosted (supabase.com).
26
- 3. Apply the migrations from `packages/providers/supabase/supabase/migrations/` (the local CLI does this automatically on `db reset`).
27
- 4. Copy the three env vars into your selva app `.env` (see below).
28
- 5. Set `SELVA_AUTH_PROVIDER=supabase`, `SELVA_DATA_PROVIDER=supabase`, `SELVA_STORAGE_PROVIDER=supabase` in the same `.env`.
29
- 6. `pnpm dev` — the selva app now reads and writes from Supabase.
30
-
31
- ---
32
-
33
- ## Environment variables
34
-
35
- All env vars are documented in [`packages/selva/.env.example`](../../selva/.env.example) — copy that file to `.env` and edit it. This provider needs `SUPABASE_URL`, `SUPABASE_ANON_KEY`, and `SUPABASE_SERVICE_ROLE_KEY`; the optional bucket / private-URL / signup overrides are also listed there.
36
-
37
- Both `SELVA_*` keys are still required, but for narrower jobs than under the local provider:
38
-
39
- - `SELVA_HMAC_KEY` — **not** used for sessions here (those are Supabase JWTs), but still hashes share-link and invite tokens before they're stored.
40
- - `SELVA_AT_REST_KEY` — encrypts `compute_servers.api_key` before it reaches the database. `SupabaseDataProvider` refuses to construct without it.
41
-
42
- Rhino.Compute URL + API key are configured in `/admin/compute` and persisted in the `compute_config` table — unchanged by the provider choice.
43
-
44
- ### Finding the keys
45
-
46
- **Local (`npx supabase status`):**
47
-
48
- ```
49
- ╭──────────────────────────────────────────────────╮
50
- │ 🔑 Authentication Keys │
51
- ├─────────────┬────────────────────────────────────┤
52
- │ Publishable │ sb_publishable_... │ ← SUPABASE_ANON_KEY
53
- │ Secret │ sb_secret_... │ ← SUPABASE_SERVICE_ROLE_KEY
54
- ╰─────────────┴────────────────────────────────────╯
55
- ```
56
-
57
- **Hosted:** Supabase Dashboard → **Project Settings** → **API**.
58
-
59
- > **The S3-compat keys under the "Storage (S3)" section are NOT what you want.** Those are for external S3 tooling (rclone, etc.), not for `@supabase/supabase-js`.
60
-
61
- ---
62
-
63
- ## Switching to the Supabase provider
64
-
65
- The selva app picks a provider per interface from env vars, via `createSelvaProviders` (`packages/server/src/providers/create-selva-providers.ts`) and the registry in `packages/selva/src/lib/server/providers.server.ts`:
66
-
67
- ```
68
- SELVA_AUTH_PROVIDER=supabase # local | supabase | header (default: local)
69
- SELVA_DATA_PROVIDER=supabase # local | supabase (default: local)
70
- SELVA_STORAGE_PROVIDER=supabase # local | supabase (default: local)
71
- ```
72
-
73
- To switch back to the local provider, remove the three vars (or set them to `local`) and restart.
74
-
75
- For a provider not bundled in the app, point `SELVA_CONFIG_PATH` at an external `selva.config.js`, loaded dynamically at boot in place of the env-driven wiring. It must be an actual `.js` file — there's no TS compiler at runtime.
76
-
77
- ---
78
-
79
- ## Applying the schema
80
-
81
- > **All Selva tables live in a dedicated `selva` schema, not `public`.** This keeps the `public` namespace entirely free for a consuming app's own tables — `selva.projects` and your `public.projects` can coexist. The initial migration creates the schema, grants the standard Supabase roles access, and tells PostgREST to expose it (see [Exposing the `selva` schema to PostgREST](#exposing-the-selva-schema-to-postgrest) for what that means on a hosted project).
82
-
83
- The `supabase/migrations/` directory holds timestamp-prefixed files, applied in filename order:
84
-
85
- | File | What it installs |
86
- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
87
- | `20260425155514_selva_initial.sql` | The `selva` schema itself, plus `user_profiles` (+ auto-seed trigger), `orgs` / `org_members` / `projects` / `project_members` (+ RLS helpers), `definitions` / `definition_versions` (+ deletion-protection FKs and the atomic `increment_run_count` RPC), `invites` (+ `get_invite_by_token` RPC), `compute_servers` (+ per-org/instance defaults), `share_links` (+ `try_increment_share_link_solve_count` RPC), and the `selva-public` / `selva-private` storage policies. |
88
- | `20260529202220_selva_definition_version_schema.sql` | Adds `definition_versions.schema` + `schema_extracted_at` (cached compute-extracted UI schema) and the `change_note` column. All `add column if not exists`, safe to re-run. |
89
-
90
- These two are only the foundation — `supabase/migrations/` ships further timestamp-prefixed files on top (solve metrics, org assets, definition status/audit, erasure functions, …). Filename order in that directory is authoritative, not this table.
91
-
92
- Future schema changes go in new timestamp-prefixed files: `<UTCtimestamp>_selva_<name>.sql` (e.g. `date -u +%Y%m%d%H%M%S` for the prefix). The `_selva_` infix and timestamp prefix let a consuming app's own migrations interleave by time without ever colliding with Selva's — see [Consuming migrations in an external app](#consuming-migrations-in-an-external-app).
93
-
94
- The `supabase/seed.sql` file creates the two storage buckets (`selva-public`, `selva-private`).
95
-
96
- **Local:** `npx supabase db reset` applies everything on a fresh DB.
97
-
98
- **Hosted:** link the CLI to your project, then push:
99
-
100
- ```bash
101
- cd packages/providers/supabase
102
-
103
- # One-time link. Reads the project-ref from Supabase Dashboard → Project Settings → General.
104
- npx supabase link --project-ref <your-project-ref>
105
-
106
- # Review what will be applied.
107
- npx supabase db diff
108
-
109
- # Apply migrations + seed.
110
- npx supabase db push
111
- ```
112
-
113
- You can also copy each `.sql` file into Supabase Dashboard → **SQL Editor** and run them in order, but prefer the CLI: it tracks which migrations already ran, so re-running it is safe.
114
-
115
- ### Exposing the `selva` schema to PostgREST
116
-
117
- Because the tables live in `selva` rather than `public`, PostgREST (the REST API supabase-js talks to) must be told to expose that schema, or every query fails with `PGRST106 Invalid schema` / `PGRST205 schema cache`.
118
-
119
- The initial migration handles this for you: it runs `alter role authenticator set pgrst.db_schemas = '…, selva'` and notifies PostgREST to reload. **You do not list `selva` in `config.toml`'s `[api] schemas`** — PostgREST reads that file at stack boot, before migrations run, so naming a not-yet-created schema there aborts `supabase start`. The migration is the right place because it runs after the schema exists.
120
-
121
- - **Local dev:** nothing to do — `db reset` / `db push` runs the migration, which exposes `selva` automatically.
122
- - **Hosted:** the migration still does the work on `db push`. As a belt-and-braces check (or if you applied SQL by hand in the Editor), confirm the schema is exposed under Dashboard → **Project Settings** → **API** → **Exposed schemas** — `selva` should be listed alongside `public` and `graphql_public`. Add it there if it's missing.
123
-
124
- ### Upgrading an existing database
125
-
126
- `supabase db push` keys on the version prefix recorded in the project's `supabase_migrations.schema_migrations` table. It applies any file whose prefix isn't recorded yet, in filename order, and skips the rest — so upgrading is always just **re-sync (external app) or re-pull (this repo), then `db push`**. Gaps and out-of-order prefixes are fine; only the lexical filename order matters.
127
-
128
- No backfill step is required for the schema-caching migration: existing definition versions keep working (the app falls back to fetching their schema from Rhino.Compute), and each version's `schema` column is populated lazily the first time it's solved.
129
-
130
- #### Migrated from the old `000N_` filenames?
131
-
132
- Earlier releases shipped `0001_initial.sql` / `0002_definition_version_schema.sql`, since renamed to `20260425155514_selva_initial.sql` / `20260529202220_selva_definition_version_schema.sql` (contents unchanged, only the names, so the files slot into a consuming app's migration timeline without collisions).
133
-
134
- To a database that already applied the `000N_` versions, the renamed files look like brand-new migrations. Both are idempotent (`create or replace`, `add column if not exists`), so a stray re-run is a harmless no-op, but you'd end up with duplicate history rows. To reconcile:
135
-
136
- - **Local dev stack:** just `npx supabase db reset` — applies the renamed files from scratch.
137
- - **Hosted project with the old versions applied:** tell the CLI the new versions are already present so it doesn't re-run them:
138
- ```bash
139
- npx supabase migration repair --status applied 20260425155514 20260529202220
140
- ```
141
- (Equivalent to inserting those version strings into `supabase_migrations.schema_migrations`.) Then future `db push` runs treat them as done.
142
-
143
- ### Consuming migrations in an external app
144
-
145
- When you install `@selvajs/supabase-provider` in your own app (rather than running it from this repo), the migration SQL ships inside the package. The clean way to apply it is to **sync the files into your app's own `supabase/migrations/` directory** and let the Supabase CLI drive them alongside your app's own migrations:
146
-
147
- ```bash
148
- # From your app root, after installing/upgrading the package:
149
- npx selva-supabase sync-migrations # copies into ./supabase/migrations
150
- npx supabase db push # applies anything not yet recorded
151
- ```
152
-
153
- `sync-migrations` copies each packaged migration **verbatim** (same timestamped filename, same bytes). That's deliberate: the filename is the migration's identity in the history table, so copying without renaming keeps every developer's and CI's history identical.
154
-
155
- - **`--dir <path>`** — target a non-default migrations directory.
156
- - **`--force`** — overwrite a same-named file whose content differs (otherwise it's reported as a conflict and the command exits non-zero, leaving your copy untouched).
157
- - Re-running is idempotent: unchanged files are skipped.
158
-
159
- **Upgrade flow** (running app, you bump the provider and it carries a new migration): `pnpm up @selvajs/supabase-provider`, then `npx selva-supabase sync-migrations` copies in the new file (later timestamp → sorts last), then `npx supabase db push` applies only that file and skips the ones already recorded. No renumbering, even if your app added its own migrations in between.
160
-
161
- **Notes specific to consuming in an external app:**
162
-
163
- - **Your tables stay in `public`; Selva's are in `selva`.** Because the engine owns a separate schema, there are no name clashes — your app can have its own `public.projects`, `public.orgs`, `public.definitions`, etc. without touching Selva's. Nothing to check before the first `db push`.
164
- - **Referencing engine objects from your own migrations.** When your app's tables need to point at the engine (FKs, RLS helpers), qualify them with the `selva` schema: `references selva.orgs(id)`, `selva.is_org_member(org_id)`, `selva.is_instance_admin()`, `selva.set_updated_at()`. The qualified names are self-documenting and won't accidentally resolve to a same-named object in your `public`.
165
- - **Expose `selva` in your app's PostgREST too.** If your app uses its own Supabase CLI project / `config.toml`, the synced initial migration exposes `selva` via `alter role authenticator …` when it runs — same mechanism as above. On a hosted project, verify it under Project Settings → API → Exposed schemas after the first push.
166
- - **Storage buckets aren't created by `db push` on a hosted project.** `seed.sql` (which creates `selva-public` / `selva-private`) is dev-only. On a hosted project, run it once by hand in the SQL Editor after the first push — same as the [Production](#production--hosted-supabase-project) flow.
7
+ **Operator setup — provisioning, env vars, migrations, production checklist:** [docs/self-hosting/providers/supabase.md](../../../docs/self-hosting/providers/supabase.md).
167
8
 
168
9
  ---
169
10
 
170
- ## Development — local Supabase stack
171
-
172
- Prerequisite: **Docker Desktop running.** First run pulls ~1 GB of images.
173
-
174
- ```bash
175
- cd packages/providers/supabase
176
- npx supabase start
177
- ```
178
-
179
- This spins up Postgres (54322), GoTrue/Auth (54321), Storage, Studio (54323), and Mailpit (54324 — fake SMTP inbox for auth emails). Migrations and the bucket seed apply automatically.
180
-
181
- Copy the printed **Publishable** and **Secret** keys into your `.env` at the selva app or repo root:
182
-
183
- ```bash
184
- # selva app .env
185
- SUPABASE_URL=http://127.0.0.1:54321
186
- SUPABASE_ANON_KEY=sb_publishable_...
187
- SUPABASE_SERVICE_ROLE_KEY=sb_secret_...
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { defineConfig } from '@selvajs/platform';
15
+ import {
16
+ SupabaseAuthProvider,
17
+ SupabaseDataProvider,
18
+ SupabaseStorageProvider
19
+ } from '@selvajs/supabase-provider';
20
+
21
+ export default defineConfig((env) => ({
22
+ auth: SupabaseAuthProvider.fromEnv(env),
23
+ data: SupabaseDataProvider.fromEnv(env),
24
+ storage: SupabaseStorageProvider.fromEnv(env)
25
+ }));
188
26
  ```
189
27
 
190
- Rhino.Compute server URL + API key are registered in `/admin/compute` after first boot.
191
-
192
- Set the three `SELVA_*_PROVIDER=supabase` env vars (above), then:
193
-
194
- ```bash
195
- pnpm dev
196
- ```
197
-
198
- **Useful commands:**
199
-
200
- ```bash
201
- npx supabase status # show URL + keys again
202
- npx supabase db reset # wipe DB + re-run migrations + seed
203
- npx supabase stop # stop containers (keeps volumes)
204
- npx supabase stop --no-backup # stop + wipe volumes
205
- ```
28
+ The Selva app already bundles this wiring — it picks a provider per interface from `SELVA_AUTH_PROVIDER` / `SELVA_DATA_PROVIDER` / `SELVA_STORAGE_PROVIDER` via `createSelvaProviders` ([create-selva-providers.ts](../../server/src/providers/create-selva-providers.ts)) over the registry in [providers.server.ts](../../selva/src/lib/server/providers.server.ts). For a provider not bundled in the app, point `SELVA_CONFIG_PATH` at an external `selva.config.js` — an actual `.js` file, since there's no TS compiler at runtime.
206
29
 
207
- Studio is a full admin UI at `http://127.0.0.1:54323`. Use it to inspect tables, rows, and RLS policies while developing.
30
+ `SupabaseDataProvider.fromEnv` refuses to construct without `SELVA_AT_REST_KEY`; it encrypts `compute_servers.api_key` before it reaches the database.
208
31
 
209
32
  ---
210
33
 
211
- ## Production — hosted Supabase project
212
-
213
- 1. Create a project on [supabase.com](https://supabase.com). Choose a region close to your selva app deployment.
214
- 2. Dashboard → **Project Settings** → **API**. Copy the **Project URL**, **Publishable** key, and **Secret** key.
215
- 3. Apply migrations via the CLI:
216
- ```bash
217
- cd packages/providers/supabase
218
- npx supabase link --project-ref <your-project-ref>
219
- npx supabase db push
220
- ```
221
- 4. Create the two storage buckets by running `supabase/seed.sql` in the Dashboard → **SQL Editor** (the CLI's `db push` doesn't run the seed on a hosted project — it's dev-only).
222
- 5. Set the env vars on your selva app host (Vercel, Fly.io, Docker, etc.):
223
- ```
224
- SUPABASE_URL=https://<project-ref>.supabase.co
225
- SUPABASE_ANON_KEY=sb_publishable_...
226
- SUPABASE_SERVICE_ROLE_KEY=sb_secret_...
227
- ```
228
- After deploying, register your Rhino.Compute server URL (+ optional API key) via `/admin/compute`.
229
- 6. Deploy the selva app with the three `SELVA_*_PROVIDER=supabase` env vars set.
230
- 7. Bootstrap the first user:
231
- - Open `/setup` once — creates the first admin with `instance_admin`.
232
- - Or manually: Dashboard → **Authentication** → **Add user**, then in the SQL Editor: `UPDATE selva.user_profiles SET platform_permissions = ARRAY['instance_admin']::text[] WHERE user_id = '<uuid>';`
233
-
234
- ### Operational checklist
235
-
236
- - **Backups.** Supabase handles daily backups on paid plans; verify restore works before relying on it.
237
- - **Rotate keys** if the Secret key is ever logged or committed. Dashboard → **Project Settings** → **API** → **Reset service_role key**.
238
- - **Row-level security is on for every table.** Disabling it on any table silently breaks the tenant boundary.
239
- - **Email sender.** Dashboard → **Authentication** → **Email templates** — configure an SMTP provider before going live, otherwise password-reset emails route through Supabase's rate-limited dev sender.
34
+ ## Migrations
240
35
 
241
- ---
36
+ `supabase/migrations/` holds timestamp-prefixed files applied in filename order. **That directory is authoritative** — don't expect a list here to stay current.
242
37
 
243
- ## Running the conformance tests
38
+ `20260425155514_selva_initial.sql` installs the foundation: the `selva` schema itself, `user_profiles` (+ the `handle_new_auth_user` auto-seed trigger), `orgs` / `org_members` / `projects` / `project_members` (+ RLS helpers), `definitions` / `definition_versions` (+ deletion-protection FKs and the atomic `increment_run_count` RPC), `invites` (+ `get_invite_by_token`), `compute_servers`, `share_links` (+ `try_increment_share_link_solve_count`), and the `selva-public` / `selva-private` storage policies. Everything after it layers on top — cached version schemas, solve metrics, org assets, definition status/audit, erasure functions.
244
39
 
245
- The package ships a full conformance suite that runs against a **live** Supabase stack. It proves the provider implements every interface the same way the local provider does.
40
+ New schema changes go in new files named `<UTCtimestamp>_selva_<name>.sql` (`date -u +%Y%m%d%H%M%S` for the prefix). The `_selva_` infix and timestamp prefix let a consuming app's own migrations interleave by time without ever colliding with Selva's.
246
41
 
247
- ```bash
248
- cd packages/providers/supabase
42
+ `supabase/seed.sql` creates the two storage buckets. It is dev-only — the CLI does not run it on a hosted project.
249
43
 
250
- # 1. Make sure the stack is running.
251
- npx supabase start
44
+ **No backfill is required for the schema-caching migration.** Existing definition versions keep working (the app falls back to fetching their schema from Rhino.Compute), and each version's `schema` column fills in lazily the first time it's solved.
252
45
 
253
- # 2. Create .env.test with the same three vars.
254
- # (This is separate from your app's .env — it's gitignored and used only by tests.)
255
- cat > .env.test <<EOF
256
- SUPABASE_URL=http://127.0.0.1:54321
257
- SUPABASE_ANON_KEY=<publishable key>
258
- SUPABASE_SERVICE_ROLE_KEY=<secret key>
259
- EOF
260
-
261
- # 3. Run.
262
- pnpm test
263
- ```
264
-
265
- When `.env.test` is missing the suite skips with a single explanatory test.
266
-
267
- The suite wipes every table and every auth user between tests — **do not point it at a production project.**
46
+ The packaged migrations reach a consuming app through the `selva-supabase` bin ([src/cli/sync-migrations.ts](src/cli/sync-migrations.ts)), which copies them verbatim into the app's own `supabase/migrations/`. See the [operator page](../../../docs/self-hosting/providers/supabase.md#3-apply-the-schema) for the flow.
268
47
 
269
48
  ---
270
49
 
@@ -275,19 +54,19 @@ The suite wipes every table and every auth user between tests — **do not point
275
54
  Two buckets:
276
55
 
277
56
  - **`selva-public`** (public) — covers, archives. `getPublicUrl` returns the direct CDN URL.
278
- - **`selva-private`** (private) — `.gh` / `.ghx` files. `getPublicUrl` returns `/api/files/{path}` which the selva app's route handler must proxy after an auth check.
57
+ - **`selva-private`** (private) — `.gh` / `.ghx` files. `getPublicUrl` returns `/api/files/{path}`, which the selva app's route handler proxies after an auth check.
279
58
 
280
59
  Images are transcoded to WebP (1200px cap, quality 85) via the shared `transcodeImageIfNeeded` helper from `@selvajs/platform/storage`. Same bytes out of both providers.
281
60
 
282
61
  ### Auth
283
62
 
284
- `SupabaseAuthProvider.verifyLogin` wraps `supabase.auth.signInWithPassword`, returning the JWT directly as `sessionToken`. `verifyToken` calls `supabase.auth.getUser(token)` — GoTrue validates the signature for us. Platform permissions merge in from `user_profiles.platform_permissions` (auto-created by the signup trigger).
63
+ `SupabaseAuthProvider.verifyLogin` wraps `supabase.auth.signInWithPassword`, returning the JWT directly as `sessionToken`. `verifyToken` calls `supabase.auth.getUser(token)` — GoTrue validates the signature for us. Platform permissions merge in from `user_profiles.platform_permissions`.
285
64
 
286
65
  MFA methods on `IPasswordAuth` are currently undefined — MFA is deferred. If a user enrolls a factor via the Supabase dashboard, `signInWithPassword` returns an AAL1 session and routes that gate on AAL2 would fail; no route does today.
287
66
 
288
67
  ### Data + RLS
289
68
 
290
- Every client is constructed with `db: { schema: 'selva' }`, so a bare `client.from('orgs')` resolves to `selva.orgs`. Every store goes through `ClientBundle.forRequest(ctx)`:
69
+ Every client is constructed with `db: { schema: 'selva' }`, so a bare `client.from('orgs')` resolves to `selva.orgs`. Every store goes through `ClientBundle.forRequest(ctx)` ([src/data/client.ts](src/data/client.ts)):
291
70
 
292
71
  - `ctx.system` → service-role client (bypasses RLS)
293
72
  - `ctx.adapterContext.sessionToken` → anon client with `Authorization: Bearer <jwt>` (RLS enforces per-user visibility)
@@ -302,18 +81,31 @@ Helper SQL functions (`selva.is_instance_admin`, `selva.is_org_member`, `selva.v
302
81
  ### Atomic improvements over the local provider
303
82
 
304
83
  - **`incrementRunCount`** uses a SQL function (`UPDATE … SET run_count = run_count + 1`) — atomic. The local provider does read-modify-write and can lose bumps under concurrent solves.
84
+ - **`try_increment_share_link_solve_count`** enforces a share link's cap in one statement, so concurrent solves can't overshoot it.
85
+
86
+ ### Erasure
87
+
88
+ `SupabaseDataProvider.onUserDeleted(ctx, userId, { email })` scrubs what FK cascade doesn't reach: deletes `audit_events` the user authored (keyed by plain-text `actor_id`), deletes `invites` addressed to their email, redacts that email from surviving `invite.created` payloads (`redact_audit_event_email`), and tombstones `solve_metrics.actor_id` so capacity aggregates survive while the person doesn't. The caller must capture the email **before** `SupabaseAuthProvider.deleteUser` runs. Credentials live in Supabase `auth.users`, but the operator is still the data controller for everything above — see [data privacy](../../../docs/self-hosting/concepts/data-privacy.md).
305
89
 
306
90
  ---
307
91
 
308
- ## Status
92
+ ## Conformance tests
93
+
94
+ The package ships the `@selvajs/platform` conformance suites running against a **live** Supabase stack. They prove this provider implements every interface the same way the local provider does.
95
+
96
+ ```bash
97
+ cd packages/providers/supabase
98
+ npx supabase start
99
+
100
+ cat > .env.test <<EOF
101
+ SUPABASE_URL=http://127.0.0.1:54321
102
+ SUPABASE_ANON_KEY=<publishable key>
103
+ SUPABASE_SERVICE_ROLE_KEY=<secret key>
104
+ EOF
309
105
 
310
- Every interface from `@selvajs/platform` is implemented and exercised by the shared conformance suites against a live local Supabase stack:
106
+ pnpm test
107
+ ```
311
108
 
312
- - `SupabaseAuthProvider` (incl. MFA-ready `LoginResult`)
313
- - `SupabaseStorageProvider`
314
- - `SupabaseOrgStore`, `SupabaseProjectStore`, `SupabaseDefinitionStore` (atomic `incrementRunCount`), `SupabaseInviteStore`, `SupabaseShareLinkStore`, `SupabaseComputeServerStore`
315
- - `SupabaseUserProfileProvider`
316
- - `SupabasePlatformPermissionStore`
317
- - `SupabaseDataProvider` — composition of the data stores
109
+ `.env.test` is gitignored and separate from your app's `.env`. `vitest.config.ts` loads it if present and probes `SUPABASE_URL` before the run; if the file is missing or the stack is unreachable it strips the three vars so every suite takes its no-credentials skip path and prints a warning.
318
110
 
319
- Run them with `pnpm test` (see [Running the conformance tests](#running-the-conformance-tests)).
111
+ The suites wipe every table and every auth user between tests — **do not point them at a production project.**
@@ -8,7 +8,11 @@
8
8
  // copy time would make every machine/CI produce a different history.
9
9
  //
10
10
  // Usage:
11
- // npx @selvajs/supabase-provider sync-migrations [--dir <path>] [--force]
11
+ // npx selva-supabase [--dir <path>] [--force]
12
+ //
13
+ // The bin is `selva-supabase` and this script IS the whole command — there is
14
+ // no `sync-migrations` subcommand to type, and parseArgs rejects one as an
15
+ // unknown argument.
12
16
  //
13
17
  // --dir <path> Target migrations dir (default: ./supabase/migrations)
14
18
  // --force Overwrite files that exist with differing content
@@ -46,10 +50,10 @@ function parseArgs(argv) {
46
50
  }
47
51
  function printHelp() {
48
52
  console.log([
49
- 'sync-migrations — copy @selvajs/supabase-provider migrations into your app.',
53
+ 'selva-supabase — copy @selvajs/supabase-provider migrations into your app.',
50
54
  '',
51
55
  'Usage:',
52
- ' npx @selvajs/supabase-provider sync-migrations [--dir <path>] [--force]',
56
+ ' npx selva-supabase [--dir <path>] [--force]',
53
57
  '',
54
58
  ' --dir <path> Target migrations dir (default: ./supabase/migrations)',
55
59
  ' --force Overwrite files that exist with differing content',
@@ -1 +1 @@
1
- {"version":3,"file":"sync-migrations.js","sourceRoot":"","sources":["../../src/cli/sync-migrations.ts"],"names":[],"mappings":";AACA,+EAA+E;AAC/E,6EAA6E;AAC7E,wCAAwC;AACxC,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AAC5E,qEAAqE;AACrE,EAAE;AACF,SAAS;AACT,4EAA4E;AAC5E,EAAE;AACF,0EAA0E;AAC1E,qEAAqE;AACrE,+EAA+E;AAE/E,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE1F,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAErD,uDAAuD;AACvD,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AAO9D,SAAS,SAAS,CAAC,IAAc;IAChC,IAAI,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IACjE,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK;gBAAE,IAAI,CAAC,gCAAgC,CAAC,CAAC;YACnD,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;aAAM,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAC9B,KAAK,GAAG,IAAI,CAAC;QACd,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC7C,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;QAClC,CAAC;IACF,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,SAAS;IACjB,OAAO,CAAC,GAAG,CACV;QACC,6EAA6E;QAC7E,EAAE;QACF,QAAQ;QACR,2EAA2E;QAC3E,EAAE;QACF,yEAAyE;QACzE,oEAAoE;QACpE,EAAE;QACF,iDAAiD;KACjD,CAAC,IAAI,CAAC,IAAI,CAAC,CACZ,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,OAAe;IAC5B,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,IAAI;IACZ,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9D,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC,2CAA2C,SAAS,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC;SAClC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SACvC,IAAI,EAAE,CAAC;IAET,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAEpC,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;YAClC,IAAI,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC/B,OAAO,EAAE,CAAC;gBACV,SAAS;YACV,CAAC;YACD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CACX,eAAe,IAAI,2DAA2D,CAC9E,CAAC;gBACF,SAAS,EAAE,CAAC;gBACZ,SAAS;YACV,CAAC;QACF,CAAC;QAED,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC;IACV,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,YAAY,OAAO,eAAe,SAAS,mBAAmB,SAAS,EAAE,CAAC,CAAC;IAElG,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;AACzE,CAAC;AAED,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"sync-migrations.js","sourceRoot":"","sources":["../../src/cli/sync-migrations.ts"],"names":[],"mappings":"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"}
@@ -112,8 +112,8 @@ export class SupabaseDataProvider {
112
112
  */
113
113
  async verifySchemaVersion() {
114
114
  const expected = EXPECTED_MIGRATION_HEAD;
115
- const pushHint = 'Apply the pending Supabase migrations: sync them into your project ' +
116
- '(see @selvajs/supabase-provider sync-migrations) and run `npx supabase db push`.';
115
+ const pushHint = 'Apply the pending Supabase migrations: run `npx selva-supabase` to copy them ' +
116
+ 'into your project, then `npx supabase db push`.';
117
117
  try {
118
118
  const { data, error } = await this.clients.serviceClient.rpc('migration_head');
119
119
  if (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"SupabaseDataProvider.js","sourceRoot":"","sources":["../../src/data/SupabaseDataProvider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SupabaseDataProvider.js","sourceRoot":"","sources":["../../src/data/SupabaseDataProvider.ts"],"names":[],"mappings":"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"}
@@ -3,5 +3,5 @@
3
3
  * whenever a migration is added — `migration-head.test.ts` asserts it
4
4
  * matches the migrations directory, so CI catches drift.
5
5
  */
6
- export declare const EXPECTED_MIGRATION_HEAD = "20260817200000";
6
+ export declare const EXPECTED_MIGRATION_HEAD = "20260821120000";
7
7
  //# sourceMappingURL=migrationHead.d.ts.map
@@ -3,5 +3,5 @@
3
3
  * whenever a migration is added — `migration-head.test.ts` asserts it
4
4
  * matches the migrations directory, so CI catches drift.
5
5
  */
6
- export const EXPECTED_MIGRATION_HEAD = '20260817200000';
6
+ export const EXPECTED_MIGRATION_HEAD = '20260821120000';
7
7
  //# sourceMappingURL=migrationHead.js.map
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@selvajs/supabase-provider",
3
- "version": "0.19.0",
3
+ "version": "0.19.2",
4
4
  "description": "Supabase (Auth + Postgres + Storage) implementations of @selvajs/platform interfaces",
5
5
  "license": "MIT",
6
6
  "author": "VektorNode",
7
- "homepage": "https://github.com/VektorNode/selva#readme",
7
+ "homepage": "https://selva.dev",
8
8
  "bugs": "https://github.com/VektorNode/selva/issues",
9
9
  "keywords": [
10
10
  "selva",
@@ -72,11 +72,11 @@
72
72
  "dependencies": {
73
73
  "@supabase/supabase-js": "^2.112.2",
74
74
  "sharp": "^0.35.3",
75
- "@selvajs/platform": "^0.19.0"
75
+ "@selvajs/platform": "^0.19.1"
76
76
  },
77
77
  "devDependencies": {
78
- "@types/node": "^24.13.3",
79
- "supabase": "^2.112.0",
78
+ "@types/node": "^26.2.0",
79
+ "supabase": "^2.114.0",
80
80
  "typescript": "~6.0.3",
81
81
  "vitest": "^4.1.10",
82
82
  "@selvajs/config": "0.0.4"
@@ -0,0 +1,24 @@
1
+ -- Two index gaps that only show up once the tables grow.
2
+ --
3
+ -- 1. Definition lists default to `order by created_at` under a `project_id`
4
+ -- filter. `idx_definitions_project` covers the filter but not the sort, so
5
+ -- every project page sorts its whole slice in memory.
6
+ -- 2. Audit pagination is keyset on `(occurred_at desc, id desc)` — see
7
+ -- SupabaseAuditQuery — but the existing indexes stop at `occurred_at`, so
8
+ -- the tie-breaker is a sort, not an index scan.
9
+
10
+ create index if not exists idx_definitions_project_created
11
+ on selva.definitions (project_id, created_at desc)
12
+ where deleted_at is null;
13
+
14
+ drop index if exists selva.audit_events_occurred_at_idx;
15
+ create index if not exists audit_events_occurred_at_id_idx
16
+ on selva.audit_events (occurred_at desc, id desc);
17
+
18
+ drop index if exists selva.audit_events_type_occurred_at_idx;
19
+ create index if not exists audit_events_type_occurred_at_id_idx
20
+ on selva.audit_events (type, occurred_at desc, id desc);
21
+
22
+ drop index if exists selva.audit_events_actor_occurred_at_idx;
23
+ create index if not exists audit_events_actor_occurred_at_id_idx
24
+ on selva.audit_events (actor_id, occurred_at desc, id desc);