@codemarc/blt 1.6.5 → 1.8.0
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 +192 -0
- package/dist/blt +4 -0
- package/dist/blt.d.ts.map +1 -1
- package/dist/blt.js.map +1 -1
- package/dist/commands/data/apply.d.ts +6 -0
- package/dist/commands/data/apply.d.ts.map +1 -0
- package/dist/commands/data/apply.js +363 -0
- package/dist/commands/data/apply.js.map +1 -0
- package/dist/commands/data/helpers.d.ts +15 -0
- package/dist/commands/data/helpers.d.ts.map +1 -0
- package/dist/commands/data/helpers.js +53 -0
- package/dist/commands/data/helpers.js.map +1 -0
- package/dist/commands/data/pull.d.ts +11 -0
- package/dist/commands/data/pull.d.ts.map +1 -0
- package/dist/commands/data/pull.js +101 -0
- package/dist/commands/data/pull.js.map +1 -0
- package/dist/commands/data/remove.d.ts +7 -0
- package/dist/commands/data/remove.d.ts.map +1 -0
- package/dist/commands/data/remove.js +29 -0
- package/dist/commands/data/remove.js.map +1 -0
- package/dist/commands/data.d.ts +3 -0
- package/dist/commands/data.d.ts.map +1 -0
- package/dist/commands/data.js +115 -0
- package/dist/commands/data.js.map +1 -0
- package/dist/commands/spin/dns.d.ts +7 -0
- package/dist/commands/spin/dns.d.ts.map +1 -0
- package/dist/commands/spin/dns.js +42 -0
- package/dist/commands/spin/dns.js.map +1 -0
- package/dist/commands/spin/down.d.ts +3 -0
- package/dist/commands/spin/down.d.ts.map +1 -0
- package/dist/commands/spin/down.js +17 -0
- package/dist/commands/spin/down.js.map +1 -0
- package/dist/commands/spin/helpers.d.ts +7 -0
- package/dist/commands/spin/helpers.d.ts.map +1 -0
- package/dist/commands/spin/helpers.js +38 -0
- package/dist/commands/spin/helpers.js.map +1 -0
- package/dist/commands/spin/list.d.ts +3 -0
- package/dist/commands/spin/list.d.ts.map +1 -0
- package/dist/commands/spin/list.js +20 -0
- package/dist/commands/spin/list.js.map +1 -0
- package/dist/commands/spin/setup.d.ts +3 -0
- package/dist/commands/spin/setup.d.ts.map +1 -0
- package/dist/commands/spin/setup.js +32 -0
- package/dist/commands/spin/setup.js.map +1 -0
- package/dist/commands/spin/ssh.d.ts +3 -0
- package/dist/commands/spin/ssh.d.ts.map +1 -0
- package/dist/commands/spin/ssh.js +14 -0
- package/dist/commands/spin/ssh.js.map +1 -0
- package/dist/commands/spin/status.d.ts +3 -0
- package/dist/commands/spin/status.d.ts.map +1 -0
- package/dist/commands/spin/status.js +21 -0
- package/dist/commands/spin/status.js.map +1 -0
- package/dist/commands/spin/up.d.ts +11 -0
- package/dist/commands/spin/up.d.ts.map +1 -0
- package/dist/commands/spin/up.js +34 -0
- package/dist/commands/spin/up.js.map +1 -0
- package/dist/commands/spin.d.ts +3 -0
- package/dist/commands/spin.d.ts.map +1 -0
- package/dist/commands/spin.js +166 -0
- package/dist/commands/spin.js.map +1 -0
- package/dist/lib/data-pull-extra-tables.d.ts +26 -0
- package/dist/lib/data-pull-extra-tables.d.ts.map +1 -0
- package/dist/lib/data-pull-extra-tables.js +212 -0
- package/dist/lib/data-pull-extra-tables.js.map +1 -0
- package/dist/lib/data-pull-manifest.d.ts +97 -0
- package/dist/lib/data-pull-manifest.d.ts.map +1 -0
- package/dist/lib/data-pull-manifest.js +603 -0
- package/dist/lib/data-pull-manifest.js.map +1 -0
- package/dist/lib/database-runner.d.ts +28 -2
- package/dist/lib/database-runner.d.ts.map +1 -1
- package/dist/lib/database-runner.js +112 -49
- package/dist/lib/database-runner.js.map +1 -1
- package/dist/lib/digitalocean.d.ts +60 -0
- package/dist/lib/digitalocean.d.ts.map +1 -0
- package/dist/lib/digitalocean.js +108 -0
- package/dist/lib/digitalocean.js.map +1 -0
- package/dist/lib/yaml-converter.d.ts +25 -1
- package/dist/lib/yaml-converter.d.ts.map +1 -1
- package/dist/lib/yaml-converter.js +98 -15
- package/dist/lib/yaml-converter.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -13,11 +13,13 @@
|
|
|
13
13
|
- **Init**: Clone repo script for BLT repositories
|
|
14
14
|
- **WAI**: AI config templates (Claude + Codex: AGENTS.md, skills, rules, commands, settings, MCP, PLAN, IMPLEMENT) — bltwai.com
|
|
15
15
|
- **Build**: Build schema from DDL files, build data from instance directory
|
|
16
|
+
- **Data**: Read-only pull of live menu graph into versioned snapshots; apply to a dev database
|
|
16
17
|
- **Deploy**: Deploy schema/data from SQL files, run a single SQL file
|
|
17
18
|
- **Bucket**: Supabase storage — list buckets, list/upload/download files, get URLs
|
|
18
19
|
- **Workflow**: List, show, delete, reload, and deploy GitHub Actions workflows (requires `gh`)
|
|
19
20
|
- **Show**: Schema info, row counts, env vars, DB version, repo list
|
|
20
21
|
- **Env**: Decrypt trailz `.trailz/env/.env.<name>.bin` to `.env` via smash (`blt env get`; requires `SMASH_KEY`)
|
|
22
|
+
- **Spin**: Manage DigitalOcean droplets and DNS for BLT test environments
|
|
21
23
|
- **Cleanup**: Remove generated SQL/instance files, clean infrequently used YAML tags
|
|
22
24
|
|
|
23
25
|
## Installation
|
|
@@ -50,6 +52,9 @@ blt template render legal/nda/mutual --data ./doc/nda/mutual-nda-blt-otter.yaml
|
|
|
50
52
|
# Update version.json in current directory
|
|
51
53
|
blt version update
|
|
52
54
|
|
|
55
|
+
# List DigitalOcean droplets
|
|
56
|
+
blt spin list
|
|
57
|
+
|
|
53
58
|
# List Supabase storage buckets
|
|
54
59
|
blt bucket names
|
|
55
60
|
|
|
@@ -71,10 +76,12 @@ blt deploy schema
|
|
|
71
76
|
| `blt init` | Clone script for BLT repos |
|
|
72
77
|
| `blt wai` | Claude Code config (claude, agents, skills, rules, commands, settings, mcp) |
|
|
73
78
|
| `blt build` | Schema (DDL), data (instance) |
|
|
79
|
+
| `blt data` | Pull / apply instance data snapshots |
|
|
74
80
|
| `blt deploy` | Schema, data, sql file |
|
|
75
81
|
| `blt workflow`| list, show, delete, reload, deploy |
|
|
76
82
|
| `blt bucket` | names, list, upload, download, url, clear |
|
|
77
83
|
| `blt show` | schema, counts, env, db, repo |
|
|
84
|
+
| `blt spin` | up, down, list, status, ssh, dns, setup |
|
|
78
85
|
| `blt env` | get (decrypt trailz env to `.env`) |
|
|
79
86
|
| `blt cleanup` | generated, tags |
|
|
80
87
|
|
|
@@ -416,6 +423,76 @@ blt deploy sql ./migrations/001_init.sql
|
|
|
416
423
|
|
|
417
424
|
---
|
|
418
425
|
|
|
426
|
+
## Data snapshots (`blt data`)
|
|
427
|
+
|
|
428
|
+
Export **instance-shaped** rows from Postgres into portable **JSON**, **YAML**, or **TOON** ([Token-Oriented Object Notation](https://toonformat.dev)) payloads that mirror `data/schema/instances/<instance>/yaml/`: `table:` / `procedure:` / `function:` targets plus `{ row }[]`. TOON yields smaller prompts for LLM workflows; `blt data apply` accepts `.toon` snapshots the same as JSON/YAML.
|
|
429
|
+
|
|
430
|
+
**Curated pulled assets:** `role_props`, `modules`, `settings` (one file per `kind`, e.g. `10-020-settings-02-location`), `payment_providers` (`10-020-settings-04-payment-providers`), `nodes`, `create_user` + `add_profile_role_by_email` (optional via flags), `insert_tax`, menu graph — `insert_menu`, `insert_category`, **`public.items`** as **table-mode** rows split into `10-121-items-menu` + `10-125-items-NN-<tag>` (stable `id` values for FKs such as `order_items`), and `insert_modifier_group` split into `10-135-groups-NN-<tag>`. Older snapshots may still contain a legacy `insert_item` function asset instead of `public.items`.
|
|
431
|
+
|
|
432
|
+
**Extra `public.*` tables (default):** By default, pull also discovers other `public` base tables not covered above and writes one asset per table (stems like `10-900-public-<table>`). Use **`--skip-extra-tables`** to pull only the curated manifest.
|
|
433
|
+
|
|
434
|
+
Use snapshots to seed a disposable dev DB from production-shaped data **without writes on pull**.
|
|
435
|
+
|
|
436
|
+
### Environment variables
|
|
437
|
+
|
|
438
|
+
| Variable | Purpose |
|
|
439
|
+
|----------|---------|
|
|
440
|
+
| `BLT_DATA_PULL_URL` | **Recommended.** Read URL for `blt data pull`. Use a replica or READ ONLY role. |
|
|
441
|
+
| `BLT_DATA_LOAD_URL` | Optional dev target for `blt data apply`. Falls back to `SUPABASE_CONNECTION_STRING`. |
|
|
442
|
+
|
|
443
|
+
If `BLT_DATA_PULL_URL` is unset, pull falls back to `SUPABASE_CONNECTION_STRING` (still runs inside `BEGIN READ ONLY`).
|
|
444
|
+
|
|
445
|
+
**Never** aim `blt data apply` at production. Apply first runs **`TRUNCATE … RESTART IDENTITY CASCADE`** only for **snapshot targets present in that manifest** that replace whole tables: function-mode replay targets (`insert_menu` → `menus`, `insert_category` → `categories`, `insert_modifier_group` → `groups`, `insert_tax` → `taxes`) and **table-mode `public.items`** when included. That clears dependent rows (e.g. `order_items` referencing `items`). Other table/procedure assets (`settings`, `nodes`, `payment_providers`, extra `public.*` dumps, etc.) are applied with **`INSERT` … `ON CONFLICT`**, `CALL`, or `SELECT` function calls — they are **not** covered by that truncate block unless their target is in the truncate set above.
|
|
446
|
+
|
|
447
|
+
### Pull / apply / remove flags and caveats
|
|
448
|
+
|
|
449
|
+
| Flag | Purpose |
|
|
450
|
+
|------|---------|
|
|
451
|
+
| `--skip-users` | Omit `10-070-users` and `10-071-profile-roles-extra`. Use when pulling from prod to avoid staff PII in files. |
|
|
452
|
+
| `--include-secrets` | Include `api_key`, `secret_key_encrypted`, `webhook_secret_encrypted` on `payment_providers` (default: secrets nulled). |
|
|
453
|
+
| `--skip-extra-tables` | Only pull the curated manifest; omit discovered extra `public.*` base tables. |
|
|
454
|
+
|
|
455
|
+
- **`create_user` / PINs:** Pulled rows set `p_pin: null`; PINs are not recoverable from `auth.users`. To restore deterministic dev PINs after apply, re-run `blt build data <instance>` against the same DB from canonical instance YAML, or edit snapshot rows.
|
|
456
|
+
- **`payment_providers`:** If the table is missing (older schema), pull writes an empty asset file.
|
|
457
|
+
- **Item / group file names:** Splits follow content rules (`props.category` vs first `props.tags[]`), not byte-identical parity with hand-authored multi-file YAML (e.g. pizza menu + toppings in one file).
|
|
458
|
+
- **`blt data remove`:** Deletes **`data-snapshots/<instance>/`** (all stamped runs) under the snapshot base. Use `-o, --out <dir>` to match your pull base (default `data-snapshots`). `--dry-run` prints the path that would be removed.
|
|
459
|
+
|
|
460
|
+
### Commands
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
# Pull (read-only) — writes ./data-snapshots/<instance>/<utc-stamp>/manifest.json + per-asset files
|
|
464
|
+
export BLT_DATA_PULL_URL="postgresql://readonly:...@...:5432/postgres"
|
|
465
|
+
cd /path/to/blt-core-data
|
|
466
|
+
blt data pull laf --format yaml
|
|
467
|
+
blt data pull laf --format toon
|
|
468
|
+
# Prod-safe: omit users / profile_roles junction
|
|
469
|
+
blt data pull prod --skip-users
|
|
470
|
+
# Curated manifest only (no extra public.* dumps)
|
|
471
|
+
blt data pull laf --skip-extra-tables
|
|
472
|
+
|
|
473
|
+
# Replay onto dev (truncates menu-graph targets from manifest, then UPSERT / CALL / SELECT — dev only)
|
|
474
|
+
export BLT_DATA_LOAD_URL="postgresql://...@localhost:5432/postgres"
|
|
475
|
+
blt data apply ./data-snapshots/laf/2026-05-12T12-30-45Z
|
|
476
|
+
|
|
477
|
+
# Inspect generated SQL without executing
|
|
478
|
+
blt data apply ./data-snapshots/laf/2026-05-12T12-30-45Z --dry-run
|
|
479
|
+
|
|
480
|
+
# Remove every stamped snapshot under ./data-snapshots/<instance>/
|
|
481
|
+
blt data remove laf
|
|
482
|
+
blt data remove laf --dry-run
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Snapshots default under `data-snapshots/` from the **current working directory**. The **`data`** git repo ignores `data-snapshots/` so accidental commits of customer data are avoided.
|
|
486
|
+
|
|
487
|
+
### Workflow vs `blt build data`
|
|
488
|
+
|
|
489
|
+
| Path | Direction |
|
|
490
|
+
|------|-----------|
|
|
491
|
+
| `blt build data` + deploy | Git instance YAML → `dist/data.sql` → DB |
|
|
492
|
+
| `blt data pull` → `blt data apply` | Live DB rows → snapshot files → DB (dev replay) |
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
419
496
|
## Init Commands
|
|
420
497
|
|
|
421
498
|
### `blt init [options]`
|
|
@@ -735,6 +812,121 @@ blt show repo --ssh
|
|
|
735
812
|
|
|
736
813
|
---
|
|
737
814
|
|
|
815
|
+
## Spin Commands (DigitalOcean)
|
|
816
|
+
|
|
817
|
+
Manage DigitalOcean droplets and DNS records for BLT test environments. Uses the `blt spin` namespace.
|
|
818
|
+
|
|
819
|
+
**Authentication:** The token is resolved in this order:
|
|
820
|
+
|
|
821
|
+
1. `DIGITALOCEAN_ACCESS_TOKEN` environment variable
|
|
822
|
+
2. `DIGITALOCEAN_TOKEN` environment variable
|
|
823
|
+
3. doctl config file (written by `doctl auth init`)
|
|
824
|
+
|
|
825
|
+
If you've already run `doctl auth init`, no extra env var setup is needed.
|
|
826
|
+
|
|
827
|
+
### `blt spin up`
|
|
828
|
+
|
|
829
|
+
Create a new droplet. Waits for the droplet to become active and reports its IP.
|
|
830
|
+
|
|
831
|
+
```bash
|
|
832
|
+
blt spin up --name test-laf --ssh-keys 12345678
|
|
833
|
+
blt spin up --name test-laf --size s-1vcpu-1gb --region nyc3 --image ubuntu-24-04-x64 --tag blt
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
**Options:**
|
|
837
|
+
|
|
838
|
+
- `--name <name>` — Droplet name (required)
|
|
839
|
+
- `--size <size>` — Droplet size slug (default: `s-1vcpu-512mb-10gb`)
|
|
840
|
+
- `--region <region>` — Region slug (default: `nyc3`)
|
|
841
|
+
- `--image <image>` — OS image slug (default: `ubuntu-24-04-x64`)
|
|
842
|
+
- `--ssh-keys <keys>` — Comma-separated SSH key IDs or fingerprints
|
|
843
|
+
- `--tag <tag>` — Tag for the droplet (default: `blt`)
|
|
844
|
+
|
|
845
|
+
### `blt spin down <name>`
|
|
846
|
+
|
|
847
|
+
Destroy a droplet. Prompts for confirmation unless `--force` is passed.
|
|
848
|
+
|
|
849
|
+
```bash
|
|
850
|
+
blt spin down test-laf
|
|
851
|
+
blt spin down test-laf --force
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
**Options:**
|
|
855
|
+
|
|
856
|
+
- `--force` — Skip confirmation prompt
|
|
857
|
+
|
|
858
|
+
### `blt spin list`
|
|
859
|
+
|
|
860
|
+
List droplets filtered by tag.
|
|
861
|
+
|
|
862
|
+
```bash
|
|
863
|
+
blt spin list
|
|
864
|
+
blt spin list --tag staging
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
**Options:**
|
|
868
|
+
|
|
869
|
+
- `--tag <tag>` — Filter by tag (default: `blt`)
|
|
870
|
+
|
|
871
|
+
### `blt spin status <name>`
|
|
872
|
+
|
|
873
|
+
Show detailed information about a droplet.
|
|
874
|
+
|
|
875
|
+
```bash
|
|
876
|
+
blt spin status test-laf
|
|
877
|
+
blt spin status 12345678
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
### `blt spin ssh <name>`
|
|
881
|
+
|
|
882
|
+
SSH into a droplet. Resolves the droplet's public IP and opens an interactive SSH session.
|
|
883
|
+
|
|
884
|
+
```bash
|
|
885
|
+
blt spin ssh test-laf
|
|
886
|
+
blt spin ssh test-laf --user root
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
**Options:**
|
|
890
|
+
|
|
891
|
+
- `--user <user>` — SSH user (default: `blt`)
|
|
892
|
+
|
|
893
|
+
### `blt spin dns <action>`
|
|
894
|
+
|
|
895
|
+
Manage DNS records for a domain.
|
|
896
|
+
|
|
897
|
+
```bash
|
|
898
|
+
# Create an A record
|
|
899
|
+
blt spin dns create --domain bltcore.com --name test-laf --ip 1.2.3.4
|
|
900
|
+
|
|
901
|
+
# List all DNS records
|
|
902
|
+
blt spin dns list --domain bltcore.com
|
|
903
|
+
|
|
904
|
+
# Delete a record by ID
|
|
905
|
+
blt spin dns delete --domain bltcore.com --record-id 12345678
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
**Options:**
|
|
909
|
+
|
|
910
|
+
- `--domain <domain>` — Domain name (default: `bltcore.com`)
|
|
911
|
+
- `--name <name>` — Record name / subdomain (for create)
|
|
912
|
+
- `--ip <ip>` — IP address for A record (for create)
|
|
913
|
+
- `--record-id <id>` — Record ID (for delete)
|
|
914
|
+
|
|
915
|
+
### `blt spin setup <name>`
|
|
916
|
+
|
|
917
|
+
Bootstrap a fresh droplet by uploading and running `deploy/scripts/bootstrap-droplet.sh`. If the script doesn't exist, prints what would run.
|
|
918
|
+
|
|
919
|
+
```bash
|
|
920
|
+
blt spin setup test-laf
|
|
921
|
+
blt spin setup test-laf --user root
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
**Options:**
|
|
925
|
+
|
|
926
|
+
- `--user <user>` — SSH user for bootstrap (default: `root`)
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
738
930
|
## Env Commands
|
|
739
931
|
|
|
740
932
|
### `blt env get <name>`
|
package/dist/blt
CHANGED
|
@@ -13,6 +13,8 @@ import workflowCommand from "./commands/workflow";
|
|
|
13
13
|
import waiCommand from "./commands/wai";
|
|
14
14
|
import templateCommand from "./commands/template";
|
|
15
15
|
import envCommand from "./commands/env";
|
|
16
|
+
import dataCommand from "./commands/data";
|
|
17
|
+
import spinCommand from "./commands/spin";
|
|
16
18
|
import { join, dirname } from "node:path";
|
|
17
19
|
import { readFileSync } from "node:fs";
|
|
18
20
|
import { fileURLToPath } from "node:url";
|
|
@@ -39,6 +41,8 @@ workflowCommand(program);
|
|
|
39
41
|
waiCommand(program);
|
|
40
42
|
templateCommand(program);
|
|
41
43
|
envCommand(program);
|
|
44
|
+
dataCommand(program);
|
|
45
|
+
spinCommand(program);
|
|
42
46
|
// If no command is provided, show help
|
|
43
47
|
const args = process.argv.slice(2);
|
|
44
48
|
if (args.length === 0) {
|
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":";AA0BA,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,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAC5C,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAC5C,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,cAAc,MAAM,oBAAoB,CAAC;AAChD,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,cAAc,MAAM,oBAAoB,CAAC;AAChD,OAAO,eAAe,MAAM,qBAAqB,CAAC;AAClD,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,eAAe,MAAM,qBAAqB,CAAC;AAClD,OAAO,UAAU,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"blt.js","sourceRoot":"","sources":["../src/blt.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAC5C,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAC5C,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,cAAc,MAAM,oBAAoB,CAAC;AAChD,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,cAAc,MAAM,oBAAoB,CAAC;AAChD,OAAO,eAAe,MAAM,qBAAqB,CAAC;AAClD,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,eAAe,MAAM,qBAAqB,CAAC;AAClD,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAE1C,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,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,WAAW,CAAC,OAAO,CAAC,CAAC;AAEvB,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 @@
|
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/commands/data/apply.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAc5C,MAAM,MAAM,aAAa,GAAG;IAC3B,MAAM,EAAE,OAAO,CAAC;CAChB,CAAC;AAoNF,wBAAsB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2NvG"}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import yaml from "js-yaml";
|
|
4
|
+
import { decode } from "@toon-format/toon";
|
|
5
|
+
import pg from "pg";
|
|
6
|
+
import { fetchPublicTableColumnUdts, fetchPublicTableGeneratedStoredColumnNames, fetchPublicTableIdentityAlwaysColumns } from "../../lib/data-pull-extra-tables";
|
|
7
|
+
import { getLoadConnectionString, runSqlContent } from "../../lib/database-runner";
|
|
8
|
+
import { jsonToSql, processEnvVars } from "../../lib/yaml-converter";
|
|
9
|
+
import { getApplyTruncateSqlForManifest, sortManifestAssetsForApply, } from "../../lib/data-pull-manifest";
|
|
10
|
+
function readPayload(path, logger) {
|
|
11
|
+
const raw = readFileSync(path, "utf8");
|
|
12
|
+
if (path.endsWith(".toon")) {
|
|
13
|
+
try {
|
|
14
|
+
return decode(raw);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
18
|
+
logger.error(`Failed to parse TOON: ${path} — ${msg}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (path.endsWith(".yaml") || path.endsWith(".yml")) {
|
|
23
|
+
try {
|
|
24
|
+
return yaml.load(raw);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
28
|
+
logger.error(`Failed to parse YAML: ${path} — ${msg}`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(raw);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
37
|
+
logger.error(`Failed to parse JSON: ${path} — ${msg}`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function prepareRows(rows) {
|
|
42
|
+
return rows.map((r) => ({
|
|
43
|
+
row: processEnvVars(r.row),
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
function resolveSqlType(payload, asset) {
|
|
47
|
+
return payload.sqlType ?? asset.sqlType ?? "function";
|
|
48
|
+
}
|
|
49
|
+
/** Curated assets use bare names; extra-table dumps use `public.table`. */
|
|
50
|
+
function publicTableFromSnapshotTarget(target) {
|
|
51
|
+
if (!target.startsWith("public."))
|
|
52
|
+
return undefined;
|
|
53
|
+
const rest = target.slice("public.".length);
|
|
54
|
+
return rest.length > 0 ? rest : undefined;
|
|
55
|
+
}
|
|
56
|
+
/** Map snapshot auth.users id → email from create_user asset (for settings FK repair). */
|
|
57
|
+
function loadCreateUserAuthIdToEmail(snapshotDir, manifest, logger) {
|
|
58
|
+
const m = new Map();
|
|
59
|
+
const asset = manifest.assets.find((a) => a.function === "create_user");
|
|
60
|
+
if (!asset)
|
|
61
|
+
return m;
|
|
62
|
+
const payload = readPayload(join(snapshotDir, asset.file), logger);
|
|
63
|
+
for (const pr of payload.rows || []) {
|
|
64
|
+
const row = processEnvVars((pr.row ?? {}));
|
|
65
|
+
const email = row.p_email;
|
|
66
|
+
const aid = row.p_authid;
|
|
67
|
+
if (typeof email === "string" && typeof aid === "string" && aid.length > 0) {
|
|
68
|
+
m.set(aid, email);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return m;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* When target DB already had auth.users for an email, create_user reuses that row's id while
|
|
75
|
+
* settings rows still carry source UUIDs — replace with a subselect by email so FK holds.
|
|
76
|
+
*/
|
|
77
|
+
function rewriteSettingsAuthidForApply(rows, authidToEmail) {
|
|
78
|
+
if (authidToEmail.size === 0)
|
|
79
|
+
return rows;
|
|
80
|
+
return rows.map(({ row }) => {
|
|
81
|
+
const authid = row.authid;
|
|
82
|
+
if (typeof authid !== "string")
|
|
83
|
+
return { row };
|
|
84
|
+
const email = authidToEmail.get(authid);
|
|
85
|
+
if (!email)
|
|
86
|
+
return { row };
|
|
87
|
+
return {
|
|
88
|
+
row: {
|
|
89
|
+
...row,
|
|
90
|
+
authid: { __blt_auth_users_id_by_email: email },
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* `audit.changed_by` FK targets `users` (typically `auth.users` ids). Same cross-env issue as
|
|
97
|
+
* `settings.authid`: emit `(SELECT id FROM auth.users WHERE email = …)` when the snapshot has a
|
|
98
|
+
* matching `create_user` row; otherwise NULL so apply does not reference missing users.
|
|
99
|
+
*/
|
|
100
|
+
function rewriteAuditChangedByForApply(rows, authidToEmail) {
|
|
101
|
+
return rows.map(({ row }) => {
|
|
102
|
+
const changedBy = row.changed_by;
|
|
103
|
+
if (changedBy === null || changedBy === undefined)
|
|
104
|
+
return { row };
|
|
105
|
+
if (typeof changedBy !== "string")
|
|
106
|
+
return { row };
|
|
107
|
+
const email = authidToEmail.get(changedBy);
|
|
108
|
+
if (email) {
|
|
109
|
+
return {
|
|
110
|
+
row: {
|
|
111
|
+
...row,
|
|
112
|
+
changed_by: { __blt_auth_users_id_by_email: email },
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return { row: { ...row, changed_by: null } };
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* `pins.authid` FK to `users` (same ids as `auth.users`). Remap like `audit.changed_by`: subselect
|
|
121
|
+
* by email when we have a `create_user` row; otherwise NULL so apply does not reference missing users.
|
|
122
|
+
*/
|
|
123
|
+
function rewritePinsAuthidForApply(rows, authidToEmail) {
|
|
124
|
+
return rows.map(({ row }) => {
|
|
125
|
+
const authid = row.authid;
|
|
126
|
+
if (authid === null || authid === undefined)
|
|
127
|
+
return { row };
|
|
128
|
+
if (typeof authid !== "string")
|
|
129
|
+
return { row };
|
|
130
|
+
const email = authidToEmail.get(authid);
|
|
131
|
+
if (email) {
|
|
132
|
+
return {
|
|
133
|
+
row: {
|
|
134
|
+
...row,
|
|
135
|
+
authid: { __blt_auth_users_id_by_email: email },
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
return { row: { ...row, authid: null } };
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/** True when the nodes snapshot carries source UUIDs (required for `devices.node_id` FK). */
|
|
143
|
+
function checkNodesSnapshotHasStableIds(snapshotDir, manifest, logger) {
|
|
144
|
+
const asset = manifest.assets.find((a) => a.function === "nodes");
|
|
145
|
+
if (!asset)
|
|
146
|
+
return false;
|
|
147
|
+
const filePath = join(snapshotDir, asset.file);
|
|
148
|
+
if (!existsSync(filePath))
|
|
149
|
+
return false;
|
|
150
|
+
const payload = readPayload(filePath, logger);
|
|
151
|
+
const first = payload.rows?.[0]?.row;
|
|
152
|
+
const id = first?.id;
|
|
153
|
+
return typeof id === "string" && id.length > 0;
|
|
154
|
+
}
|
|
155
|
+
/** Legacy pulls omitted `nodes.id`, so target inserts get new UUIDs while `devices` still hold source ids. */
|
|
156
|
+
function nullDevicesNodeIdWhenNodesLackIds(rows) {
|
|
157
|
+
return rows.map(({ row }) => {
|
|
158
|
+
if (!Object.prototype.hasOwnProperty.call(row, "node_id"))
|
|
159
|
+
return { row };
|
|
160
|
+
return { row: { ...row, node_id: null } };
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/** Snapshot row set includes any column that is GENERATED ALWAYS AS IDENTITY on the target. */
|
|
164
|
+
function preparedTouchesIdentityAlwaysColumns(prepared, identityAlways) {
|
|
165
|
+
if (identityAlways.length === 0)
|
|
166
|
+
return false;
|
|
167
|
+
const idSet = new Set(identityAlways);
|
|
168
|
+
for (const pr of prepared) {
|
|
169
|
+
for (const k of Object.keys(pr.row)) {
|
|
170
|
+
if (idSet.has(k))
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
/** Remove stored-generated columns from rows — Postgres rejects explicit values for them on INSERT/UPSERT. */
|
|
177
|
+
function stripGeneratedStoredColumnsFromPrepared(prepared, generatedCols) {
|
|
178
|
+
if (generatedCols.length === 0)
|
|
179
|
+
return prepared;
|
|
180
|
+
const drop = new Set(generatedCols);
|
|
181
|
+
return prepared.map(({ row }) => {
|
|
182
|
+
const next = { ...row };
|
|
183
|
+
for (const c of drop)
|
|
184
|
+
delete next[c];
|
|
185
|
+
return { row: next };
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export async function dataApply(snapshotDir, opts, logger) {
|
|
189
|
+
const mf = join(snapshotDir, "manifest.json");
|
|
190
|
+
if (!existsSync(mf)) {
|
|
191
|
+
logger.error(`manifest.json not found under: ${snapshotDir}`);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
let manifest;
|
|
195
|
+
try {
|
|
196
|
+
manifest = JSON.parse(readFileSync(mf, "utf8"));
|
|
197
|
+
}
|
|
198
|
+
catch (e) {
|
|
199
|
+
logger.error(`Invalid manifest.json: ${e instanceof Error ? e.message : String(e)}`);
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
const sqlParts = [
|
|
203
|
+
`-- BLT snapshot apply — instance ${manifest.instance} pulled ${manifest.pulledAt}`,
|
|
204
|
+
`SET search_path = public, auth, extensions;`,
|
|
205
|
+
``,
|
|
206
|
+
];
|
|
207
|
+
const orderedAssets = sortManifestAssetsForApply(manifest.assets);
|
|
208
|
+
const authidToEmail = loadCreateUserAuthIdToEmail(snapshotDir, manifest, logger);
|
|
209
|
+
const nodesSnapshotHasStableIds = checkNodesSnapshotHasStableIds(snapshotDir, manifest, logger);
|
|
210
|
+
if (!nodesSnapshotHasStableIds &&
|
|
211
|
+
orderedAssets.some((a) => a.function === "public.devices")) {
|
|
212
|
+
logger.warn("Snapshot `nodes` has no `id` column (legacy pull). Clearing `public.devices.node_id` for apply; re-pull with current CLI to keep device→node links.");
|
|
213
|
+
}
|
|
214
|
+
const truncateSql = getApplyTruncateSqlForManifest(orderedAssets);
|
|
215
|
+
if (truncateSql)
|
|
216
|
+
sqlParts.push(truncateSql);
|
|
217
|
+
const url = opts.dryRun ? "" : getLoadConnectionString();
|
|
218
|
+
let metaClient = null;
|
|
219
|
+
const udtCache = new Map();
|
|
220
|
+
const identityAlwaysCache = new Map();
|
|
221
|
+
const generatedStoredCache = new Map();
|
|
222
|
+
if (!opts.dryRun) {
|
|
223
|
+
metaClient = new pg.Client({ connectionString: url });
|
|
224
|
+
await metaClient.connect();
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
for (const asset of orderedAssets) {
|
|
228
|
+
const filePath = join(snapshotDir, asset.file);
|
|
229
|
+
if (!existsSync(filePath)) {
|
|
230
|
+
logger.error(`Missing asset file referenced in manifest: ${filePath}`);
|
|
231
|
+
process.exit(1);
|
|
232
|
+
}
|
|
233
|
+
const payload = readPayload(filePath, logger);
|
|
234
|
+
if (payload.function !== asset.function) {
|
|
235
|
+
logger.error(`Target mismatch for ${asset.id}: manifest=${asset.function} file=${payload.function}`);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
let prepared = prepareRows(payload.rows || []);
|
|
239
|
+
if (asset.function === "settings" && authidToEmail.size > 0) {
|
|
240
|
+
prepared = rewriteSettingsAuthidForApply(prepared, authidToEmail);
|
|
241
|
+
}
|
|
242
|
+
if (asset.function === "public.audit") {
|
|
243
|
+
prepared = rewriteAuditChangedByForApply(prepared, authidToEmail);
|
|
244
|
+
}
|
|
245
|
+
if (asset.function === "public.pins") {
|
|
246
|
+
prepared = rewritePinsAuthidForApply(prepared, authidToEmail);
|
|
247
|
+
}
|
|
248
|
+
if (asset.function === "public.devices" && !nodesSnapshotHasStableIds) {
|
|
249
|
+
prepared = nullDevicesNodeIdWhenNodesLackIds(prepared);
|
|
250
|
+
}
|
|
251
|
+
if (prepared.length === 0) {
|
|
252
|
+
sqlParts.push(`-- skip ${asset.id} (no rows)`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
const sqlType = resolveSqlType(payload, asset);
|
|
256
|
+
let columnUdts = payload.columnUdts && Object.keys(payload.columnUdts).length > 0
|
|
257
|
+
? payload.columnUdts
|
|
258
|
+
: undefined;
|
|
259
|
+
if (sqlType === "table" &&
|
|
260
|
+
metaClient &&
|
|
261
|
+
(!columnUdts || Object.keys(columnUdts).length === 0)) {
|
|
262
|
+
const pubTable = publicTableFromSnapshotTarget(payload.function);
|
|
263
|
+
if (pubTable) {
|
|
264
|
+
if (!udtCache.has(pubTable)) {
|
|
265
|
+
udtCache.set(pubTable, await fetchPublicTableColumnUdts(metaClient, pubTable));
|
|
266
|
+
}
|
|
267
|
+
columnUdts = udtCache.get(pubTable);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
const pubTable = sqlType === "table" ? publicTableFromSnapshotTarget(payload.function) : undefined;
|
|
271
|
+
if (metaClient && pubTable) {
|
|
272
|
+
if (!identityAlwaysCache.has(pubTable)) {
|
|
273
|
+
identityAlwaysCache.set(pubTable, await fetchPublicTableIdentityAlwaysColumns(metaClient, pubTable));
|
|
274
|
+
}
|
|
275
|
+
if (!generatedStoredCache.has(pubTable)) {
|
|
276
|
+
generatedStoredCache.set(pubTable, await fetchPublicTableGeneratedStoredColumnNames(metaClient, pubTable));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const identityAlwaysCols = pubTable ? (identityAlwaysCache.get(pubTable) ?? []) : [];
|
|
280
|
+
const generatedStoredCols = pubTable ? (generatedStoredCache.get(pubTable) ?? []) : [];
|
|
281
|
+
if (generatedStoredCols.length > 0) {
|
|
282
|
+
prepared = stripGeneratedStoredColumnsFromPrepared(prepared, generatedStoredCols);
|
|
283
|
+
}
|
|
284
|
+
const isPaymentProviders = payload.function === "payment_providers";
|
|
285
|
+
/** Older node snapshots upserted on `id` but DBs often have `UNIQUE (node_code)` — 23505 when codes collide. */
|
|
286
|
+
const nodesLegacyUpsert = payload.function === "nodes" &&
|
|
287
|
+
sqlType === "table" &&
|
|
288
|
+
(!payload.primaryKey?.length ||
|
|
289
|
+
(payload.primaryKey.length === 1 && payload.primaryKey[0] === "id"));
|
|
290
|
+
const excludeFromConflictUpdateMerged = [
|
|
291
|
+
...(payload.conflictUpdateExclude ?? []),
|
|
292
|
+
...(isPaymentProviders ? ["id"] : []),
|
|
293
|
+
...(nodesLegacyUpsert && !(payload.conflictUpdateExclude ?? []).includes("id") ? ["id"] : []),
|
|
294
|
+
...identityAlwaysCols,
|
|
295
|
+
...generatedStoredCols,
|
|
296
|
+
];
|
|
297
|
+
const excludeForUpsert = excludeFromConflictUpdateMerged.length > 0 ? excludeFromConflictUpdateMerged : undefined;
|
|
298
|
+
let fragment;
|
|
299
|
+
if (payload.function === "payment_providers" && !payload.conflictWhere) {
|
|
300
|
+
const globalRows = prepared.filter((r) => r.row.location_id === null || r.row.location_id === undefined);
|
|
301
|
+
const scopedRows = prepared.filter((r) => r.row.location_id !== null && r.row.location_id !== undefined);
|
|
302
|
+
const chunks = [];
|
|
303
|
+
if (globalRows.length > 0) {
|
|
304
|
+
chunks.push(jsonToSql(globalRows, "payment_providers", sqlType, {
|
|
305
|
+
conflictColumns: ["provider_type"],
|
|
306
|
+
conflictWhere: "location_id IS NULL",
|
|
307
|
+
excludeFromConflictUpdate: excludeForUpsert,
|
|
308
|
+
columnUdts,
|
|
309
|
+
overridingSystemValue: preparedTouchesIdentityAlwaysColumns(globalRows, identityAlwaysCols),
|
|
310
|
+
}));
|
|
311
|
+
}
|
|
312
|
+
if (scopedRows.length > 0) {
|
|
313
|
+
chunks.push(jsonToSql(scopedRows, "payment_providers", sqlType, {
|
|
314
|
+
conflictColumns: ["id"],
|
|
315
|
+
excludeFromConflictUpdate: excludeForUpsert,
|
|
316
|
+
columnUdts,
|
|
317
|
+
overridingSystemValue: preparedTouchesIdentityAlwaysColumns(scopedRows, identityAlwaysCols),
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
fragment = chunks.join("\n\n");
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
fragment = jsonToSql(prepared, payload.function, sqlType, {
|
|
324
|
+
conflictColumns: nodesLegacyUpsert
|
|
325
|
+
? ["node_code"]
|
|
326
|
+
: (payload.primaryKey ?? (isPaymentProviders ? ["provider_type"] : undefined)),
|
|
327
|
+
excludeFromConflictUpdate: excludeForUpsert,
|
|
328
|
+
conflictWhere: payload.conflictWhere,
|
|
329
|
+
columnUdts,
|
|
330
|
+
overridingSystemValue: preparedTouchesIdentityAlwaysColumns(prepared, identityAlwaysCols),
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
sqlParts.push(`-- ${payload.assetId} (${prepared.length} rows, ${sqlType})`);
|
|
334
|
+
sqlParts.push(fragment);
|
|
335
|
+
if (asset.function === "public.audit" && sqlType === "table") {
|
|
336
|
+
sqlParts.push([
|
|
337
|
+
"-- Resync audit.id sequence after bulk restore (triggers use nextval; without this, duplicate audit_pkey)",
|
|
338
|
+
"SELECT setval(",
|
|
339
|
+
" pg_get_serial_sequence('public.audit', 'id'),",
|
|
340
|
+
" COALESCE((SELECT MAX(id) FROM public.audit), 1)",
|
|
341
|
+
");",
|
|
342
|
+
].join("\n"));
|
|
343
|
+
}
|
|
344
|
+
sqlParts.push(``);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
finally {
|
|
348
|
+
if (metaClient) {
|
|
349
|
+
await metaClient.end();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
const bundled = sqlParts.join("\n");
|
|
353
|
+
if (opts.dryRun) {
|
|
354
|
+
console.log(bundled);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
await runSqlContent(bundled, {
|
|
358
|
+
name: `snapshot:${manifest.instance}`,
|
|
359
|
+
path: snapshotDir,
|
|
360
|
+
version: "unknown",
|
|
361
|
+
}, url);
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/commands/data/apply.ts"],"names":[],"mappings":"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"}
|