@supabase/lite 0.9.0 → 0.9.1-next.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.
Files changed (64) hide show
  1. package/FEATURES.md +176 -0
  2. package/LIMITATIONS.md +9 -6
  3. package/PATTERNS.md +66 -6
  4. package/README.md +16 -8
  5. package/STATUS.md +33 -20
  6. package/dist/{Connection-ZWTDByQ5.d.ts → Connection-f_d5HhQ0.d.ts} +301 -293
  7. package/dist/cli/index.js +127 -124
  8. package/dist/cli/lib.d.ts +1 -12
  9. package/dist/cli/lib.js +44 -39
  10. package/dist/db/fallback.d.ts +1 -1
  11. package/dist/db/postgres/PostgresConnection.js +18 -18
  12. package/dist/db/postgres/pglite/PgliteConnection.js +17 -17
  13. package/dist/index.d.ts +116 -40
  14. package/dist/index.js +181 -73
  15. package/dist/static/.vite/manifest.json +34 -2
  16. package/dist/static/assets/InterVariable-Dx4kXJAl.woff2 +0 -0
  17. package/dist/static/assets/InterVariable-Italic-DpCbqKDY.woff2 +0 -0
  18. package/dist/static/assets/SourceCodePro-Variable-BP8Zz55n.woff2 +0 -0
  19. package/dist/static/assets/SourceCodePro-Variable-Italic-eALmlzX7.woff2 +0 -0
  20. package/dist/static/assets/main-BY4iigay.css +1 -0
  21. package/dist/static/assets/main-BnQ-v4V9.js +199 -0
  22. package/dist/static/assets/manrope-latin-ext-wght-normal-Ch3YOpNY.woff2 +0 -0
  23. package/dist/static/assets/manrope-latin-wght-normal-DHIcAJRg.woff2 +0 -0
  24. package/dist/vite/index.d.ts +627 -31
  25. package/dist/vite/index.js +2 -2
  26. package/docs/auth/email.mdx +214 -0
  27. package/docs/auth/not-supported.mdx +57 -0
  28. package/docs/auth/overview.mdx +52 -0
  29. package/docs/auth/supported-flows.mdx +120 -0
  30. package/docs/cli/overview.mdx +112 -0
  31. package/docs/cli/telemetry.mdx +34 -0
  32. package/docs/compatibility.mdx +115 -0
  33. package/docs/database/backends.mdx +118 -0
  34. package/docs/database/data-api.mdx +90 -0
  35. package/docs/database/functions-triggers.mdx +93 -0
  36. package/docs/database/migrations.mdx +95 -0
  37. package/docs/database/overview.mdx +66 -0
  38. package/docs/database/postgres-sqlite-translation.mdx +130 -0
  39. package/docs/database/rls.mdx +161 -0
  40. package/docs/database/schemas.mdx +58 -0
  41. package/docs/index.mdx +49 -0
  42. package/docs/integrations/embedded.mdx +100 -0
  43. package/docs/integrations/frameworks.mdx +83 -0
  44. package/docs/integrations/vite.mdx +87 -0
  45. package/docs/llms.txt +52 -0
  46. package/docs/other/edge-functions.mdx +34 -0
  47. package/docs/other/realtime.mdx +22 -0
  48. package/docs/quickstart.mdx +150 -0
  49. package/docs/running.mdx +127 -0
  50. package/docs/storage/adapters.mdx +75 -0
  51. package/docs/storage/limitations.mdx +21 -0
  52. package/docs/storage/overview.mdx +88 -0
  53. package/docs/upgrade.mdx +108 -0
  54. package/package.json +5 -1
  55. package/skills/supalite/SKILL.md +6 -4
  56. package/dist/static/assets/main-1bwWb_1q.js +0 -40996
  57. package/dist/static/assets/main-BDsRycsc.css +0 -4045
  58. package/dist/static/fonts/CustomFont-Black.woff2 +0 -0
  59. package/dist/static/fonts/CustomFont-BlackItalic.woff2 +0 -0
  60. package/dist/static/fonts/CustomFont-Bold.woff2 +0 -0
  61. package/dist/static/fonts/CustomFont-BoldItalic.woff2 +0 -0
  62. package/dist/static/fonts/CustomFont-Book.woff2 +0 -0
  63. package/dist/static/fonts/CustomFont-BookItalic.woff2 +0 -0
  64. package/dist/static/fonts/CustomFont-Medium.woff2 +0 -0
