@codemarc/blt 1.10.1 → 1.10.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 +83 -0
- package/dist/blt +2 -0
- package/dist/blt.d.ts.map +1 -1
- package/dist/blt.js.map +1 -1
- package/dist/commands/db/diff-endpoint.d.ts +16 -0
- package/dist/commands/db/diff-endpoint.d.ts.map +1 -0
- package/dist/commands/db/diff-endpoint.js +39 -0
- package/dist/commands/db/diff-endpoint.js.map +1 -0
- package/dist/commands/db/diff.d.ts +37 -0
- package/dist/commands/db/diff.d.ts.map +1 -0
- package/dist/commands/db/diff.js +123 -0
- package/dist/commands/db/diff.js.map +1 -0
- package/dist/commands/db/dump.d.ts +23 -0
- package/dist/commands/db/dump.d.ts.map +1 -0
- package/dist/commands/db/dump.js +49 -0
- package/dist/commands/db/dump.js.map +1 -0
- package/dist/commands/db/env-url.d.ts +4 -0
- package/dist/commands/db/env-url.d.ts.map +1 -0
- package/dist/commands/db/env-url.js +34 -0
- package/dist/commands/db/env-url.js.map +1 -0
- package/dist/commands/db/patch.d.ts +14 -0
- package/dist/commands/db/patch.d.ts.map +1 -0
- package/dist/commands/db/patch.js +58 -0
- package/dist/commands/db/patch.js.map +1 -0
- package/dist/commands/db/run.d.ts +4 -0
- package/dist/commands/db/run.d.ts.map +1 -0
- package/dist/commands/db/run.js +19 -0
- package/dist/commands/db/run.js.map +1 -0
- package/dist/commands/db/schema-loader.d.ts +28 -0
- package/dist/commands/db/schema-loader.d.ts.map +1 -0
- package/dist/commands/db/schema-loader.js +121 -0
- package/dist/commands/db/schema-loader.js.map +1 -0
- package/dist/commands/db/sql.d.ts +10 -0
- package/dist/commands/db/sql.d.ts.map +1 -0
- package/dist/commands/db/sql.js +152 -0
- package/dist/commands/db/sql.js.map +1 -0
- package/dist/commands/db/supabase-schema.d.ts +38 -0
- package/dist/commands/db/supabase-schema.d.ts.map +1 -0
- package/dist/commands/db/supabase-schema.js +132 -0
- package/dist/commands/db/supabase-schema.js.map +1 -0
- package/dist/commands/db.d.ts +3 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +116 -0
- package/dist/commands/db.js.map +1 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
- **Bucket**: Supabase storage — list buckets, list/upload/download files, get URLs
|
|
12
12
|
- **Cleanup**: Remove generated SQL/instance files, clean infrequently used YAML tags
|
|
13
13
|
- **Data**: Read-only pull of live menu graph into versioned snapshots; apply to a dev database
|
|
14
|
+
- **Db**: Run ad-hoc SQL strings or `.sql` files; compare schemas between trailz envs
|
|
14
15
|
- **Deploy**: Deploy schema/data from SQL files, run a single SQL file
|
|
15
16
|
- **Env**: Decrypt trailz `.trailz/env/env.<name>.bin` to `.env` via smash (`blt env get`; expands `$VAR` by default; requires `SMASH_KEY`)
|
|
16
17
|
- **Image**: WebP conversion, sharpening, color manipulation, and enhancement
|
|
@@ -74,6 +75,7 @@ blt deploy schema
|
|
|
74
75
|
| `blt bucket` | names, list, upload, download, url, clear |
|
|
75
76
|
| `blt cleanup` | generated, tags |
|
|
76
77
|
| `blt data` | Pull / apply instance data snapshots |
|
|
78
|
+
| `blt db` | sql, run, dump, patch (schema tools) |
|
|
77
79
|
| `blt deploy` | Schema, data, sql file |
|
|
78
80
|
| `blt env` | get (decrypt trailz env to `.env`) |
|
|
79
81
|
| `blt image` | Convert, sharpen, enhance, recolor |
|
|
@@ -394,6 +396,87 @@ blt build data my_instance
|
|
|
394
396
|
|
|
395
397
|
---
|
|
396
398
|
|
|
399
|
+
## Db Commands
|
|
400
|
+
|
|
401
|
+
Ad-hoc SQL against the load database (`BLT_DATA_LOAD_URL` or `SUPABASE_CONNECTION_STRING`).
|
|
402
|
+
|
|
403
|
+
### `blt db sql <query>`
|
|
404
|
+
|
|
405
|
+
Execute a SQL string.
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
blt db sql "SELECT count(*) FROM settings"
|
|
409
|
+
blt db sql "SELECT * FROM settings LIMIT 5" --format json
|
|
410
|
+
blt db sql "SELECT * FROM settings LIMIT 5" --format jsonl
|
|
411
|
+
blt db sql "SELECT name,role FROM profiles LIMIT 5" --format jsonl | jq -c 'select(.role == "manager")'
|
|
412
|
+
blt db sql "SELECT * FROM settings LIMIT 5" --format toon
|
|
413
|
+
blt db sql "SELECT * FROM settings LIMIT 5" --format csv > settings.csv
|
|
414
|
+
blt db sql "UPDATE settings SET props = props WHERE false" --verbose
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**Options:**
|
|
418
|
+
|
|
419
|
+
- `-f, --format <format>` — Result format for SELECT queries: `table` (default), `json`, `jsonl`, `toon`, or `csv`
|
|
420
|
+
- `--verbose` — Execute each statement separately with progress labels
|
|
421
|
+
|
|
422
|
+
### `blt db run <file>`
|
|
423
|
+
|
|
424
|
+
Execute a `.sql` file.
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
blt db run ./scripts/my-migration.sql
|
|
428
|
+
blt db run ./dist/bltcore-v1.0.0.sql --verbose
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Options:**
|
|
432
|
+
|
|
433
|
+
- `--verbose` — Log each SQL statement as it runs
|
|
434
|
+
|
|
435
|
+
### `blt db dump <env>`
|
|
436
|
+
|
|
437
|
+
Dump the schema from a single trailz environment (name from `blt env list`).
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
cd data
|
|
441
|
+
blt db dump laf
|
|
442
|
+
blt db dump laf --schema public --dir ./diff
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
Writes `<env>.sql` (e.g. `laf.sql`) and `manifest.json` under `--dir` (default `diff`).
|
|
446
|
+
|
|
447
|
+
**Options:**
|
|
448
|
+
|
|
449
|
+
- `-s, --schema <name>` — Postgres schema to dump (default: `public`)
|
|
450
|
+
- `--dir <path>` — Output directory (default: `diff`)
|
|
451
|
+
|
|
452
|
+
### `blt db patch <source-env> <target-env>`
|
|
453
|
+
|
|
454
|
+
Generate a single roll-forward patch SQL file from **source** (desired schema) to **target** (database to update). Does **not** apply the patch — review the file, then run it with `blt db run`.
|
|
455
|
+
|
|
456
|
+
Names come from `blt env list`; paths ending in `.sql` reuse an existing dump.
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
cd data
|
|
460
|
+
blt db patch laf test1
|
|
461
|
+
blt db patch diff/laf.sql test1
|
|
462
|
+
blt db patch laf test1 --schema public,auth --name p1.sql --dir ./diff
|
|
463
|
+
blt db run ./diff/p1.sql
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
**`.sql` endpoints:** when either side is a file, Docker loads the dump(s) into temporary Postgres so `supabase db diff` can run.
|
|
467
|
+
|
|
468
|
+
**Options:**
|
|
469
|
+
|
|
470
|
+
- `-s, --schema <schemas>` — Comma-separated Postgres schemas (default: `public`)
|
|
471
|
+
- `-n, --name <file>` — Patch SQL filename (default: `patch.sql`)
|
|
472
|
+
- `--dir <path>` — Output directory (default: `diff`)
|
|
473
|
+
|
|
474
|
+
**Prerequisites:** `SMASH_KEY` (for env endpoints), trailz env bundles at `.trailz/env/env.<name>.bin`, [Supabase CLI](https://supabase.com/docs/guides/cli) on `PATH`, and **Docker** when either side is a `.sql` file path.
|
|
475
|
+
|
|
476
|
+
Generated SQL is evidence for review — not auto-approved production SQL. Prefer direct Postgres URLs (port 5432) in env bundles when pooler URLs cause patch timeouts.
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
397
480
|
## Deploy Commands
|
|
398
481
|
|
|
399
482
|
### `blt deploy schema [name]`
|
package/dist/blt
CHANGED
|
@@ -5,6 +5,7 @@ import bucketCommand from "./commands/bucket";
|
|
|
5
5
|
import buildCommand from "./commands/build";
|
|
6
6
|
import cleanupCommand from "./commands/cleanup";
|
|
7
7
|
// import dataCommand from "./commands/data";
|
|
8
|
+
import dbCommand from "./commands/db";
|
|
8
9
|
import deployCommand from "./commands/deploy";
|
|
9
10
|
import envCommand from "./commands/env";
|
|
10
11
|
import imageCommand from "./commands/image";
|
|
@@ -35,6 +36,7 @@ bucketCommand(program);
|
|
|
35
36
|
buildCommand(program);
|
|
36
37
|
cleanupCommand(program);
|
|
37
38
|
// dataCommand(program);
|
|
39
|
+
dbCommand(program);
|
|
38
40
|
deployCommand(program);
|
|
39
41
|
envCommand(program);
|
|
40
42
|
imageCommand(program);
|
package/dist/blt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blt.d.ts","sourceRoot":"","sources":["../src/blt.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"blt.d.ts","sourceRoot":"","sources":["../src/blt.ts"],"names":[],"mappings":";AA6BA,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C"}
|
package/dist/blt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blt.js","sourceRoot":"","sources":["../src/blt.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAC5C,OAAO,cAAc,MAAM,oBAAoB,CAAC;AAChD,6CAA6C;AAC7C,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAC5C,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,eAAe,MAAM,qBAAqB,CAAC;AAClD,OAAO,cAAc,MAAM,oBAAoB,CAAC;AAChD,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,eAAe,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAG,IAAI,EAAE,cAAc,CAAC,CAAC;AAE/D,MAAM,UAAU,iBAAiB;IAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC;AAED,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;KACjB,OAAO,CAAC,iBAAiB,EAAE,CAAC;KAC5B,WAAW,CAAC,cAAc,CAAC,CAAC;AAE5B,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,wBAAwB;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,eAAe,CAAC,OAAO,CAAC,CAAC;AAE3B,uCAAuC;AACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AACD,OAAO,CAAC,GAAG,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"blt.js","sourceRoot":"","sources":["../src/blt.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAC5C,OAAO,cAAc,MAAM,oBAAoB,CAAC;AAChD,6CAA6C;AAC7C,OAAO,SAAS,MAAM,eAAe,CAAC;AACtC,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAC5C,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,eAAe,MAAM,qBAAqB,CAAC;AAClD,OAAO,cAAc,MAAM,oBAAoB,CAAC;AAChD,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,eAAe,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAG,IAAI,EAAE,cAAc,CAAC,CAAC;AAE/D,MAAM,UAAU,iBAAiB;IAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC;AAED,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;KACjB,OAAO,CAAC,iBAAiB,EAAE,CAAC;KAC5B,WAAW,CAAC,cAAc,CAAC,CAAC;AAE5B,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,wBAAwB;AACxB,SAAS,CAAC,OAAO,CAAC,CAAC;AACnB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,eAAe,CAAC,OAAO,CAAC,CAAC;AAE3B,uCAAuC;AACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AACD,OAAO,CAAC,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Logger } from "@caporal/core";
|
|
2
|
+
export type DiffEndpoint = {
|
|
3
|
+
kind: "env";
|
|
4
|
+
spec: string;
|
|
5
|
+
dbUrl: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: "file";
|
|
8
|
+
spec: string;
|
|
9
|
+
path: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function isSqlFileSpec(spec: string): boolean;
|
|
12
|
+
export declare function resolveSqlFilePath(spec: string, cwd: string, logger: Logger): string;
|
|
13
|
+
export declare function resolveDiffEndpoint(spec: string, logger: Logger, cwd: string): DiffEndpoint;
|
|
14
|
+
/** Copy an existing dump into the diff output dir when it is not already there. */
|
|
15
|
+
export declare function materializeDumpArtifact(sourcePath: string, artifactPath: string, logger: Logger): string;
|
|
16
|
+
//# sourceMappingURL=diff-endpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-endpoint.d.ts","sourceRoot":"","sources":["../../../src/commands/db/diff-endpoint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAG5C,MAAM,MAAM,YAAY,GACrB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOpF;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACT,YAAY,CAcd;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,CACtC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACZ,MAAM,CAQR"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { copyFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, resolve } from "node:path";
|
|
3
|
+
import { resolveTrailzConnectionString } from "./env-url";
|
|
4
|
+
export function isSqlFileSpec(spec) {
|
|
5
|
+
return /\.sql$/i.test(spec.trim());
|
|
6
|
+
}
|
|
7
|
+
export function resolveSqlFilePath(spec, cwd, logger) {
|
|
8
|
+
const path = isAbsolute(spec) ? spec : resolve(cwd, spec);
|
|
9
|
+
if (!existsSync(path)) {
|
|
10
|
+
logger.error(`SQL file not found: ${path}`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
return path;
|
|
14
|
+
}
|
|
15
|
+
export function resolveDiffEndpoint(spec, logger, cwd) {
|
|
16
|
+
if (isSqlFileSpec(spec)) {
|
|
17
|
+
return {
|
|
18
|
+
kind: "file",
|
|
19
|
+
spec,
|
|
20
|
+
path: resolveSqlFilePath(spec, cwd, logger),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
kind: "env",
|
|
25
|
+
spec,
|
|
26
|
+
dbUrl: resolveTrailzConnectionString(spec, logger, cwd),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** Copy an existing dump into the diff output dir when it is not already there. */
|
|
30
|
+
export function materializeDumpArtifact(sourcePath, artifactPath, logger) {
|
|
31
|
+
if (resolve(sourcePath) === resolve(artifactPath)) {
|
|
32
|
+
logger.info(`Using existing dump: ${sourcePath}`);
|
|
33
|
+
return sourcePath;
|
|
34
|
+
}
|
|
35
|
+
copyFileSync(sourcePath, artifactPath);
|
|
36
|
+
logger.info(`Copied ${sourcePath} → ${artifactPath}`);
|
|
37
|
+
return artifactPath;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=diff-endpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-endpoint.js","sourceRoot":"","sources":["../../../src/commands/db/diff-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAM1D,MAAM,UAAU,aAAa,CAAC,IAAY;IACzC,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,GAAW,EAAE,MAAc;IAC3E,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,mBAAmB,CAClC,IAAY,EACZ,MAAc,EACd,GAAW;IAEX,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO;YACN,IAAI,EAAE,MAAM;YACZ,IAAI;YACJ,IAAI,EAAE,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC;SAC3C,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,EAAE,KAAK;QACX,IAAI;QACJ,KAAK,EAAE,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC;KACvD,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,uBAAuB,CACtC,UAAkB,EAClB,YAAoB,EACpB,MAAc;IAEd,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;QAClD,OAAO,UAAU,CAAC;IACnB,CAAC;IACD,YAAY,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,CAAC,UAAU,UAAU,MAAM,YAAY,EAAE,CAAC,CAAC;IACtD,OAAO,YAAY,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Logger } from "@caporal/core";
|
|
2
|
+
export type DbDiffOptions = {
|
|
3
|
+
sourceEnv: string;
|
|
4
|
+
targetEnv: string;
|
|
5
|
+
schema: string;
|
|
6
|
+
dir: string;
|
|
7
|
+
cwd?: string;
|
|
8
|
+
};
|
|
9
|
+
export type DiffArtifactKey = "source.sql" | "target.sql" | "rollforward.sql" | "rollback.sql";
|
|
10
|
+
export type DiffManifest = {
|
|
11
|
+
generatedAt: string;
|
|
12
|
+
source: {
|
|
13
|
+
kind: "env" | "file";
|
|
14
|
+
spec: string;
|
|
15
|
+
};
|
|
16
|
+
target: {
|
|
17
|
+
kind: "env" | "file";
|
|
18
|
+
spec: string;
|
|
19
|
+
};
|
|
20
|
+
schema: string;
|
|
21
|
+
dir: string;
|
|
22
|
+
connections: {
|
|
23
|
+
source: string;
|
|
24
|
+
target: string;
|
|
25
|
+
};
|
|
26
|
+
artifacts: Partial<Record<DiffArtifactKey, {
|
|
27
|
+
path: string;
|
|
28
|
+
bytes: number;
|
|
29
|
+
}>>;
|
|
30
|
+
notes: string[];
|
|
31
|
+
};
|
|
32
|
+
export declare function buildDiffPlan(sourceUrl: string, targetUrl: string, schema: string, outDir: string): {
|
|
33
|
+
rollforward: string[];
|
|
34
|
+
rollback: string[];
|
|
35
|
+
};
|
|
36
|
+
export declare function dbDiff(opts: DbDiffOptions, logger: Logger): Promise<void>;
|
|
37
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/commands/db/diff.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAoB5C,MAAM,MAAM,aAAa,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GACxB,YAAY,GACZ,YAAY,GACZ,iBAAiB,GACjB,cAAc,CAAC;AAElB,MAAM,MAAM,YAAY,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QAAE,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,MAAM,EAAE;QAAE,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KACf,CAAC;IACF,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC7E,KAAK,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC;AAEF,wBAAgB,aAAa,CAC5B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM;;;EAgBd;AA4CD,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgH/E"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { runCommand } from "../app/shell";
|
|
4
|
+
import { redactedDbUrl } from "../data/helpers";
|
|
5
|
+
import { materializeDumpArtifact, resolveDiffEndpoint, } from "./diff-endpoint";
|
|
6
|
+
import { resolveSchemaUrlsForDiff } from "./schema-loader";
|
|
7
|
+
import { buildSupabaseDiffArgs, ensureOutDir, fileBytes, prependHeader, requireSupabaseCli, resolveOutDir, runSchemaDump, sqlFileHeader, } from "./supabase-schema";
|
|
8
|
+
export function buildDiffPlan(sourceUrl, targetUrl, schema, outDir) {
|
|
9
|
+
return {
|
|
10
|
+
rollforward: buildSupabaseDiffArgs(targetUrl, sourceUrl, schema, join(outDir, "rollforward.sql")),
|
|
11
|
+
rollback: buildSupabaseDiffArgs(sourceUrl, targetUrl, schema, join(outDir, "rollback.sql")),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function connectionLabel(endpoint) {
|
|
15
|
+
return endpoint.kind === "env"
|
|
16
|
+
? redactedDbUrl(endpoint.dbUrl)
|
|
17
|
+
: endpoint.path;
|
|
18
|
+
}
|
|
19
|
+
function prepareDumpArtifact(endpoint, artifactPath, otherSpec, opts, generatedAt, logger, cwd, side) {
|
|
20
|
+
const header = sqlFileHeader({
|
|
21
|
+
command: "diff",
|
|
22
|
+
kind: "dump",
|
|
23
|
+
env: endpoint.spec,
|
|
24
|
+
otherEnv: otherSpec,
|
|
25
|
+
schema: opts.schema,
|
|
26
|
+
generatedAt,
|
|
27
|
+
});
|
|
28
|
+
if (endpoint.kind === "file") {
|
|
29
|
+
materializeDumpArtifact(endpoint.path, artifactPath, logger);
|
|
30
|
+
prependHeader(artifactPath, header);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
runSchemaDump({
|
|
34
|
+
dbUrl: endpoint.dbUrl,
|
|
35
|
+
schema: opts.schema,
|
|
36
|
+
outputFile: artifactPath,
|
|
37
|
+
header,
|
|
38
|
+
logger,
|
|
39
|
+
cwd,
|
|
40
|
+
label: side === "source" ? "Dumping source schema…" : "Dumping target schema…",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export async function dbDiff(opts, logger) {
|
|
44
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
45
|
+
const outDir = resolveOutDir(opts.dir, cwd);
|
|
46
|
+
const generatedAt = new Date().toISOString();
|
|
47
|
+
if (opts.sourceEnv === opts.targetEnv) {
|
|
48
|
+
logger.error("Source and target must differ.");
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
requireSupabaseCli(logger);
|
|
52
|
+
ensureOutDir(outDir, logger);
|
|
53
|
+
logger.info(`Schema: ${opts.schema}`);
|
|
54
|
+
const source = resolveDiffEndpoint(opts.sourceEnv, logger, cwd);
|
|
55
|
+
const target = resolveDiffEndpoint(opts.targetEnv, logger, cwd);
|
|
56
|
+
const sourceArtifact = join(outDir, "source.sql");
|
|
57
|
+
const targetArtifact = join(outDir, "target.sql");
|
|
58
|
+
prepareDumpArtifact(source, sourceArtifact, opts.targetEnv, opts, generatedAt, logger, cwd, "source");
|
|
59
|
+
prepareDumpArtifact(target, targetArtifact, opts.sourceEnv, opts, generatedAt, logger, cwd, "target");
|
|
60
|
+
const { sourceUrl, targetUrl, cleanup } = resolveSchemaUrlsForDiff({
|
|
61
|
+
source: source.kind === "env"
|
|
62
|
+
? { kind: "env", dbUrl: source.dbUrl }
|
|
63
|
+
: { kind: "file", path: sourceArtifact },
|
|
64
|
+
target: target.kind === "env"
|
|
65
|
+
? { kind: "env", dbUrl: target.dbUrl }
|
|
66
|
+
: { kind: "file", path: targetArtifact },
|
|
67
|
+
logger,
|
|
68
|
+
});
|
|
69
|
+
try {
|
|
70
|
+
const plan = buildDiffPlan(sourceUrl, targetUrl, opts.schema, outDir);
|
|
71
|
+
const diffHeader = (kind) => sqlFileHeader({
|
|
72
|
+
command: "diff",
|
|
73
|
+
kind,
|
|
74
|
+
env: opts.sourceEnv,
|
|
75
|
+
otherEnv: opts.targetEnv,
|
|
76
|
+
schema: opts.schema,
|
|
77
|
+
generatedAt,
|
|
78
|
+
});
|
|
79
|
+
logger.info("Generating roll-forward SQL (target → source)…");
|
|
80
|
+
runCommand("supabase", plan.rollforward, logger, { cwd });
|
|
81
|
+
prependHeader(join(outDir, "rollforward.sql"), diffHeader("rollforward"));
|
|
82
|
+
logger.info("Generating rollback SQL (source → target)…");
|
|
83
|
+
runCommand("supabase", plan.rollback, logger, { cwd });
|
|
84
|
+
prependHeader(join(outDir, "rollback.sql"), diffHeader("rollback"));
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
cleanup();
|
|
88
|
+
}
|
|
89
|
+
const artifacts = {};
|
|
90
|
+
for (const key of [
|
|
91
|
+
"source.sql",
|
|
92
|
+
"target.sql",
|
|
93
|
+
"rollforward.sql",
|
|
94
|
+
"rollback.sql",
|
|
95
|
+
]) {
|
|
96
|
+
const path = join(outDir, key);
|
|
97
|
+
artifacts[key] = { path, bytes: fileBytes(path) };
|
|
98
|
+
}
|
|
99
|
+
const manifest = {
|
|
100
|
+
generatedAt,
|
|
101
|
+
source: { kind: source.kind, spec: source.spec },
|
|
102
|
+
target: { kind: target.kind, spec: target.spec },
|
|
103
|
+
schema: opts.schema,
|
|
104
|
+
dir: outDir,
|
|
105
|
+
connections: {
|
|
106
|
+
source: connectionLabel(source),
|
|
107
|
+
target: connectionLabel(target),
|
|
108
|
+
},
|
|
109
|
+
artifacts,
|
|
110
|
+
notes: [
|
|
111
|
+
"Review rollforward.sql before applying to the target database.",
|
|
112
|
+
"Rollback SQL may include destructive DDL — review before use.",
|
|
113
|
+
".sql file endpoints skip re-dump; existing files are copied to source.sql / target.sql when needed.",
|
|
114
|
+
"Docker is used to load .sql files for supabase db diff when a side is not a live env URL.",
|
|
115
|
+
"Prefer direct Postgres URLs (port 5432) when pooler URLs cause dump/diff timeouts.",
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
const manifestPath = join(outDir, "manifest.json");
|
|
119
|
+
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
120
|
+
logger.info(`Wrote ${manifestPath}`);
|
|
121
|
+
logger.info("Done. Review rollforward.sql and rollback.sql before applying.");
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/commands/db/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACN,uBAAuB,EACvB,mBAAmB,GAEnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EACN,qBAAqB,EACrB,YAAY,EACZ,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,aAAa,GACb,MAAM,mBAAmB,CAAC;AA8B3B,MAAM,UAAU,aAAa,CAC5B,SAAiB,EACjB,SAAiB,EACjB,MAAc,EACd,MAAc;IAEd,OAAO;QACN,WAAW,EAAE,qBAAqB,CACjC,SAAS,EACT,SAAS,EACT,MAAM,EACN,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAC/B;QACD,QAAQ,EAAE,qBAAqB,CAC9B,SAAS,EACT,SAAS,EACT,MAAM,EACN,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAC5B;KACD,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,QAAsB;IAC9C,OAAO,QAAQ,CAAC,IAAI,KAAK,KAAK;QAC7B,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,SAAS,mBAAmB,CAC3B,QAAsB,EACtB,YAAoB,EACpB,SAAiB,EACjB,IAAmB,EACnB,WAAmB,EACnB,MAAc,EACd,GAAW,EACX,IAAyB;IAEzB,MAAM,MAAM,GAAG,aAAa,CAAC;QAC5B,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,QAAQ,CAAC,IAAI;QAClB,QAAQ,EAAE,SAAS;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,WAAW;KACX,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC9B,uBAAuB,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;QAC7D,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACpC,OAAO;IACR,CAAC;IAED,aAAa,CAAC;QACb,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,YAAY;QACxB,MAAM;QACN,MAAM;QACN,GAAG;QACH,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,wBAAwB;KAC9E,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAmB,EAAE,MAAc;IAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE7C,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtC,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAEhE,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAElD,mBAAmB,CAClB,MAAM,EACN,cAAc,EACd,IAAI,CAAC,SAAS,EACd,IAAI,EACJ,WAAW,EACX,MAAM,EACN,GAAG,EACH,QAAQ,CACR,CAAC;IACF,mBAAmB,CAClB,MAAM,EACN,cAAc,EACd,IAAI,CAAC,SAAS,EACd,IAAI,EACJ,WAAW,EACX,MAAM,EACN,GAAG,EACH,QAAQ,CACR,CAAC;IAEF,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,wBAAwB,CAAC;QAClE,MAAM,EACL,MAAM,CAAC,IAAI,KAAK,KAAK;YACpB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE;YACtC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE;QAC1C,MAAM,EACL,MAAM,CAAC,IAAI,KAAK,KAAK;YACpB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE;YACtC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE;QAC1C,MAAM;KACN,CAAC,CAAC;IAEH,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAEtE,MAAM,UAAU,GAAG,CAAC,IAAgC,EAAE,EAAE,CACvD,aAAa,CAAC;YACb,OAAO,EAAE,MAAM;YACf,IAAI;YACJ,GAAG,EAAE,IAAI,CAAC,SAAS;YACnB,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,WAAW;SACX,CAAC,CAAC;QAEJ,MAAM,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAC9D,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1D,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC;QAE1E,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QAC1D,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACvD,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACrE,CAAC;YAAS,CAAC;QACV,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAA8B,EAAE,CAAC;IAChD,KAAK,MAAM,GAAG,IAAI;QACjB,YAAY;QACZ,YAAY;QACZ,iBAAiB;QACjB,cAAc;KACL,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/B,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,CAAC;IAED,MAAM,QAAQ,GAAiB;QAC9B,WAAW;QACX,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;QAChD,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;QAChD,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,MAAM;QACX,WAAW,EAAE;YACZ,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;YAC/B,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;SAC/B;QACD,SAAS;QACT,KAAK,EAAE;YACN,gEAAgE;YAChE,+DAA+D;YAC/D,qGAAqG;YACrG,2FAA2F;YAC3F,oFAAoF;SACpF;KACD,CAAC;IAEF,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,aAAa,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9E,MAAM,CAAC,IAAI,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC;IACrC,MAAM,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Logger } from "@caporal/core";
|
|
2
|
+
export type DbDumpOptions = {
|
|
3
|
+
env: string;
|
|
4
|
+
schema: string;
|
|
5
|
+
dir: string;
|
|
6
|
+
cwd?: string;
|
|
7
|
+
};
|
|
8
|
+
export type DumpManifest = {
|
|
9
|
+
generatedAt: string;
|
|
10
|
+
env: string;
|
|
11
|
+
schema: string;
|
|
12
|
+
dir: string;
|
|
13
|
+
connection: string;
|
|
14
|
+
artifacts: {
|
|
15
|
+
[fileName: string]: {
|
|
16
|
+
path: string;
|
|
17
|
+
bytes: number;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare function dumpFileName(envName: string): string;
|
|
22
|
+
export declare function dbDump(opts: DbDumpOptions, logger: Logger): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=dump.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump.d.ts","sourceRoot":"","sources":["../../../src/commands/db/dump.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAY5C,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QACV,CAAC,QAAQ,EAAE,MAAM,GAAG;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACpD,CAAC;CACF,CAAC;AAEF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C/E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { redactedDbUrl } from "../data/helpers";
|
|
4
|
+
import { resolveTrailzConnectionString } from "./env-url";
|
|
5
|
+
import { ensureOutDir, fileBytes, requireSupabaseCli, resolveOutDir, runSchemaDump, sqlFileHeader, } from "./supabase-schema";
|
|
6
|
+
export function dumpFileName(envName) {
|
|
7
|
+
return `${envName}.sql`;
|
|
8
|
+
}
|
|
9
|
+
export async function dbDump(opts, logger) {
|
|
10
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
11
|
+
const outDir = resolveOutDir(opts.dir, cwd);
|
|
12
|
+
const generatedAt = new Date().toISOString();
|
|
13
|
+
const fileName = dumpFileName(opts.env);
|
|
14
|
+
const outputFile = join(outDir, fileName);
|
|
15
|
+
requireSupabaseCli(logger);
|
|
16
|
+
ensureOutDir(outDir, logger);
|
|
17
|
+
logger.info(`Schema: ${opts.schema}`);
|
|
18
|
+
const dbUrl = resolveTrailzConnectionString(opts.env, logger, cwd);
|
|
19
|
+
runSchemaDump({
|
|
20
|
+
dbUrl,
|
|
21
|
+
schema: opts.schema,
|
|
22
|
+
outputFile,
|
|
23
|
+
header: sqlFileHeader({
|
|
24
|
+
command: "dump",
|
|
25
|
+
kind: "dump",
|
|
26
|
+
env: opts.env,
|
|
27
|
+
schema: opts.schema,
|
|
28
|
+
generatedAt,
|
|
29
|
+
}),
|
|
30
|
+
logger,
|
|
31
|
+
cwd,
|
|
32
|
+
label: `Dumping ${opts.env} schema…`,
|
|
33
|
+
});
|
|
34
|
+
const manifest = {
|
|
35
|
+
generatedAt,
|
|
36
|
+
env: opts.env,
|
|
37
|
+
schema: opts.schema,
|
|
38
|
+
dir: outDir,
|
|
39
|
+
connection: redactedDbUrl(dbUrl),
|
|
40
|
+
artifacts: {
|
|
41
|
+
[fileName]: { path: outputFile, bytes: fileBytes(outputFile) },
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
const manifestPath = join(outDir, "manifest.json");
|
|
45
|
+
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
46
|
+
logger.info(`Wrote ${outputFile}`);
|
|
47
|
+
logger.info(`Wrote ${manifestPath}`);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=dump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump.js","sourceRoot":"","sources":["../../../src/commands/db/dump.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EACN,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,aAAa,GACb,MAAM,mBAAmB,CAAC;AAoB3B,MAAM,UAAU,YAAY,CAAC,OAAe;IAC3C,OAAO,GAAG,OAAO,MAAM,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAmB,EAAE,MAAc;IAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAE1C,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtC,MAAM,KAAK,GAAG,6BAA6B,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAEnE,aAAa,CAAC;QACb,KAAK;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU;QACV,MAAM,EAAE,aAAa,CAAC;YACrB,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,MAAM;YACZ,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,WAAW;SACX,CAAC;QACF,MAAM;QACN,GAAG;QACH,KAAK,EAAE,WAAW,IAAI,CAAC,GAAG,UAAU;KACpC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAiB;QAC9B,WAAW;QACX,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,MAAM;QACX,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC;QAChC,SAAS,EAAE;YACV,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE;SAC9D;KACD,CAAC;IAEF,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,aAAa,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9E,MAAM,CAAC,IAAI,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Logger } from "@caporal/core";
|
|
2
|
+
/** Decrypt a trailz env bundle and return `SUPABASE_CONNECTION_STRING`. */
|
|
3
|
+
export declare function resolveTrailzConnectionString(envName: string, logger: Logger, cwd?: string): string;
|
|
4
|
+
//# sourceMappingURL=env-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-url.d.ts","sourceRoot":"","sources":["../../../src/commands/db/env-url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAY5C,2EAA2E;AAC3E,wBAAgB,6BAA6B,CAC5C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,GAAE,MAAsB,GACzB,MAAM,CAiCR"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ensureAppEnv, parseDotEnvAssignments, resolveTrailzEnvPaths, } from "../app/env-check";
|
|
2
|
+
import { decryptTrailzEnvBase } from "../app/env-decrypt";
|
|
3
|
+
import { redactedDbUrl } from "../data/helpers";
|
|
4
|
+
import { readTrailzKeysExpansionContext } from "../notify/keys";
|
|
5
|
+
const NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
6
|
+
/** Decrypt a trailz env bundle and return `SUPABASE_CONNECTION_STRING`. */
|
|
7
|
+
export function resolveTrailzConnectionString(envName, logger, cwd = process.cwd()) {
|
|
8
|
+
if (!NAME_RE.test(envName)) {
|
|
9
|
+
logger.error(`Invalid environment name "${envName}": use one segment (letters, numbers, . _ -).`);
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
ensureAppEnv({ envName, cwd, logger, trailzOnly: true });
|
|
13
|
+
const resolved = resolveTrailzEnvPaths(cwd, envName);
|
|
14
|
+
if (!resolved) {
|
|
15
|
+
logger.error(`Trailz env bundle not found for "${envName}"`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const keysContext = readTrailzKeysExpansionContext({ cwd });
|
|
19
|
+
const body = decryptTrailzEnvBase(resolved.basePath, {
|
|
20
|
+
cwd,
|
|
21
|
+
expand: true,
|
|
22
|
+
expansionContext: keysContext,
|
|
23
|
+
});
|
|
24
|
+
const parsed = parseDotEnvAssignments(body);
|
|
25
|
+
const url = parsed.SUPABASE_CONNECTION_STRING;
|
|
26
|
+
if (!url) {
|
|
27
|
+
logger.error(`SUPABASE_CONNECTION_STRING not found in trailz env "${envName}".\n` +
|
|
28
|
+
` Run: blt env get ${envName} and verify the bundle contents.`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
logger.info(`Resolved ${envName} → ${redactedDbUrl(url)}`);
|
|
32
|
+
return url;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=env-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-url.js","sourceRoot":"","sources":["../../../src/commands/db/env-url.ts"],"names":[],"mappings":"AACA,OAAO,EACN,YAAY,EACZ,sBAAsB,EACtB,qBAAqB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAEhE,MAAM,OAAO,GAAG,8BAA8B,CAAC;AAE/C,2EAA2E;AAC3E,MAAM,UAAU,6BAA6B,CAC5C,OAAe,EACf,MAAc,EACd,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAK,CACX,6BAA6B,OAAO,+CAA+C,CACnF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACrD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,oCAAoC,OAAO,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,WAAW,GAAG,8BAA8B,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE;QACpD,GAAG;QACH,MAAM,EAAE,IAAI;QACZ,gBAAgB,EAAE,WAAW;KAC7B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,0BAA0B,CAAC;IAC9C,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,MAAM,CAAC,KAAK,CACX,uDAAuD,OAAO,MAAM;YACnE,sBAAsB,OAAO,kCAAkC,CAChE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,YAAY,OAAO,MAAM,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3D,OAAO,GAAG,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Logger } from "@caporal/core";
|
|
2
|
+
export type DbPatchOptions = {
|
|
3
|
+
sourceEnv: string;
|
|
4
|
+
targetEnv: string;
|
|
5
|
+
schema: string;
|
|
6
|
+
name: string;
|
|
7
|
+
dir: string;
|
|
8
|
+
cwd?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const DEFAULT_PATCH_NAME = "patch.sql";
|
|
11
|
+
/** Roll-forward diff args: apply to target so it matches source. */
|
|
12
|
+
export declare function buildPatchArgs(sourceUrl: string, targetUrl: string, schema: string, outputFile: string): string[];
|
|
13
|
+
export declare function dbPatch(opts: DbPatchOptions, logger: Logger): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=patch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../../src/commands/db/patch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAe5C,MAAM,MAAM,cAAc,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C,oEAAoE;AACpE,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAChB,MAAM,EAAE,CAEV;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8DjF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { runCommand } from "../app/shell";
|
|
3
|
+
import { resolveDiffEndpoint } from "./diff-endpoint";
|
|
4
|
+
import { resolveSchemaUrlsForDiff } from "./schema-loader";
|
|
5
|
+
import { buildSupabaseDiffArgs, ensureOutDir, fileBytes, normalizeSchemaOption, prependHeader, requireSupabaseCli, resolveOutDir, sqlFileHeader, } from "./supabase-schema";
|
|
6
|
+
export const DEFAULT_PATCH_NAME = "patch.sql";
|
|
7
|
+
/** Roll-forward diff args: apply to target so it matches source. */
|
|
8
|
+
export function buildPatchArgs(sourceUrl, targetUrl, schema, outputFile) {
|
|
9
|
+
return buildSupabaseDiffArgs(targetUrl, sourceUrl, schema, outputFile);
|
|
10
|
+
}
|
|
11
|
+
export async function dbPatch(opts, logger) {
|
|
12
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
13
|
+
const outDir = resolveOutDir(opts.dir, cwd);
|
|
14
|
+
const schema = normalizeSchemaOption(opts.schema);
|
|
15
|
+
const generatedAt = new Date().toISOString();
|
|
16
|
+
const outputFile = join(outDir, opts.name);
|
|
17
|
+
if (!schema) {
|
|
18
|
+
logger.error("At least one schema is required (e.g. --schema public or public,auth).");
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
if (opts.sourceEnv === opts.targetEnv) {
|
|
22
|
+
logger.error("Source and target must differ.");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
requireSupabaseCli(logger);
|
|
26
|
+
ensureOutDir(outDir, logger);
|
|
27
|
+
logger.info(`Schema: ${schema}`);
|
|
28
|
+
const source = resolveDiffEndpoint(opts.sourceEnv, logger, cwd);
|
|
29
|
+
const target = resolveDiffEndpoint(opts.targetEnv, logger, cwd);
|
|
30
|
+
const { sourceUrl, targetUrl, cleanup } = resolveSchemaUrlsForDiff({
|
|
31
|
+
source: source.kind === "env"
|
|
32
|
+
? { kind: "env", dbUrl: source.dbUrl }
|
|
33
|
+
: { kind: "file", path: source.path },
|
|
34
|
+
target: target.kind === "env"
|
|
35
|
+
? { kind: "env", dbUrl: target.dbUrl }
|
|
36
|
+
: { kind: "file", path: target.path },
|
|
37
|
+
logger,
|
|
38
|
+
});
|
|
39
|
+
try {
|
|
40
|
+
logger.info("Generating patch SQL (target → source)…");
|
|
41
|
+
runCommand("supabase", buildPatchArgs(sourceUrl, targetUrl, schema, outputFile), logger, { cwd });
|
|
42
|
+
prependHeader(outputFile, sqlFileHeader({
|
|
43
|
+
command: "patch",
|
|
44
|
+
kind: "patch",
|
|
45
|
+
env: opts.sourceEnv,
|
|
46
|
+
otherEnv: opts.targetEnv,
|
|
47
|
+
schema,
|
|
48
|
+
generatedAt,
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
cleanup();
|
|
53
|
+
}
|
|
54
|
+
const bytes = fileBytes(outputFile);
|
|
55
|
+
logger.info(`Wrote ${outputFile} (${bytes} bytes)`);
|
|
56
|
+
logger.info(`Apply when ready: blt db run ${outputFile}`);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=patch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.js","sourceRoot":"","sources":["../../../src/commands/db/patch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/db/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE3E,wBAAsB,KAAK,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { runSqlFile } from "../../lib/database-runner";
|
|
4
|
+
export async function dbRun(filePath, options, logger) {
|
|
5
|
+
const resolved = resolve(filePath);
|
|
6
|
+
if (!existsSync(resolved)) {
|
|
7
|
+
logger.error(`SQL file not found: ${resolved}`);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
await runSqlFile(resolved, undefined, options);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15
|
+
logger.error(`Failed to run SQL file: ${message}`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/db/run.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAsB,MAAM,2BAA2B,CAAC;AAE3E,MAAM,CAAC,KAAK,UAAU,KAAK,CAC1B,QAAgB,EAChB,OAAsB,EACtB,MAAc;IAEd,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,CAAC,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;AACF,CAAC"}
|