@supabase/lite 0.4.0 → 0.4.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.
package/LIMITATIONS.md CHANGED
@@ -45,5 +45,4 @@ Common ways code goes wrong against supalite. The fix for each is the correspond
45
45
  - Don't use embedded dotted-path filters (`.eq('rel.col', v)`) on SQLite. Filter the FK column on the parent, or fetch matching ids first.
46
46
  - Don't run `lite dev` or `lite start` next to the Vite plugin — port collision.
47
47
  - Don't assume `vite preview` mounts the API. It doesn't. Use `lite start` or a real backend for non-dev environments.
48
- - Don't write `.env` files with `VITE_SUPABASE_URL` for an in-Vite plugin app until [#27](https://github.com/supabase-community/lite/issues/27) ships — use `window.location.origin` + any non-empty anon string.
49
48
  - Don't reach for `trim` / `length` / `lower` inside `CHECK` constraints on SQLite — use literal/operator comparisons.
package/README.md CHANGED
@@ -14,7 +14,7 @@ Supalite targets AI builders who want quick, cheap prototypes today with a clear
14
14
 
15
15
  **Scope:** Both declarative schema (`supabase/schemas/*.sql`) and imperative Postgres migrations (`supabase/migrations/*.sql`, Supabase-CLI compatible) are supported. See [Migrations](#migrations). Advanced Postgres-specific column types (ranges, arrays of composites, and similar) are not available.
16
16
 
17
- Validated against the upstream PostgREST and GoTrue test suites: 1,803 tests passing.
17
+ Validated against the upstream PostgREST and GoTrue spec suites: 1,918 cases passing on SQLite (1,677 Data API + 241 Auth), zero failing. See [Testing](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#testing) for per-backend pass rates.
18
18
 
19
19
  ---
20
20
 
@@ -43,10 +43,12 @@ The skill itself points at the installed docs (not their content), so updates la
43
43
 
44
44
  Compatibility is measured from the `@supabase/supabase-js` surface. The goal is that code written against Supabase keeps working when pointed at @supabase/lite. Direct database access (raw SQL clients, Postgres wire protocol, `psql`) is **not** a target; everything below is scoped to what supabase-js exercises.
45
45
 
46
+ For a per-capability parity view with effort estimates and feasibility notes for unsupported features, see [FEATURES.md](https://github.com/supabase-community/lite/blob/HEAD/FEATURES.md).
47
+
46
48
  | Service | Status | Notes |
47
49
  |-------------------------|--------|--------------------------------------------------------------------|
48
50
  | [Databases](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#database-support) | ✅ | `bun:sqlite`, `node:sqlite`, sqlite-wasm, Cloudflare D1 + DO, PGlite, PostgreSQL |
49
- | [Data API (PostgREST)](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#database-api-postgrest-compatible) | ✅ | 47/74 supabase-js methods on SQLite: `from`, `select`, `insert`, `update`, `delete`, `upsert`, `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn`, `is`, `isDistinct`, `like`, `ilike`, `likeAllOf`, `likeAnyOf`, `ilikeAllOf`, `ilikeAnyOf`, `match`, `or`, `not`, `filter`, `order`, `limit`, `range`, `single`, `maybeSingle`, `csv`, `abortSignal`, `setHeader`, `throwOnError`, `maxAffected`, `returns`, `overrideTypes`, plus full resource embedding (FK joins, `!inner`, spreads, nested, aggregates). Partial: `contains`, `containedBy`, `overlaps`. `rpc` not supported on SQLite. 72/74 on Postgres. |
51
+ | [Data API (PostgREST)](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#database-api-postgrest-compatible) | ✅ | 53/74 supabase-js methods on SQLite: `from`, `select`, `insert`, `update`, `delete`, `upsert`, `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn`, `is`, `isDistinct`, `like`, `ilike`, `likeAllOf`, `likeAnyOf`, `ilikeAllOf`, `ilikeAnyOf`, `match`, `or`, `not`, `filter`, `order`, `limit`, `range`, `single`, `maybeSingle`, `csv`, `abortSignal`, `setHeader`, `throwOnError`, `maxAffected`, `returns`, `overrideTypes`, plus full resource embedding (FK joins, `!inner`, spreads, nested, aggregates). Partial: `contains`, `containedBy`, `overlaps`, `textSearch` (LIKE-based lexeme approximation), `regexMatch`/`regexIMatch` (simple anchored patterns). `rpc` not supported on SQLite. 72/74 on Postgres. |
50
52
  | [Auth API (GoTrue)](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#auth-api-gotrue-compatible) | ✅ | 21/63 supabase-js methods (11 backend + 10 client-side helpers): `signUp`, `signInWithPassword`, `signInWithOtp`, `verifyOtp`, `refreshSession`, `signOut`, `getUser`, `updateUser`, `resetPasswordForEmail`, `resend`, `reauthenticate`. OAuth, anonymous, identity linking, admin API, and MFA planned. |
51
53
  | [Storage API](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#storage-api-compatible) | 🧪 | 20/20 supabase-js methods: `upload`, `download`, `list`, `remove`, `move`, `copy`, `info`, `exists`, `update`, `getPublicUrl`, `createSignedUrl`, `createSignedUrls`, `createSignedUploadUrl`, `uploadToSignedUrl`, `listBuckets`, `getBucket`, `createBucket`, `updateBucket`, `deleteBucket`, `emptyBucket`. Role-based access + RLS pending. <br />⚠️ Gated behind `EXPERIMENTAL_STORAGE`. |
52
54
  | Realtime | 🔄 | Coming soon |
@@ -114,9 +116,15 @@ lite <command> [options]
114
116
  | `dev` | Start server + watch `schemas/*.sql`, auto-apply on change |
115
117
  | `start` | Start server (no watch, no auto-migrate) |
116
118
  | `db schema` | Print current DB schema; `--diff` compares vs `schemas/*.sql` |
117
- | `migration diff` | Generate/apply migrations from schema diff |
118
- | `repl` | Interactive REPL with `app`, `client`, `conn` in scope |
119
+ | `db diff` | Emit a new pg-DDL migration from the declarative schema diff |
119
120
  | `db query` | Run a SQL statement against the local DB |
121
+ | `db reset` | Drop everything, replay migrations, run seed |
122
+ | `migration new` | Create an empty migration file in `supabase/migrations/` |
123
+ | `migration up` | Apply pending migrations (`--dry-run` to preview) |
124
+ | `migration list` | Show applied vs pending migrations |
125
+ | `migration diff` | Diff DB state against `schemas/*.sql` |
126
+ | `repl` | Interactive REPL with `app`, `client`, `conn` in scope |
127
+ | `upgrade` | Migrate the project to hosted or local Supabase (see [UPGRADE.md](https://github.com/supabase-community/lite/blob/HEAD/UPGRADE.md)) |
120
128
  | `debug` | Show runtime/config info |
121
129
 
122
130
  Common flags:
@@ -171,18 +179,21 @@ export default defineConfig({
171
179
  });
172
180
  ```
173
181
 
174
- Then from your frontend. Because the plugin mounts the API on the Vite dev
175
- server itself, the simplest dev setup is to point supabase-js at the current
176
- origin and pass any non-empty string as the anon key:
182
+ Then from your frontend, the canonical snippet works with no setup. The plugin
183
+ injects `VITE_SUPABASE_URL` (the current origin, since the API rides on the Vite
184
+ server) and a dev `VITE_SUPABASE_ANON_KEY`:
177
185
 
178
186
  ```ts
179
187
  import { createClient } from "@supabase/supabase-js";
180
188
 
181
- const client = createClient(window.location.origin, "any-string-works-for-now");
189
+ const client = createClient(
190
+ import.meta.env.VITE_SUPABASE_URL,
191
+ import.meta.env.VITE_SUPABASE_ANON_KEY,
192
+ );
182
193
  ```
183
194
 
184
- The plugin does **not** currently inject `VITE_SUPABASE_URL` or
185
- `VITE_SUPABASE_ANON_KEY` — env injection is tracked in [#27](https://github.com/supabase-community/lite/issues/27). Until that lands, prefer `window.location.origin` over an env-driven URL for the in-Vite path.
195
+ Set either var in a `.env` file to override the injected defaults — your values
196
+ always win.
186
197
 
187
198
  The plugin auto-resolves `./supabase/config.toml`, applies the schema on boot,
188
199
  watches `schemas/*.sql` for hot-reload, and mounts `/auth/v1`, `/rest/v1`, and
package/STATUS.md CHANGED
@@ -335,10 +335,10 @@ All operators are parsed into the AST. The "Status" column reflects whether a wo
335
335
 
336
336
  | Method | SQLite | Postgres | Notes |
337
337
  |------------------------|--------|----------|----------------------------------------------|
338
- | `textSearch()` (fts) | | ✅ | Not implemented on SQLite; FTS5 candidate (backlog) |
339
- | `textSearch()` (plfts) | | ✅ | Not implemented on SQLite |
340
- | `textSearch()` (phfts) | | ✅ | Not implemented on SQLite |
341
- | `textSearch()` (wfts) | | ✅ | Not implemented on SQLite |
338
+ | `textSearch()` (fts) | ⚠️ | ✅ | SQLite: LIKE-based tsvector-lexeme approximation, not FTS5 ranking. Language/dictionary variants and computed-column FTS are limited. |
339
+ | `textSearch()` (plfts) | ⚠️ | ✅ | SQLite: phrase query split into per-lexeme `AND` over the approximation |
340
+ | `textSearch()` (phfts) | ⚠️ | ✅ | SQLite: same lexeme approximation; dictionary/stemming differences not modeled |
341
+ | `textSearch()` (wfts) | ⚠️ | ✅ | SQLite: websearch query parsed to lexemes over the approximation |
342
342
 
343
343
  ### Advanced Filters
344
344
 
@@ -353,8 +353,8 @@ All operators are parsed into the AST. The "Status" column reflects whether a wo
353
353
 
354
354
  | Method | SQLite | Postgres | Notes |
355
355
  |-----------------|--------|----------|--------------------------------------------------|
356
- | `regexMatch()` | | ✅ | Not implemented on SQLite; would require `regexp` extension |
357
- | `regexIMatch()` | | ✅ | Not implemented on SQLite; would require `regexp` extension |
356
+ | `regexMatch()` | ⚠️ | ✅ | SQLite: simple anchored/literal patterns (`^foo`, `bar$`, `^exact$`, substrings) translated to `GLOB`; complex regex (classes, quantifiers, alternation) unsupported |
357
+ | `regexIMatch()` | ⚠️ | ✅ | SQLite: case-insensitive variant of the above via `LIKE`; complex regex unsupported |
358
358
 
359
359
  ### Range Operators
360
360
 
@@ -446,18 +446,18 @@ Supported natively on the Postgres / PGlite path.
446
446
  | Comparison (10) | ✅ 10 ⚠️ 0 ❌ 0 | ✅ 10 ⚠️ 0 ❌ 0 |
447
447
  | Pattern (6) | ✅ 6 ⚠️ 0 ❌ 0 | ✅ 6 ⚠️ 0 ❌ 0 |
448
448
  | Array/JSON (3) | ✅ 0 ⚠️ 3 ❌ 0 | ✅ 3 ⚠️ 0 ❌ 0 |
449
- | Full-Text (4) | ✅ 0 ⚠️ 04 | ✅ 4 ⚠️ 0 ❌ 0 |
449
+ | Full-Text (4) | ✅ 0 ⚠️ 40 | ✅ 4 ⚠️ 0 ❌ 0 |
450
450
  | Advanced (4) | ✅ 4 ⚠️ 0 ❌ 0 | ✅ 4 ⚠️ 0 ❌ 0 |
451
- | Regex (2) | ✅ 0 ⚠️ 02 | ✅ 2 ⚠️ 0 ❌ 0 |
451
+ | Regex (2) | ✅ 0 ⚠️ 20 | ✅ 2 ⚠️ 0 ❌ 0 |
452
452
  | Range (5) | ✅ 0 ⚠️ 0 ❌ 5 | ✅ 5 ⚠️ 0 ❌ 0 |
453
453
  | Quantified (12) | ✅ 0 ⚠️ 0 ❌ 12 | ✅ 12 ⚠️ 0 ❌ 0 |
454
454
  | Transforms (5) | ✅ 5 ⚠️ 0 ❌ 0 | ✅ 5 ⚠️ 0 ❌ 0 |
455
455
  | Embedding (5) | ✅ 5 ⚠️ 0 ❌ 0 | ✅ 5 ⚠️ 0 ❌ 0 |
456
456
  | Response (7) | ✅ 5 ⚠️ 1 ❌ 1 | ✅ 5 ⚠️ 1 ❌ 1 |
457
457
  | Control (5) | ✅ 0 ⚠️ 0 ❌ 3 ⚫ 2 | ✅ 2 ⚠️ 0 ❌ 1 ⚫ 2 |
458
- | **Total (74)** | **✅ 41 ⚠️ 4 27 ⚫ 2** | **✅ 69 ⚠️ 1 ❌ 2 ⚫ 2** |
458
+ | **Total (74)** | **✅ 41 ⚠️ 10 21 ⚫ 2** | **✅ 69 ⚠️ 1 ❌ 2 ⚫ 2** |
459
459
 
460
- > Counting effective availability (✅ + ⚠️ + ⚫): **47/74 on SQLite**, **72/74 on Postgres** (`geojson()` and `rollback()` are the only gaps on Postgres). The 2 ⚫ methods (`returns`, `overrideTypes`) are TypeScript-only and need no backend.
460
+ > Counting effective availability (✅ + ⚠️ + ⚫): **53/74 on SQLite**, **72/74 on Postgres** (`geojson()` and `rollback()` are the only gaps on Postgres). The 2 ⚫ methods (`returns`, `overrideTypes`) are TypeScript-only and need no backend.
461
461
 
462
462
  ### PostgREST spec: SQLite skip breakdown
463
463
 
@@ -734,7 +734,10 @@ Help groups match upstream: **Local Development** (commands you run from a proje
734
734
  | Command | Status | Notes |
735
735
  |---------------------|--------|--------------------------------------------------------|
736
736
  | `migration diff` | ✅ | `[lite]`: diff DB state against `schemas/*.sql` |
737
- | `migration new`, `migration list`, `migration up`, `migration down`, `migration repair`, `migration squash`, `migration fetch` | 🔄 | Not registered |
737
+ | `migration new` | ✅ | Create an empty migration file in `supabase/migrations/` |
738
+ | `migration up` | ✅ | Apply pending migrations; `--dry-run` lists without applying |
739
+ | `migration list` | ✅ | Show applied vs pending migrations |
740
+ | `migration down`, `migration repair`, `migration squash`, `migration fetch` | 🔄 | Not registered |
738
741
 
739
742
  ### `cloud` group `[lite]` `[experimental]`
740
743
 
@@ -783,8 +786,8 @@ Mirrors upstream behavior documented in [`internal/docs/cli/environment.md`](htt
783
786
 
784
787
  | Status | Count |
785
788
  |-----------------------------|-------|
786
- | ✅ Implemented | 22 |
787
- | 🔄 Planned (not registered) | 17 |
789
+ | ✅ Implemented | 25 |
790
+ | 🔄 Planned (not registered) | 14 |
788
791
  | 🚫 Not Applicable | 7 |
789
792
 
790
793
  > Counts include only commands tracked in this file (excludes management-API groups represented as a single row each).
@@ -803,9 +806,9 @@ Mirrors upstream behavior documented in [`internal/docs/cli/environment.md`](htt
803
806
 
804
807
  ### Vite plugin scope
805
808
 
806
- - **Active only during `vite` / `vite dev`.** `vite preview`, `vite build`, and any production server do **not** mount the API. Use a real backend (`lite start`, hosted Supabase, or equivalent) for non-dev environments.
809
+ - **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.
807
810
  - **Same-process by design.** The plugin mounts `/auth/v1`, `/rest/v1`, and `/_system` on the Vite dev server. Do not run `lite dev` or `lite start` alongside — both bind the API and will collide on port.
808
- - **No env-var injection (yet).** The plugin does not currently set `VITE_SUPABASE_URL` / `VITE_SUPABASE_ANON_KEY`. Tracked in [#27](https://github.com/supabase-community/lite/issues/27). For now pass `window.location.origin` + any non-empty anon string to `createClient`.
811
+ - **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.
809
812
 
810
813
  ---
811
814
 
@@ -827,9 +830,9 @@ See [UPGRADE.md](https://github.com/supabase-community/lite/blob/HEAD/UPGRADE.md
827
830
 
828
831
  | Test Suite | Passing | Skipped | Failed | Assertions | Files |
829
832
  |------------|-------------------|-------------|-----------------|-------------------|----------------|
830
- | App | **2,221 passing** | 486 skipped | 0 failed | 17,186 assertions | 150 test files |
831
- | App (vitest: node + D1 + DO + KV) | **34 passing** | 0 skipped | 0 failed | 80 assertions | 4 test files |
832
- | Repo | **3,248 passing** | 540 skipped | 0 failed | 30,961 assertions | 155 test files |
833
+ | App | **2,376 passing** | 486 skipped | 0 failed | 17,538 assertions | 168 test files |
834
+ | App (vitest: node + browser + D1 + DO + KV) | **47 passing** | 0 skipped | 0 failed | | 5 test files |
835
+ | Repo | **3,404 passing** | 540 skipped | 0 failed | 31,320 assertions | 173 test files |
833
836
 
834
837
  Latest `cd app && bun test`, `cd app && bun run vitest`, and root `bun test --recursive` completed with zero failures.
835
838
 
package/UPGRADE.md CHANGED
@@ -54,13 +54,19 @@ Only `--mode user` is currently supported. `--mode platform` is reserved for fut
54
54
 
55
55
  ### Local Supabase
56
56
 
57
- `--target local` upgrades into a local Supabase CLI workdir. By default, the workdir is the current directory, so the command initializes or updates `./supabase/config.toml` in the project being upgraded:
57
+ `--target local` upgrades into a local Supabase CLI workdir. By default, the workdir is the current directory, so the command rewrites `./supabase/config.toml` in place: it strips the Supalite-only `[db].driver`/`[db].url` keys and repoints the file at the Supabase CLI stack. This breaks `bun run dev` (the Supalite Vite plugin) until the config is restored.
58
+
59
+ To prevent data loss, the original Supalite config is first backed up to `./supabase/config.toml.bak`, and the upgrade report prints how to restore it. Restore supalite dev with:
60
+
61
+ ```bash
62
+ cp supabase/config.toml.bak supabase/config.toml # or: git checkout supabase/config.toml
63
+ ```
58
64
 
59
65
  ```bash
60
66
  lite upgrade --target local --force --no-migrate-sessions
61
67
  ```
62
68
 
63
- Use `--local-dir` to put the Supabase CLI workdir somewhere else:
69
+ Use `--local-dir` to put the Supabase CLI workdir somewhere else and avoid touching the project's `supabase/config.toml` entirely:
64
70
 
65
71
  ```bash
66
72
  lite upgrade \
@@ -98,6 +104,8 @@ rm -rf supabase/.branches supabase/.temp
98
104
  lite upgrade --target local --force --no-migrate-sessions
99
105
  ```
100
106
 
107
+ The `supabase/config.toml.bak` created on the first in-place run is preserved across reruns (it is never overwritten by the already-sanitized config), so the original Supalite config stays recoverable.
108
+
101
109
  If the local target uses a separate directory, clean that directory instead:
102
110
 
103
111
  ```bash