package/STATUS.md CHANGED
@@ -36,7 +36,7 @@ Feature and API compatibility tracking for @supabase/lite. For usage docs, see [
36
36
 
37
37
  When using SQLite databases, SQL schemas written in Postgres dialect are translated on the fly. The translator extends the Postgres deparser. It passes through 1:1 compatible syntax unchanged, rewrites constructs that have SQLite equivalents (for example `SERIAL` → `INTEGER PRIMARY KEY AUTOINCREMENT`, `NOW()` → `datetime('now')`), silently drops Postgres-only decorators and relation/schema privilege metadata (storage parameters, locking clauses, table/schema/sequence grants), and errors on features that have no SQLite counterpart (`LATERAL` joins, table inheritance, function grants).
38
38
 
39
- 📋 See [`app/POSTGRES-SQLITE-COMPAT.md`](https://github.com/supabase-community/lite/blob/HEAD/app/POSTGRES-SQLITE-COMPAT.md) for the full auto-generated compatibility reference (71 entries).
39
+ 📋 See [`app/POSTGRES-SQLITE-COMPAT.md`](https://github.com/supabase-community/lite/blob/HEAD/app/POSTGRES-SQLITE-COMPAT.md) for the full auto-generated compatibility reference (74 entries).
40
40
 
41
41
  Here is an example of a Postgres schema that is translated to SQLite:
42
42
 
@@ -130,6 +130,12 @@ CREATE TABLE orders
130
130
  -- RLS statements not emitted
131
131
  ```
132
132
 
133
+ ### Extension Statements
134
+
135
+ On the SQLite translation path, `CREATE EXTENSION` is accepted only for `plpgsql`, `pgcrypto`, and `uuid-ossp`, then omitted from the emitted DDL. The `plpgsql` declaration is accepted for `pg_dump` schema compatibility; PL/pgSQL support remains limited to the documented trigger-function subset. The UUID declarations allow migrations that use the supported `gen_random_uuid()` and `uuid_generate_v4()` defaults to run, but no other extension APIs are provided. Valid creation modifiers such as `IF NOT EXISTS`, `WITH SCHEMA`, `VERSION`, and `CASCADE` are accepted for those three exact names; quoted names remain case-sensitive.
136
+
137
+ To keep declarative `db diff` state convergent, `ALTER EXTENSION <accepted-name> SET SCHEMA ...` and `DROP EXTENSION` containing only accepted names are also omitted. Every other `CREATE EXTENSION`, all extension updates/member changes, schema moves for unsupported extensions, and drops containing an unsupported name fail during translation before any statement in that migration is executed. PGlite and PostgreSQL run extension statements natively; the bare `sqlite` driver does not translate PostgreSQL DDL.
138
+
133
139
  ### Translated Field Types
134
140
 
135
141
  | PostgreSQL type / syntax | SQLite storage | Field implementation | Mapping / validation |
@@ -154,6 +160,8 @@ CREATE TABLE orders
154
160
  | `CREATE TYPE ... AS ENUM` | `TEXT` | `EnumField` | Emits allowed-value `CHECK (... IN (...))`. |
155
161
  | `<type>[]`, `_type` arrays | `TEXT` | `ArrayField` | Stores JSON arrays and delegates element serialization where possible. |
156
162
 
163
+ Mutating an existing enum on the SQLite path (`ALTER TYPE ... ADD VALUE` / `RENAME VALUE`) is not supported; the translator fails with a clear error that names the type and operation. Recreate the type with the full value set, or track the change in a manual migration.
164
+
157
165
  Unsupported PostgreSQL data types currently include `oid`, `xid`, `xid8`, `cid`, `money`, `citext`, `cidr`, `macaddr`, `macaddr8`, `bit`, `bit varying`, `varbit`, geometric types (`point`, `line`, `lseg`, `box`, `path`, `polygon`, `circle`), `xml`, text-search types (`tsvector`, `tsquery`), range and multirange types, `reg*` catalog reference types, internal types (`tid`, `pg_lsn`, `internal`), pseudo-types, and handler types.
158
166
 
159
167
  **Custom domains & data representations.** On the Postgres path (PGlite/PostgreSQL), a column typed as a domain that defines `CAST(<domain> AS json)` (the PostgREST "data representations" feature) renders through that cast on reads and `RETURNING` — e.g. a `unixtz` domain over `timestamptz` returns epoch seconds, a `monetary` domain over `numeric` returns a fixed-precision string. On the SQLite path the known representation types (`color`, `unixtz`, `isodate`, `monetary`, `bytea_b64`) are handled by built-in field shims. Mutating JSON values **into** a domain column (epoch→`timestamptz`, base64→`bytea`, decimal-string→`numeric`) is converted on the Postgres path via `buildDomainInputValue`. Not yet handled: domain formatting through cross-relation embeds. Postgres connections run with `TimeZone=UTC` by default so `timestamptz` rendering is deterministic regardless of the server's host timezone; override via the `postgresOptions.connection.TimeZone` connection option.
@@ -222,6 +230,7 @@ RLS is supported on all database backends. The enforcement strategy differs by d
222
230
  | Feature | SQLite | PGlite/Postgres | Notes |
223
231
  |------------------------------------------------|--------|-----------------|-------------------------------------------------------------|
224
232
  | `ENABLE ROW LEVEL SECURITY` | ✅ | ✅ | Default-deny when no policies match |
233
+ | `DISABLE ROW LEVEL SECURITY` | ✅ | ✅ | Policies remain stored but inert until RLS is enabled again |
225
234
  | `CREATE POLICY ... USING (expr)` | ✅ | ✅ | SQLite: merged into `WHERE`; Postgres: native |
226
235
  | `CREATE POLICY ... WITH CHECK (expr)` | ✅ | ✅ | SQLite: validated in-memory; Postgres: native |
227
236
  | `AS PERMISSIVE` (default) | ✅ | ✅ | Multiple permissive policies `OR`'d |
@@ -244,7 +253,7 @@ Each supported behavior is regression-covered against both backends in [`app/tes
244
253
 
245
254
  📖 See [`internal/docs/postgres/rls.md`](https://github.com/supabase-community/lite/blob/HEAD/internal/docs/postgres/rls.md) for the full RLS reference and behavior matrix.
246
255
 
247
- **SQLite metadata persistence (`sqlite-postgres`):** Policies live in translation metadata, not in the database file, so a command that never migrates would otherwise boot with RLS off. Every declarative schema translation, every `lite db reset`, and every migration apply in a migrations-only project writes the full deparse info to `supabase/.temp/.deparse-cache.json`. `lite start` restores that cache, verified against the migration-history fingerprint, the schema hash, member-level payload validation, and a cross-check that its RLS table list still covers everything the applied migration history enabled RLS on. When the cache is missing or stale, a migrations-only project recalculates from the applied migration history (never from unapplied migration files). A declarative project (`supabase/schemas/*.sql`) is instead refused outright, with no exceptions: `lite start` serves the migrations workflow and never applies schema files, so without a valid cache it exits with non-interactive recovery instructions rather than guessing. `lite db diff -f <name>` then `lite db reset` is the transition that establishes migration authority — the generated migration carries the schema's `ENABLE ROW LEVEL SECURITY` / `CREATE POLICY` statements, and `db reset` is destructive, so afterwards the migration-derived metadata describes the fresh database exactly and is always persisted. That is what makes the recovery loop terminate. A non-destructive `lite migration up` never persists over a declarative project's snapshot, because it cannot know what the live database still carries from a declarative apply. RLS metadata also follows the table lifecycle: an `ALTER TABLE ... RENAME TO` carries enforcement and its policies to the new name, and a `DROP TABLE` (even followed by a `CREATE TABLE` of the same name) drops them, matching Postgres. Embedded/programmatic use falls back to a per-table deny backstop. The cache file is safe to delete — it is regenerated by the next apply, and a boot that cannot rebuild it fails closed, never open. `pglite` / `postgres` (native RLS) and the bare `sqlite` driver are unaffected. See [LIMITATIONS.md](https://github.com/supabase-community/lite/blob/HEAD/LIMITATIONS.md) for the declarative-project workflow.
256
+ **SQLite runtime metadata (`sqlite-postgres`):** Policies, Postgres field types, enums, constraints, comments, variables, and relationship metadata are collected during translation and stored in the disposable runtime metadata cache at `supabase/.temp/.runtime-metadata-cache.json`. For `lite start`, the only authority is the ordered `{version, statements}` history in `supabase_migrations.schema_migrations`: applied files may be edited or deleted, pending files and `schemas/*.sql` are ignored, and a missing, corrupt, old, stale, or tampered cache is rebuilt automatically from the recorded SQL. Startup also replays the same history into an in-memory SQLite database and compares its raw structure with the live database; introspection is used only for equality checking, never to invent metadata. Invalid history or out-of-band structural DDL exits with a `lite db reset` hint. `lite migration up` and `lite db reset` refresh migration-derived metadata even when no new migration was applied. `lite dev` and the Vite plugin remain declarative: after applying migrations they replace the complete metadata payload from the applied declarative schema, including after watched migrations. Cache writes use a sibling temporary file plus atomic rename and are best-effort; a write failure leaves the previous file intact while the rebuilt in-memory payload remains usable. Embedded/programmatic use retains the history-based deny backstop as a last resort. `pglite` / `postgres` (native RLS) and bare `sqlite` are unaffected.
248
257
 
249
258
  **PGlite / PostgreSQL auto-setup:** When any table has `ENABLE ROW LEVEL SECURITY`, supalite creates `anon`, `authenticated`, and `service_role` roles (if missing; `service_role` uses `BYPASSRLS`) and grants default privileges on all tables and sequences in the relevant schemas. No manual `CREATE ROLE` or `GRANT` statements needed for these built-in roles.
250
259
 
@@ -534,7 +543,7 @@ Opaque `sb_publishable_*` / `sb_secret_*` keys, matching Supabase's current key
534
543
  | `/storage/v1` | ⚠️ | Transform-only, like upstream self-hosted Kong: keys map to roles when present, but a missing/invalid key never 401s at the gateway (public objects, signed URLs, S3 presigned flows stay keyless). Storage's own route auth still applies; a secret key satisfies storage's authed routes as `service_role` (including bypassing RLS-equivalent checks on SQLite) |
535
544
  | Secret key + browser `User-Agent` (`Mozilla/5.0`) | ✅ | Rejected (401), mirrors the hosted gateway's browser guard |
536
545
  | OpenAPI root (`GET /rest/v1/`) | ✅ | Requires the secret key: publishable → 403, secret → 200, mirroring upstream's admin-only ACL on that route (LITE-35) |
537
- | Local admin mode (`options.server.admin`) | ✅ | Local-dev only. A request with **no** credential (no `apikey` header/query, no `Authorization`) on `/rest/v1` or `/storage/v1` is served as `service_role`, so a browser studio can do admin work without a secret key reaching the browser. Also requires same-origin (or no `Origin`), a loopback **socket peer**, and a loopback **hostname** both halves: the peer check stops a LAN client spoofing `Host: localhost`, the hostname check stops DNS rebinding (where the socket really is loopback but `Host`/`Origin` are the attacker's domain). `/auth/v1` is never elevated. On by default for `lite dev`, `lite start` (`--no-admin` to disable) and the Vite dev server (`/rest/v1` only there the plugin doesn't mount `/storage/v1`); off for `vite preview` and for embedders. Precedence: explicit flag > `options.server.admin` in config > launcher default. Credentialed requests are unaffected, so `anon`/`authenticated` RLS stays testable (LITE-309) |
546
+ | Local admin mode (`options.server.admin`) | ✅ | Local-dev only. A request with **no** credential (no `apikey` header/query, no `Authorization`) on `/rest/v1` or `/storage/v1` is served as `service_role`, so browser Studio can do admin work without receiving a secret key. Elevation requires same-origin (or no `Origin`), a loopback **socket peer**, and a loopback **hostname**; transport adapters pass the peer through `App.fetch(request, { peerAddress })`, which fails closed when unavailable. `/auth/v1` is never elevated. `lite dev`/`lite start` bind `127.0.0.1` and default admin on; `--host [host]` exposes/selects an address and defaults it off unless `--admin` is explicit. Exposed Vite hosts likewise require `supalite({ admin: true })`; preview and embedders default off. Credentialed requests are never elevated (LITE-309, LITE-332) |
538
547
  | Secrets redacted from `/_system/config` / `/_system/info` | ✅ | `auth.secret_key` and `auth.jwt_secret` are masked in both responses |
539
548
  | Legacy JWT-as-apikey (`ANON_KEY`/`SERVICE_ROLE_KEY` HS256) | ❌ | Not supported |
540
549
  | `options.server.apiKeys: false` | ✅ | Disables enforcement entirely (embedders) |
@@ -659,6 +668,11 @@ Backend implementation in `app/src/storage/`. HTTP endpoints at `/storage/v1/*`.
659
668
  | `POST /object/upload/sign/:bucketId/*` | Sign | Create signed upload URL |
660
669
  | `GET /object/sign/:bucketId/*` | Download | Via signed URL token |
661
670
  | `PUT /object/upload/sign/:bucketId/*` | Upload | Via signed upload URL |
671
+ | `GET /status` | Health | No authentication required |
672
+
673
+ Storage metadata operations use the same verified JWT claims and RLS execution path as the Data API on SQLite, PGlite, and PostgreSQL. The `storage` schema is protected and omitted from the default PostgREST `api.schemas` list; `/storage/v1` remains the supported client surface, while explicitly adding `storage` enables direct metadata endpoints. On SQLite, the system schema declaration keeps `storage.buckets` and `storage.objects` RLS-enforced even when supplied runtime metadata omits them: no policies deny access and `service_role` still bypasses. Missing credentials run as `anon`; protected operations return a Storage-shaped 401 for invalid or expired bearer JWTs, while object `GET`, `HEAD`, and info tolerate invalid JWTs so public objects remain retrievable. Unauthenticated private retrieval returns `NoSuchBucket`, matching upstream; a verified `anon` JWT can still reach an `anon` `SELECT` policy. `service_role` bypasses RLS, and custom string roles are preserved for `TO role` policies. Uploads made with a verified JWT carrying a `sub` claim set both `owner_id` and the legacy `owner` field from that claim; `service_role` uploads remain ownerless. Public object retrieval through `GET`, `HEAD`, and info bypasses object `SELECT`; list, signing, copy, and move remain caller-scoped.
674
+
675
+ Bucket CRUD maps to matching policies on `storage.buckets`; PostgreSQL/PGlite bucket deletion runs trusted, row-locking existence and emptiness preflights plus the caller-scoped `DELETE` in one transaction. SQLite/D1 uses trusted preflights followed by one caller-scoped `DELETE`, with the bucket-object foreign key keeping that mutation race-safe. Object upload maps to `INSERT`; private download and info, list, and signing map to `SELECT`; remove maps to `DELETE`; move maps to source `SELECT` plus `UPDATE`; copy maps to source `SELECT` plus destination `INSERT`. Upsert additionally requires `SELECT` and `UPDATE`. Permission probes roll back before adapter writes, so denied mutations cannot change filesystem or S3 data. Public `GET`, `HEAD`, and info bypass `SELECT`, while signed URL redemption uses the authorization decision captured when the URL was created. The canonical `storage.foldername()`, `storage.filename()`, `storage.extension()`, `storage.operation()`, `storage.allow_only_operation()`, and `storage.allow_any_operation()` policy helpers work on every backend; `storage.operation()` preserves the complete upstream route identifier and supports comparison, pattern, membership, and null predicates with SQL null semantics.
662
676
 
663
677
  ### Storage Adapters
664
678
 
@@ -680,9 +694,6 @@ Backend implementation in `app/src/storage/`. HTTP endpoints at `/storage/v1/*`.
680
694
 
681
695
  | Feature | Notes |
682
696
  |--------------------------------|------------------------------------------------------------|
683
- | `/status` health endpoint | Oracle returns 200 with no auth |
684
- | Role-based access control | API keys now resolve `service_role`/`anon`/`authenticated` for storage's route-level auth (see [API Keys](#api-keys)); no per-object RLS policies yet |
685
- | RLS policies on storage tables | Per-user object access via row-level security |
686
697
  | Bucket list query params | `?search=`, `?limit=`, `?offset=` on `GET /bucket` |
687
698
  | S3-compatible protocol | `PUT/GET/DELETE` via S3 API paths (`/s3/`) |
688
699
  | TUS resumable uploads | `POST/PATCH/HEAD` on `/upload/resumable` |
@@ -692,9 +703,9 @@ Backend implementation in `app/src/storage/`. HTTP endpoints at `/storage/v1/*`.
692
703
 
693
704
  | Status | Count |
694
705
  |---------------------|------------------------------|
695
- | ✅ Endpoints | 20 |
706
+ | ✅ Endpoints | 20 supabase-js + health |
696
707
  | ✅ Adapters | 3 storage + 3 transformation |
697
- | 🔄 Missing features | 7 |
708
+ | 🔄 Missing features | 4 |
698
709
 
699
710
  ### Spec Test Results
700
711
 
@@ -702,21 +713,23 @@ Tests run via supabase-spec JSON test cases against Postgres (pgserve). Run: `cd
702
713
 
703
714
  | Category | Pass | Fail | Notes |
704
715
  |------------------|------|------|---------------------------------------------|
705
- | bucket_crud | 36 | 2 | Fails: anon/authenticated access |
706
- | object_upload | 19 | 3 | Fails: anon access, size limit, auth format |
707
- | access_control | -- | 48 | Needs RLS + role-based access |
716
+ | bucket_crud | 38 | 0 | Full current category |
717
+ | object_upload | 20 | 2 | Residual size-limit fixture and auth-envelope shape |
718
+ | access_control | 70 | 7 | Core authorization passes; residual fixture body bytes and a legacy null-owner assertion |
708
719
  | object_read | -- | 28 | Cascade from setup/access issues |
709
720
  | object_list | -- | 26 | Cascade from setup/access issues |
710
721
  | signed_urls | -- | 24 | Cascade from setup/access issues |
711
- | errors | -- | 27 | Auth error format (401 vs 400) |
722
+ | errors | 44 | 10 | Includes unrelated TUS, signed-URL shape, validation, and one legacy missing-auth validation shape; 4 skipped TUS steps |
712
723
  | object_move_copy | -- | 21 | Cascade from setup/access issues |
713
724
  | object_naming | -- | 15 | Cascade from setup/access issues |
714
725
  | user_metadata | -- | 10 | Cascade from setup/access issues |
715
726
  | file_types | -- | 8 | Cascade from setup/access issues |
716
- | health | -- | 3 | Missing `/status` endpoint |
727
+ | health | 6 | 0 | Full current category |
717
728
  | object_delete | -- | 3 | Cascade from setup/access issues |
718
729
 
719
- > Many failures cascade from a few root issues (missing role-based access, auth error format). Fixing role checking, `/status`, and error format would flip a large number of tests.
730
+ > Counts reflect the current vendored phenotype files, whose `access_control` category contains 77 setup/action assertions rather than the older 48-case snapshot. Remaining failures are tracked by their actual response-shape, fixture, or unrelated feature root cause; `storage_auth_policy` is no longer a skip category.
731
+ >
732
+ > `bun run test:spec:storage` completes with zero failures on PostgreSQL, PGlite, SQLite, and SQLite-Postgres. Its default report lists seven vendored expectation conflicts separately: five fixture-body byte mismatches, one legacy missing-auth validation shape, and one legacy null-owner assertion. `SKIP=0` retains the raw phenotype counts above.
720
733
 
721
734
  ---
722
735
 
@@ -761,7 +774,7 @@ Default command output is pipe-friendly: no global banner, and config/database-l
761
774
  | `db query` | ✅ | Renamed from top-level `exec`; supports `--remote`, `--config`, and stdin |
762
775
  | `db schema` | ✅ | `[lite]`: moved from top-level; `--diff` and `--sql` modes |
763
776
  | `db push` | 🔄 | Not registered; use `lite cloud deploy` |
764
- | `db reset` | ✅ | Replays migrations + seed; does not apply declarative schema_paths; clears `supabase/.temp` caches and always rewrites the deparse cache from the replayed migrations — the reset is destructive, so migration state (RLS included) becomes the authoritative state, and declarative schemas are only in the database if you generated a migration from them first (`lite db diff -f <name>`) |
777
+ | `db reset` | ✅ | Replays migrations + seed; does not apply declarative schema_paths; clears `supabase/.temp` caches and always rewrites the runtime metadata cache from the replayed migrations — the reset is destructive, so migration state (RLS included) becomes the authoritative state, and declarative schemas are only in the database if you generated a migration from them first (`lite db diff -f <name>`) |
765
778
  | `db pull`, `db dump`, `db lint`, `db advisors` | 🔄 | Not registered |
766
779
  | `db start` | 🚫 | Not applicable; in-process, no separate DB start |
767
780
 
@@ -770,7 +783,7 @@ Default command output is pipe-friendly: no global banner, and config/database-l
770
783
  | Command | Status | Notes |
771
784
  |---------------------|--------|--------------------------------------------------------|
772
785
  | `migration new` | ✅ | Create an empty migration file in `supabase/migrations/` |
773
- | `migration up` | ✅ | Apply pending migrations; `--dry-run` lists without applying |
786
+ | `migration up` | ✅ | Apply pending migrations; `--dry-run` lists without applying. On `sqlite-postgres`, refreshes complete runtime metadata from recorded history even on a no-op run. |
774
787
  | `migration list` | ✅ | Show applied vs pending migrations |
775
788
  | `migration down`, `migration repair`, `migration squash`, `migration fetch` | 🔄 | Not registered |
776
789
 
@@ -842,8 +855,8 @@ Mirrors upstream behavior documented in [`internal/docs/cli/environment.md`](htt
842
855
  ### Vite plugin scope
843
856
 
844
857
  - **Active during `vite` / `vite dev` and `vite preview`.** `vite dev` watches `schemas/*.sql` for hot-reload; `vite preview` mounts the API and runs boot migrations but does **not** watch schemas (it simulates production). `vite build` and any standalone production server do **not** mount the API — use a real backend (`lite start`, hosted Supabase, or equivalent) there.
845
- - **Same-process by design.** The plugin mounts `/auth/v1`, `/rest/v1`, and `/_system` on the Vite dev server. `/storage/v1` is not mounted by default — add it to `prefixes` if you need it. Do not run `lite dev` or `lite start` alongside both bind the API and will collide on port.
846
- - **Admin mode on in dev, never in preview.** `vite`/`vite dev` default to `admin: true` (keyless same-origin loopback `/rest/v1` requests run as `service_role`); `configurePreviewServer` forces it off. Override with `supalite({ admin: false })`. See [API Keys](#api-keys).
858
+ - **Same-process by design.** The plugin mounts `/auth/v1`, `/rest/v1`, and `/_system` on the Vite dev server. `/storage/v1` is not mounted by default — add it to `prefixes` if you need it. Run only one backend per project: never combine the plugin with `lite dev` or `lite start`, and never run both CLI backends together.
859
+ - **Admin mode on for loopback dev, never in preview.** `vite`/`vite dev` default to `admin: true` only when Vite binds a loopback host. `vite --host` and other non-loopback hosts default it off and require `supalite({ admin: true })` to opt in; `configurePreviewServer` always forces it off. See [API Keys](#api-keys).
847
860
  - **Env-var injection.** The plugin's `config()` hook injects `VITE_SUPABASE_URL` (the current origin) and a dev `VITE_SUPABASE_ANON_KEY`, so `createClient(import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_ANON_KEY)` works with no `.env`. A user-provided `.env` overrides either value.
848
861
 
849
862
  ---
@@ -866,9 +879,9 @@ See [UPGRADE.md](https://github.com/supabase-community/lite/blob/HEAD/UPGRADE.md
866
879
 
867
880
  | Test Suite | Passing | Skipped | Failed | Assertions | Files |
868
881
  |------------|-------------------|-------------|-----------------|-------------------|----------------|
869
- | App | **2,939 passing** | 486 skipped | 0 failed | 19,345 assertions | 204 test files |
882
+ | App | **3,385 passing** | 486 skipped | 0 failed | 20,741 assertions | 228 test files |
870
883
  | App (vitest: node + browser + D1 + DO + KV) | **65 passing** | 0 skipped | 0 failed | — | 5 test files |
871
- | Repo | **3,967 passing** | 540 skipped | 0 failed | 33,127 assertions | 209 test files |
884
+ | Repo | **4,413 passing** | 540 skipped | 0 failed | 34,523 assertions | 233 test files |
872
885
 
873
886
  Latest `cd app && bun test`, `cd app && bun run vitest`, and root `bun test --recursive` completed with zero failures.
874
887