supabee 0.3.2 → 0.3.4
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 +420 -328
- package/dist/commands/cutoff.d.ts +5 -0
- package/dist/commands/cutoff.js +49 -0
- package/dist/commands/cutoff.js.map +1 -0
- package/dist/commands/db-reset.d.ts +2 -0
- package/dist/commands/db-reset.js +119 -182
- package/dist/commands/db-reset.js.map +1 -1
- package/dist/commands/init.js +9 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migration.d.ts +18 -0
- package/dist/commands/migration.js +290 -0
- package/dist/commands/migration.js.map +1 -0
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.js +50 -2
- package/dist/commands/sync.js.map +1 -1
- package/dist/index.js +129 -88
- package/dist/index.js.map +1 -1
- package/dist/lib/constants.d.ts +3 -0
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/migration-classifier.d.ts +39 -0
- package/dist/lib/migration-classifier.js +321 -0
- package/dist/lib/migration-classifier.js.map +1 -0
- package/dist/lib/post-seed-cutoff.d.ts +24 -0
- package/dist/lib/post-seed-cutoff.js +195 -0
- package/dist/lib/post-seed-cutoff.js.map +1 -0
- package/dist/lib/subprocess.js +7 -7
- package/package.json +54 -53
- package/supabee.config.example.json +34 -29
package/README.md
CHANGED
|
@@ -1,413 +1,505 @@
|
|
|
1
|
-
# Supabee
|
|
2
|
-
|
|
3
|
-
[](https://github.com/kaihochak/supabee/actions/workflows/ci.yml)
|
|
4
|
-
[](https://www.npmjs.com/package/supabee)
|
|
5
|
-
[](./LICENSE)
|
|
6
|
-
|
|
7
|
-
Orchestrate local Supabase schema/data workflows: split giant SQL dumps into organized files, and apply post-seed migrations in a production-like order.
|
|
8
|
-
|
|
9
|
-
## Why?
|
|
10
|
-
|
|
11
|
-
Supabase workflows often end up with two pain points:
|
|
12
|
-
|
|
13
|
-
1. **One huge dump file** (`supabase db dump` / `--data-only`) that's painful to review, edit, or selectively seed from.
|
|
14
|
-
2. **Local reset/start ordering** (migrations → seeds) that can diverge from production deploys (new migrations applied onto an already-populated database).
|
|
15
|
-
|
|
16
|
-
`supabee` addresses both:
|
|
17
|
-
|
|
18
|
-
- **Split + validate dumps:** split schema and data dumps into focused files (by category / by table), then reconstruct and validate round-trip (PR-friendly diffs, easier navigation, and smaller merge conflicts).
|
|
19
|
-
- **Defer post-seed migrations:** temporarily move newer migrations out of the way for `supabase db reset` / `supabase start`, then restore + reapply them after seeds load.
|
|
20
|
-
|
|
21
|
-
### Use cases
|
|
22
|
-
|
|
23
|
-
- **Seed data you can control:** keep per-table seed files and point `[db.seed].sql_paths` at only the ones you want.
|
|
24
|
-
- **Schema as docs / source of truth:** keep schema readable in-repo (tables, functions, RLS, permissions, etc.).
|
|
25
|
-
- **Mimic production locally:** catch “works on reset” vs “works on deploy” issues by applying post-seed migrations after data exists.
|
|
26
|
-
- **One-liners with validation:** `sync schema` / `sync data` run dump → split → reconstruct → validate.
|
|
27
|
-
|
|
28
|
-
### Repo hygiene (recommended)
|
|
29
|
-
|
|
30
|
-
Commit split outputs (for example `supabase/schemas/split/**` and `supabase/seeds/split/**`), and ignore large generated artifacts in your repo:
|
|
31
|
-
|
|
32
|
-
```gitignore
|
|
33
|
-
# raw dumps (generated from prod; optional to keep locally)
|
|
34
|
-
supabase/schemas/prod-schemas.sql
|
|
35
|
-
supabase/seeds/prod-data.sql
|
|
36
|
-
|
|
37
|
-
# reconstructed outputs (validation artifacts)
|
|
38
|
-
supabase/schemas/reconstructed-schemas.sql
|
|
39
|
-
supabase/seeds/reconstructed-data.sql
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Prerequisites
|
|
43
|
-
|
|
44
|
-
- [Node.js](https://nodejs.org/) >= 18
|
|
45
|
-
- [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) installed and authenticated
|
|
46
|
-
|
|
47
|
-
## Install
|
|
48
|
-
|
|
49
|
-
Global install (recommended):
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
npm i -g supabee
|
|
53
|
-
pnpm add -g supabee
|
|
54
|
-
bun add -g supabee
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
One-off run without global install:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
npx supabee --help
|
|
61
|
-
pnpm dlx supabee --help
|
|
62
|
-
bunx supabee --help
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Project-local install (optional):
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
npm install --save-dev supabee
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Setup
|
|
72
|
-
|
|
73
|
-
### 1. Initialize config
|
|
74
|
-
|
|
75
|
-
Run `init` to generate `supabee.config.json` (if it doesn't exist) and update `supabase/config.toml` seed paths:
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
supabee init
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Review the generated `supabee.config.json` and adjust paths/limits for your project.
|
|
82
|
-
|
|
83
|
-
### 2. Link your Supabase project
|
|
84
|
-
|
|
85
|
-
If you haven't already, link your local repo to your Supabase project. This is required before you can dump schema or data:
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
supabase link
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
You'll be prompted for your project ref and database password. See the [Supabase CLI docs](https://supabase.com/docs/reference/cli/supabase-link) for details.
|
|
92
|
-
|
|
93
|
-
### 3. Run the primary workflows
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
supabee sync schema
|
|
97
|
-
supabee sync data
|
|
98
|
-
supabee db reset [cutoff_timestamp]
|
|
99
|
-
supabee start [cutoff_timestamp]
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
`sync` commands run end-to-end:
|
|
103
|
-
|
|
104
|
-
- schema: `supabase db dump` -> split -> reconstruct -> validate
|
|
105
|
-
- data: `supabase db dump --data-only` -> split -> reconstruct -> validate
|
|
106
|
-
|
|
107
|
-
### Selective seeding example (optional)
|
|
108
|
-
|
|
109
|
-
By default, `supabee init` configures `supabase/config.toml` to load all split seed files (for example `./seeds/split/*.sql`).
|
|
110
|
-
To seed only a subset, replace `[db.seed].sql_paths` with an explicit ordered list (keep `001_setup.sql` and `999_cleanup.sql`; add the generated `*_sequences.sql` file if you need sequence values):
|
|
111
|
-
|
|
112
|
-
```toml
|
|
113
|
-
[db.seed]
|
|
114
|
-
sql_paths = [
|
|
115
|
-
"./seeds/split/001_setup.sql",
|
|
116
|
-
"./seeds/split/002_public_users.sql",
|
|
117
|
-
"./seeds/split/003_public_projects.sql",
|
|
118
|
-
"./seeds/split/999_cleanup.sql",
|
|
119
|
-
]
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Commands
|
|
123
|
-
|
|
124
|
-
### `init`
|
|
125
|
-
|
|
126
|
-
Creates `supabee.config.json` if missing, then updates `supabase/config.toml` `[db.seed].sql_paths` so Supabase knows where to find your split seed files.
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
supabee init
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### `schema`
|
|
133
|
-
|
|
134
|
-
Processes an existing schema dump into categorized folders:
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
supabase/schemas/split/
|
|
138
|
-
├── 00_extensions/
|
|
139
|
-
├── 01_setup/
|
|
140
|
-
├── 02_types/
|
|
141
|
-
├── 03_functions/
|
|
142
|
-
├── 04_tables/
|
|
143
|
-
├── 05_views/
|
|
144
|
-
├── 06_constraints/
|
|
145
|
-
├── 07_indexes/
|
|
146
|
-
├── 08_foreign_keys/
|
|
147
|
-
├── 09_rls/
|
|
148
|
-
├── 10_permissions/
|
|
149
|
-
├── 11_ownership/
|
|
150
|
-
└── 12_others/
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
# Full chain (split → reconstruct → validate)
|
|
155
|
-
supabee schema
|
|
156
|
-
|
|
157
|
-
# Individual steps
|
|
158
|
-
supabee schema split
|
|
159
|
-
supabee schema reconstruct
|
|
160
|
-
supabee schema validate
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### `data`
|
|
164
|
-
|
|
165
|
-
Processes an existing data dump into per-table files with configurable row/statement limits:
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
# Full chain (split → reconstruct → validate)
|
|
169
|
-
supabee data
|
|
170
|
-
|
|
171
|
-
# Individual steps
|
|
172
|
-
supabee data split
|
|
173
|
-
supabee data reconstruct
|
|
174
|
-
supabee data validate
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### `sync schema`
|
|
178
|
-
|
|
179
|
-
Dumps schema from the linked Supabase project, then runs full schema processing:
|
|
180
|
-
|
|
1
|
+
# Supabee
|
|
2
|
+
|
|
3
|
+
[](https://github.com/kaihochak/supabee/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/supabee)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
7
|
+
Orchestrate local Supabase schema/data workflows: split giant SQL dumps into organized files, and apply post-seed migrations in a production-like order.
|
|
8
|
+
|
|
9
|
+
## Why?
|
|
10
|
+
|
|
11
|
+
Supabase workflows often end up with two pain points:
|
|
12
|
+
|
|
13
|
+
1. **One huge dump file** (`supabase db dump` / `--data-only`) that's painful to review, edit, or selectively seed from.
|
|
14
|
+
2. **Local reset/start ordering** (migrations → seeds) that can diverge from production deploys (new migrations applied onto an already-populated database).
|
|
15
|
+
|
|
16
|
+
`supabee` addresses both:
|
|
17
|
+
|
|
18
|
+
- **Split + validate dumps:** split schema and data dumps into focused files (by category / by table), then reconstruct and validate round-trip (PR-friendly diffs, easier navigation, and smaller merge conflicts).
|
|
19
|
+
- **Defer post-seed migrations:** temporarily move newer migrations out of the way for `supabase db reset` / `supabase start`, then restore + reapply them after seeds load.
|
|
20
|
+
|
|
21
|
+
### Use cases
|
|
22
|
+
|
|
23
|
+
- **Seed data you can control:** keep per-table seed files and point `[db.seed].sql_paths` at only the ones you want.
|
|
24
|
+
- **Schema as docs / source of truth:** keep schema readable in-repo (tables, functions, RLS, permissions, etc.).
|
|
25
|
+
- **Mimic production locally:** catch “works on reset” vs “works on deploy” issues by applying post-seed migrations after data exists.
|
|
26
|
+
- **One-liners with validation:** `sync schema` / `sync data` run dump → split → reconstruct → validate.
|
|
27
|
+
|
|
28
|
+
### Repo hygiene (recommended)
|
|
29
|
+
|
|
30
|
+
Commit split outputs (for example `supabase/schemas/split/**` and `supabase/seeds/split/**`), and ignore large generated artifacts in your repo:
|
|
31
|
+
|
|
32
|
+
```gitignore
|
|
33
|
+
# raw dumps (generated from prod; optional to keep locally)
|
|
34
|
+
supabase/schemas/prod-schemas.sql
|
|
35
|
+
supabase/seeds/prod-data.sql
|
|
36
|
+
|
|
37
|
+
# reconstructed outputs (validation artifacts)
|
|
38
|
+
supabase/schemas/reconstructed-schemas.sql
|
|
39
|
+
supabase/seeds/reconstructed-data.sql
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Prerequisites
|
|
43
|
+
|
|
44
|
+
- [Node.js](https://nodejs.org/) >= 18
|
|
45
|
+
- [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) installed and authenticated
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
Global install (recommended):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm i -g supabee
|
|
53
|
+
pnpm add -g supabee
|
|
54
|
+
bun add -g supabee
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
One-off run without global install:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx supabee --help
|
|
61
|
+
pnpm dlx supabee --help
|
|
62
|
+
bunx supabee --help
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Project-local install (optional):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm install --save-dev supabee
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Setup
|
|
72
|
+
|
|
73
|
+
### 1. Initialize config
|
|
74
|
+
|
|
75
|
+
Run `init` to generate `supabee.config.json` (if it doesn't exist) and update `supabase/config.toml` seed paths:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
supabee init
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Review the generated `supabee.config.json` and adjust paths/limits for your project.
|
|
82
|
+
|
|
83
|
+
### 2. Link your Supabase project
|
|
84
|
+
|
|
85
|
+
If you haven't already, link your local repo to your Supabase project. This is required before you can dump schema or data:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
supabase link
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
You'll be prompted for your project ref and database password. See the [Supabase CLI docs](https://supabase.com/docs/reference/cli/supabase-link) for details.
|
|
92
|
+
|
|
93
|
+
### 3. Run the primary workflows
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
supabee sync schema
|
|
97
|
+
supabee sync data
|
|
98
|
+
supabee db reset [cutoff_timestamp]
|
|
99
|
+
supabee start [cutoff_timestamp]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`sync` commands run end-to-end:
|
|
103
|
+
|
|
104
|
+
- schema: `supabase db dump` -> split -> reconstruct -> validate
|
|
105
|
+
- data: `supabase db dump --data-only` -> split -> reconstruct -> validate
|
|
106
|
+
|
|
107
|
+
### Selective seeding example (optional)
|
|
108
|
+
|
|
109
|
+
By default, `supabee init` configures `supabase/config.toml` to load all split seed files (for example `./seeds/split/*.sql`).
|
|
110
|
+
To seed only a subset, replace `[db.seed].sql_paths` with an explicit ordered list (keep `001_setup.sql` and `999_cleanup.sql`; add the generated `*_sequences.sql` file if you need sequence values):
|
|
111
|
+
|
|
112
|
+
```toml
|
|
113
|
+
[db.seed]
|
|
114
|
+
sql_paths = [
|
|
115
|
+
"./seeds/split/001_setup.sql",
|
|
116
|
+
"./seeds/split/002_public_users.sql",
|
|
117
|
+
"./seeds/split/003_public_projects.sql",
|
|
118
|
+
"./seeds/split/999_cleanup.sql",
|
|
119
|
+
]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Commands
|
|
123
|
+
|
|
124
|
+
### `init`
|
|
125
|
+
|
|
126
|
+
Creates `supabee.config.json` if missing, then updates `supabase/config.toml` `[db.seed].sql_paths` so Supabase knows where to find your split seed files.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
supabee init
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `schema`
|
|
133
|
+
|
|
134
|
+
Processes an existing schema dump into categorized folders:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
supabase/schemas/split/
|
|
138
|
+
├── 00_extensions/
|
|
139
|
+
├── 01_setup/
|
|
140
|
+
├── 02_types/
|
|
141
|
+
├── 03_functions/
|
|
142
|
+
├── 04_tables/
|
|
143
|
+
├── 05_views/
|
|
144
|
+
├── 06_constraints/
|
|
145
|
+
├── 07_indexes/
|
|
146
|
+
├── 08_foreign_keys/
|
|
147
|
+
├── 09_rls/
|
|
148
|
+
├── 10_permissions/
|
|
149
|
+
├── 11_ownership/
|
|
150
|
+
└── 12_others/
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Full chain (split → reconstruct → validate)
|
|
155
|
+
supabee schema
|
|
156
|
+
|
|
157
|
+
# Individual steps
|
|
158
|
+
supabee schema split
|
|
159
|
+
supabee schema reconstruct
|
|
160
|
+
supabee schema validate
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### `data`
|
|
164
|
+
|
|
165
|
+
Processes an existing data dump into per-table files with configurable row/statement limits:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Full chain (split → reconstruct → validate)
|
|
169
|
+
supabee data
|
|
170
|
+
|
|
171
|
+
# Individual steps
|
|
172
|
+
supabee data split
|
|
173
|
+
supabee data reconstruct
|
|
174
|
+
supabee data validate
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### `sync schema`
|
|
178
|
+
|
|
179
|
+
Dumps schema from the linked Supabase project, then runs full schema processing:
|
|
180
|
+
|
|
181
181
|
```bash
|
|
182
182
|
supabee sync schema
|
|
183
183
|
supabee sync schema --input supabase/schemas/prod-schemas.sql --output supabase/schemas/split
|
|
184
184
|
supabee sync schema --backup
|
|
185
|
+
supabee sync schema --force
|
|
185
186
|
```
|
|
186
|
-
|
|
187
|
-
### `sync data`
|
|
188
|
-
|
|
189
|
-
Dumps data (`--data-only`) from the linked Supabase project, then runs full data processing:
|
|
190
|
-
|
|
187
|
+
|
|
188
|
+
### `sync data`
|
|
189
|
+
|
|
190
|
+
Dumps data (`--data-only`) from the linked Supabase project, then runs full data processing:
|
|
191
|
+
|
|
191
192
|
```bash
|
|
192
193
|
supabee sync data
|
|
193
194
|
supabee sync data --input supabase/seeds/prod-data.sql --output supabase/seeds/split
|
|
194
195
|
supabee sync data --backup
|
|
195
196
|
supabee sync data --no-backup
|
|
197
|
+
supabee sync data --force
|
|
196
198
|
```
|
|
197
|
-
|
|
199
|
+
|
|
198
200
|
### `db reset`
|
|
199
201
|
|
|
200
202
|
Defers post-seed migrations newer than the cutoff timestamp, runs `supabase db reset`, restores deferred migrations, then reapplies them.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
For historical data migrations at or before cutoff, `supabee` executes a temporary no-op stub during reset, then restores original SQL.
|
|
204
|
+
Classification is automatic by SQL patterns (`INSERT/UPDATE/DELETE/...` vs `CREATE/ALTER/DROP ...`), and optional markers can override classification.
|
|
205
|
+
Mixed schema+DML migrations are blocked when they are after cutoff and must be split.
|
|
206
|
+
Mixed migrations at/before cutoff run in compatibility mode by default (warning only). Use `--strict-mixed` to fail on any mixed migration.
|
|
207
|
+
|
|
208
|
+
If `[cutoff_timestamp]` is omitted, `supabee` auto-detects it from `supabase migration list --linked` by taking the latest migration version that exists in both local and remote (works even when remote has gaps).
|
|
209
|
+
When linked lookup succeeds, `supabee` stores the value in `supabee.config.json` as `postSeedCutoff` (or `postSeedCutoffByEnv.<env>` when `--env` is set).
|
|
210
|
+
If linked lookup fails (for example in CI), it falls back to `postSeedCutoffByEnv.<env>` when `--env` is set, otherwise `postSeedCutoff`.
|
|
205
211
|
If not linked, `supabee` runs `supabase link` and retries once.
|
|
206
|
-
|
|
207
|
-
```bash
|
|
212
|
+
|
|
213
|
+
```bash
|
|
208
214
|
# default re-apply mode: supabase migration up
|
|
209
215
|
supabee db reset 20260309180959
|
|
210
216
|
supabee db reset
|
|
217
|
+
supabee db reset --env staging
|
|
211
218
|
|
|
212
219
|
# optional re-apply mode: psql
|
|
213
220
|
supabee db reset 20260309180959 --psql
|
|
214
|
-
```
|
|
215
221
|
|
|
222
|
+
# strict mixed policy
|
|
223
|
+
supabee db reset --strict-mixed
|
|
224
|
+
```
|
|
225
|
+
|
|
216
226
|
### `start`
|
|
217
227
|
|
|
218
228
|
Defers post-seed migrations newer than the cutoff timestamp, runs `supabase start`, restores deferred migrations, then reapplies them.
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
229
|
+
For historical data-migration files, `supabee` temporarily swaps the file body to a no-op during the run, then restores the original SQL file content.
|
|
230
|
+
|
|
231
|
+
If `[cutoff_timestamp]` is omitted, `supabee` auto-detects it from `supabase migration list --linked` the same way as `db reset`.
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# explicit cutoff
|
|
235
|
+
supabee start 20260309180959
|
|
236
|
+
|
|
226
237
|
# auto cutoff from linked migration alignment
|
|
227
238
|
supabee start
|
|
228
239
|
|
|
229
240
|
# optional re-apply mode: psql
|
|
230
241
|
supabee start --psql
|
|
242
|
+
supabee start --env production
|
|
243
|
+
|
|
244
|
+
# strict mixed policy
|
|
245
|
+
supabee start --strict-mixed
|
|
231
246
|
```
|
|
232
247
|
|
|
233
|
-
###
|
|
248
|
+
### `cutoff detect`
|
|
234
249
|
|
|
235
|
-
|
|
250
|
+
Resolves cutoff from argument, linked migration alignment, or config fallback.
|
|
236
251
|
|
|
237
252
|
```bash
|
|
238
|
-
supabee
|
|
239
|
-
supabee
|
|
253
|
+
supabee cutoff detect
|
|
254
|
+
supabee cutoff detect --env staging
|
|
255
|
+
supabee cutoff detect 20260309180959 --json
|
|
240
256
|
```
|
|
241
257
|
|
|
242
|
-
###
|
|
258
|
+
### `migration audit`
|
|
243
259
|
|
|
244
|
-
`schema`, `
|
|
260
|
+
Classifies migration files as `data`, `schema`, `mixed`, or `unknown`, and shows recommended marker actions.
|
|
245
261
|
|
|
246
262
|
```bash
|
|
247
|
-
supabee
|
|
248
|
-
supabee
|
|
249
|
-
supabee
|
|
250
|
-
supabee
|
|
263
|
+
supabee migration audit
|
|
264
|
+
supabee migration audit --migrations-dir supabase/migrations
|
|
265
|
+
supabee migration audit --verbose
|
|
266
|
+
supabee migration audit --json
|
|
267
|
+
supabee migration audit --json --verbose
|
|
251
268
|
```
|
|
252
269
|
|
|
253
|
-
|
|
254
|
-
|
|
270
|
+
### `migration mark`
|
|
271
|
+
|
|
272
|
+
Adds suggested marker comments by default with interactive confirmation prompts.
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# default: interactive apply
|
|
276
|
+
supabee migration mark
|
|
277
|
+
|
|
278
|
+
# preview only (no writes)
|
|
279
|
+
supabee migration mark --dry-run
|
|
255
280
|
|
|
256
|
-
|
|
281
|
+
# non-interactive apply (CI/scripts)
|
|
282
|
+
supabee migration mark --yes
|
|
283
|
+
```
|
|
257
284
|
|
|
258
|
-
`
|
|
285
|
+
### `migration unmark`
|
|
259
286
|
|
|
260
|
-
|
|
287
|
+
Removes marker comments with the same interaction model as `mark`.
|
|
261
288
|
|
|
262
|
-
|
|
289
|
+
```bash
|
|
290
|
+
# default: interactive remove
|
|
291
|
+
supabee migration unmark
|
|
263
292
|
|
|
264
|
-
|
|
293
|
+
# preview only (no writes)
|
|
294
|
+
supabee migration unmark --dry-run
|
|
265
295
|
|
|
266
|
-
|
|
296
|
+
# non-interactive remove
|
|
297
|
+
supabee migration unmark --yes
|
|
298
|
+
```
|
|
267
299
|
|
|
300
|
+
### Supabase passthrough
|
|
301
|
+
|
|
302
|
+
Unknown commands are forwarded to Supabase CLI:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
supabee migration up # forwards to: supabase migration up
|
|
306
|
+
supabee db dump # forwards to: supabase db dump
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Overriding paths
|
|
310
|
+
|
|
311
|
+
`schema`, `data`, and `sync` commands accept `--input` and `--output` flags:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
supabee schema split --input path/to/schema.sql --output path/to/split
|
|
315
|
+
supabee schema split --input path/to/schema.sql --output path/to/split --backup
|
|
316
|
+
supabee data split --input path/to/data.sql --output path/to/split
|
|
317
|
+
supabee data split --input path/to/data.sql --output path/to/split --no-backup
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
By default, split operations replace existing output in-place (while preserving configured `keepFiles`) without creating a backup folder.
|
|
321
|
+
Use `--backup` to keep a timestamped backup before replacement.
|
|
322
|
+
|
|
323
|
+
## Configuration
|
|
324
|
+
|
|
325
|
+
`supabee` reads `supabee.config.json` from your project root.
|
|
326
|
+
|
|
327
|
+
**Precedence:** CLI flags > config file > built-in defaults.
|
|
328
|
+
|
|
329
|
+
If the config file is missing, built-in defaults are used. Run `supabee init` to generate one.
|
|
330
|
+
|
|
331
|
+
Legacy support: `supabase-splitter.config.json` is still recognized, but `supabee.config.json` is preferred.
|
|
332
|
+
|
|
333
|
+
### Full config reference
|
|
334
|
+
|
|
268
335
|
```json
|
|
269
336
|
{
|
|
270
337
|
"postSeedCutoff": "",
|
|
271
|
-
"
|
|
272
|
-
"
|
|
273
|
-
"
|
|
274
|
-
"reconstructed": "supabase/schemas/reconstructed-schemas.sql",
|
|
275
|
-
"backup": false,
|
|
276
|
-
"keepFiles": []
|
|
338
|
+
"postSeedCutoffByEnv": {
|
|
339
|
+
"staging": "",
|
|
340
|
+
"production": ""
|
|
277
341
|
},
|
|
278
|
-
"
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
"
|
|
282
|
-
"
|
|
283
|
-
"
|
|
284
|
-
"
|
|
285
|
-
"
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
"
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
"
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
|
306
|
-
|
|
307
|
-
| `
|
|
308
|
-
| `
|
|
309
|
-
| `
|
|
310
|
-
| `
|
|
342
|
+
"dataMigrationMarker": "supabee:data-migration",
|
|
343
|
+
"schemaMigrationMarker": "supabee:schema-migration",
|
|
344
|
+
"schema": {
|
|
345
|
+
"input": "supabase/schemas/prod-schemas.sql",
|
|
346
|
+
"output": "supabase/schemas/split",
|
|
347
|
+
"reconstructed": "supabase/schemas/reconstructed-schemas.sql",
|
|
348
|
+
"backup": false,
|
|
349
|
+
"keepFiles": []
|
|
350
|
+
},
|
|
351
|
+
"data": {
|
|
352
|
+
"input": "supabase/seeds/prod-data.sql",
|
|
353
|
+
"output": "supabase/seeds/split",
|
|
354
|
+
"reconstructed": "supabase/seeds/reconstructed-data.sql",
|
|
355
|
+
"backup": false,
|
|
356
|
+
"maxLinesPerFile": 2000,
|
|
357
|
+
"maxStatementsPerFile": 20,
|
|
358
|
+
"maxRowsPerInsert": 200,
|
|
359
|
+
"tableRules": {},
|
|
360
|
+
"keepFiles": [],
|
|
361
|
+
"ignoreInReconstruct": []
|
|
362
|
+
},
|
|
363
|
+
"init": {
|
|
364
|
+
"seedSqlPaths": ["./seeds/split/*.sql"]
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
| Key | Description |
|
|
370
|
+
|-----|-------------|
|
|
371
|
+
| `schema.input` | Path to your schema dump file |
|
|
372
|
+
| `schema.output` | Directory for split schema files |
|
|
373
|
+
| `schema.reconstructed` | Path for the reconstructed schema (used in validation) |
|
|
374
|
+
| `schema.backup` | Whether split should create backup folder before replacing output (default: `false`) |
|
|
375
|
+
| `schema.keepFiles` | Files in the split dir to preserve across re-splits |
|
|
376
|
+
| `data.input` | Path to your data dump file |
|
|
377
|
+
| `data.output` | Directory for split data files |
|
|
378
|
+
| `data.reconstructed` | Path for the reconstructed data (used in validation) |
|
|
379
|
+
| `data.backup` | Whether split should create backup folder before replacing output (default: `false`) |
|
|
380
|
+
| `data.maxLinesPerFile` | Max lines per split file (default: 2000) |
|
|
381
|
+
| `data.maxStatementsPerFile` | Max INSERT statements per file (default: 20) |
|
|
382
|
+
| `data.maxRowsPerInsert` | Max rows per INSERT statement (default: 200) |
|
|
383
|
+
| `data.tableRules` | Per-table overrides (see below) |
|
|
311
384
|
| `data.keepFiles` | Files in the split dir to preserve across re-splits |
|
|
312
385
|
| `data.ignoreInReconstruct` | Files to skip during reconstruction |
|
|
313
386
|
| `init.seedSqlPaths` | Paths written to `supabase/config.toml` `[db.seed].sql_paths` |
|
|
314
387
|
| `postSeedCutoff` | Fallback cutoff timestamp used by `db reset`/`start` when linked lookup is unavailable (for example in CI) |
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
"
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
388
|
+
| `postSeedCutoffByEnv` | Optional per-environment fallback cutoff map (for example `staging`, `production`) |
|
|
389
|
+
| `dataMigrationMarker` | Optional override marker for data migrations (default: `supabee:data-migration`) |
|
|
390
|
+
| `schemaMigrationMarker` | Optional override marker for schema migrations (default: `supabee:schema-migration`) |
|
|
391
|
+
|
|
392
|
+
### Table-specific rules
|
|
393
|
+
|
|
394
|
+
Override limits or skip specific tables:
|
|
395
|
+
|
|
396
|
+
```json
|
|
397
|
+
{
|
|
398
|
+
"data": {
|
|
399
|
+
"tableRules": {
|
|
400
|
+
"public.cities": {
|
|
401
|
+
"maxLinesPerFile": 800,
|
|
402
|
+
"maxStatementsPerFile": 8,
|
|
403
|
+
"maxRowsPerInsert": 80
|
|
404
|
+
},
|
|
405
|
+
"public.audit_logs": {
|
|
406
|
+
"skip": true
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## Flags
|
|
414
|
+
|
|
339
415
|
`schema`, `data`, `sync schema`, and `sync data` support:
|
|
340
416
|
|
|
341
417
|
- `--input`: source SQL file
|
|
342
418
|
- `--output`: output path (split dir for `split`, reconstructed file for `reconstruct`/`validate`)
|
|
343
419
|
- `--backup`: create backup of dirty split directory before running split
|
|
344
420
|
- `--no-backup`: disable backup of dirty split directory before running split
|
|
421
|
+
- `--force` (sync commands only): skip linked migration alignment preflight
|
|
345
422
|
|
|
346
423
|
For `validate`, you can pass reconstructed path either as `--output <path>` or as the second positional argument.
|
|
347
|
-
|
|
424
|
+
|
|
348
425
|
`db reset` supports:
|
|
349
426
|
|
|
350
427
|
- `--psql`: apply deferred migrations via `psql` instead of `supabase migration up`
|
|
428
|
+
- `--strict-mixed`: fail when any mixed schema+DML migration is detected (default behavior only fails when mixed migrations are after cutoff)
|
|
351
429
|
- `--migrations-dir <path>`: override migrations directory (default `supabase/migrations`)
|
|
352
430
|
- `--temp-dir <path>`: override temporary defer directory (default `supabase/.tmp-migrations`)
|
|
431
|
+
- `--env <name>`: use `postSeedCutoffByEnv.<name>` as fallback cutoff source
|
|
353
432
|
|
|
354
433
|
`start` supports:
|
|
355
434
|
|
|
356
435
|
- `--psql`: apply deferred migrations via `psql` instead of `supabase migration up`
|
|
436
|
+
- `--strict-mixed`: fail when any mixed schema+DML migration is detected (default behavior only fails when mixed migrations are after cutoff)
|
|
357
437
|
- `--migrations-dir <path>`: override migrations directory (default `supabase/migrations`)
|
|
358
438
|
- `--temp-dir <path>`: override temporary defer directory (default `supabase/.tmp-migrations`)
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
439
|
+
- `--env <name>`: use `postSeedCutoffByEnv.<name>` as fallback cutoff source
|
|
440
|
+
|
|
441
|
+
`cutoff detect` supports:
|
|
442
|
+
|
|
443
|
+
- `--env <name>`: include environment fallback lookup
|
|
444
|
+
- `--json`: print machine-readable output
|
|
445
|
+
|
|
446
|
+
## Deep dive: why `supabee db reset` and `supabee start`
|
|
447
|
+
|
|
448
|
+
The short version is in the **Why?** section above. These commands matter most when local replay order diverges from how production data actually evolved:
|
|
449
|
+
|
|
450
|
+
1. Seed files may be shaped for pre-migration schema.
|
|
451
|
+
2. Some migrations intentionally mutate/seed production data for traceability (for example RBAC rows).
|
|
452
|
+
3. Local `migrations -> seed` replay can fail even when production worked on already-populated data.
|
|
453
|
+
|
|
454
|
+
By deferring post-seed migrations and applying them after seed load, `supabee` better matches this production-style path.
|
|
455
|
+
|
|
456
|
+
## Migration + Seed Duplication Caveat
|
|
457
|
+
|
|
458
|
+
If the same logical data mutation exists in both migration SQL and seed files, local replay can become order-dependent and brittle.
|
|
459
|
+
|
|
460
|
+
Typical symptoms:
|
|
461
|
+
- enum/value already exists errors,
|
|
462
|
+
- duplicate key or constraint violations,
|
|
463
|
+
- reset/start-only failures that don’t appear on incremental production deploys.
|
|
464
|
+
|
|
379
465
|
Recommended approach:
|
|
380
466
|
|
|
381
467
|
1. Keep schema structure changes in migrations.
|
|
382
468
|
2. Keep baseline/reference seed rows in seed files.
|
|
383
|
-
3.
|
|
384
|
-
4.
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
supabee
|
|
392
|
-
supabee
|
|
393
|
-
supabee sync
|
|
394
|
-
supabee schema --help
|
|
469
|
+
3. Put data mutations in dedicated migration files; `supabee` auto-detects these by SQL patterns.
|
|
470
|
+
4. Use `supabee migration audit` to review classification and `supabee migration mark` if you want explicit marker comments in files.
|
|
471
|
+
5. Keep data migrations free of schema DDL (`CREATE`/`ALTER`/`DROP ...`); mixed files are blocked and must be split.
|
|
472
|
+
6. Make migration-time data mutations idempotent (`IF NOT EXISTS`, `ON CONFLICT DO NOTHING`, guarded updates).
|
|
473
|
+
|
|
474
|
+
## Help
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
supabee --help
|
|
478
|
+
supabee init --help
|
|
479
|
+
supabee sync --help
|
|
480
|
+
supabee sync schema --help
|
|
481
|
+
supabee sync data --help
|
|
482
|
+
supabee schema --help
|
|
395
483
|
supabee data --help
|
|
396
484
|
supabee start --help
|
|
397
485
|
supabee db --help
|
|
398
486
|
supabee db reset --help
|
|
487
|
+
supabee cutoff detect --help
|
|
488
|
+
supabee migration audit --help
|
|
489
|
+
supabee migration mark --help
|
|
490
|
+
supabee migration unmark --help
|
|
399
491
|
```
|
|
400
|
-
|
|
401
|
-
Legacy CLI alias is still available: `supabase-splitter --help`.
|
|
402
|
-
|
|
403
|
-
## Development
|
|
404
|
-
|
|
405
|
-
```bash
|
|
406
|
-
npm install
|
|
407
|
-
npm run typecheck
|
|
408
|
-
npm run build
|
|
409
|
-
npm run test
|
|
410
|
-
npm run pack:check
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
RC gate checklist: `docs/rc-checklist.md`
|
|
492
|
+
|
|
493
|
+
Legacy CLI alias is still available: `supabase-splitter --help`.
|
|
494
|
+
|
|
495
|
+
## Development
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
npm install
|
|
499
|
+
npm run typecheck
|
|
500
|
+
npm run build
|
|
501
|
+
npm run test
|
|
502
|
+
npm run pack:check
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
RC gate checklist: `docs/rc-checklist.md`
|