@carllee1983/dbcli 1.41.0 → 1.42.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/rules/dbcli.mdc +1 -1
- package/.cursor/skills/dbcli/reference.md +59 -4
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/skills/dbcli/SKILL.md +1 -1
- package/.github/skills/dbcli/reference.md +59 -4
- package/CHANGELOG.md +17 -0
- package/assets/SKILL.md +1 -1
- package/assets/SKILL.zh-TW.md +1 -1
- package/assets/reference.md +59 -4
- package/dist/cli.mjs +1141 -11448
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
- package/plugins/dbcli-agent/skills/dbcli/SKILL.md +1 -1
- package/plugins/dbcli-agent/skills/dbcli/reference.md +59 -4
- package/skills/dbcli/SKILL.md +1 -1
- package/skills/dbcli/reference.md +59 -4
package/.cursor/rules/dbcli.mdc
CHANGED
|
@@ -307,7 +307,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
|
|
|
307
307
|
| `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. Supports `--recovery`. |
|
|
308
308
|
| `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
|
|
309
309
|
| `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
|
|
310
|
-
| `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json`, `--ignore <globs>`, `--format json\|table\|markdown`. |
|
|
310
|
+
| `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize`, `--ignore <globs>`, `--format json\|table\|markdown`. Drizzle: point at `drizzle/meta/<NNNN>_snapshot.json` (run `drizzle-kit generate` first; `.ts` sources are rejected with a hint). TypeORM/Sequelize: feed tool-generated DDL (`schema:log` / a schema-only dump); source files are rejected with the exact generation command to run. |
|
|
311
311
|
| `snapshot` | query-only+ | **(v1.25)** SQL only. Capture a result fingerprint (`rowCount` + per-column null/distinct/min/max/sum + order-independent checksum). `--out` (default `.dbcli/snapshots/snap-<ts>.json`), `--rows`, `--stdout`, `--format`, `--no-limit`. Baseline for `assert --against`. |
|
|
312
312
|
| `assert` | query-only+ | **(v1.25)** SQL only. Verify an invariant; exit 1 on failure unless `--no-fail`. `--expect "rows>0\|value==X\|col:c not null\|unique\|between a and b\|>= n"`, `--vs <query> --compare rows\|value` (reconcile), `--against <snapshot> --tolerance <pct>`. |
|
|
313
313
|
| `verification` | n/a | Inspect and manage local verification artifacts. `list` / `show <id-or-path>` / `summary` are read-only; `prune` is dry-run by default and deletes only with `--execute --force`. Reads `<cwd>/.dbcli/verification/`; no DB connection, no audit writes. |
|
|
@@ -722,6 +722,10 @@ separate `--snapshot` / `--against` workflow.
|
|
|
722
722
|
dbcli diff --against-orm prisma/schema.prisma --format json
|
|
723
723
|
dbcli diff --against-orm schema.normalized.json --orm-format json --format table
|
|
724
724
|
|
|
725
|
+
# Drizzle requires a PostgreSQL drizzle-kit v7 snapshot (generate it first)
|
|
726
|
+
drizzle-kit generate
|
|
727
|
+
dbcli diff --against-orm drizzle/meta/0001_snapshot.json --orm-format drizzle --format table
|
|
728
|
+
|
|
725
729
|
# DDL accepts repeatable or comma-separated paths and real filesystem globs
|
|
726
730
|
dbcli diff --against-orm "migrations/*.sql" --format markdown
|
|
727
731
|
dbcli diff --against-orm migrations/base.sql,migrations/accounts.sql \
|
|
@@ -731,11 +735,60 @@ dbcli diff --against-orm migrations/base.sql,migrations/accounts.sql \
|
|
|
731
735
|
dbcli diff --against-orm prisma/schema.prisma --ignore 'public.audit_*,public.Legacy'
|
|
732
736
|
```
|
|
733
737
|
|
|
738
|
+
##### TypeORM
|
|
739
|
+
|
|
740
|
+
TypeORM entities are not parsed directly. `schema:log` prints the SQL that
|
|
741
|
+
`schema:sync` would execute without applying it; `-d` is the required data-source
|
|
742
|
+
path. Generate that DDL, then select the `typeorm` alias so the report is tagged
|
|
743
|
+
`ormSource: typeorm`:
|
|
744
|
+
|
|
745
|
+
```bash
|
|
746
|
+
bunx typeorm schema:log -d <path/to/datasource> > schema.sql
|
|
747
|
+
dbcli diff --against-orm schema.sql --orm-format typeorm --format table
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
With `--orm-format typeorm`, `typeorm_metadata` and `migrations` are
|
|
751
|
+
default-ignored and appear as `unmanaged` rather than scored drift. Passing a
|
|
752
|
+
TypeORM `.ts`, `.js`, `.mjs`, or `.cjs` source file is rejected with the
|
|
753
|
+
`schema:log` command to run. See the
|
|
754
|
+
[TypeORM CLI documentation](https://typeorm.io/docs/using-cli) and
|
|
755
|
+
[`SchemaLogCommand`](https://github.com/typeorm/typeorm/blob/master/src/commands/SchemaLogCommand.ts).
|
|
756
|
+
|
|
757
|
+
##### Sequelize
|
|
758
|
+
|
|
759
|
+
Sequelize CLI does not provide a universal `db:migrate --dry-run`. Point the
|
|
760
|
+
project's existing Sequelize configuration at an empty scratch database, apply
|
|
761
|
+
the migrations there, and dump definitions without row data:
|
|
762
|
+
|
|
763
|
+
```bash
|
|
764
|
+
# Configure Sequelize for an empty scratch database first
|
|
765
|
+
bunx sequelize-cli db:migrate
|
|
766
|
+
|
|
767
|
+
# PostgreSQL scratch database
|
|
768
|
+
pg_dump --schema-only <scratch-database> > schema.sql
|
|
769
|
+
|
|
770
|
+
# MySQL scratch database
|
|
771
|
+
mysqldump --no-data <database> > schema.sql
|
|
772
|
+
|
|
773
|
+
dbcli diff --against-orm schema.sql --orm-format sequelize --format json
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
With `--orm-format sequelize`, `SequelizeMeta` is default-ignored and appears as
|
|
777
|
+
`unmanaged` rather than scored drift. Passing a Sequelize `.ts`, `.js`, `.mjs`,
|
|
778
|
+
or `.cjs` model file is rejected with the scratch-database and schema-only dump
|
|
779
|
+
recipe. See the
|
|
780
|
+
[Sequelize CLI migration command](https://github.com/sequelize/cli/blob/main/src/commands/migrate.js),
|
|
781
|
+
[PostgreSQL `pg_dump`](https://www.postgresql.org/docs/current/app-pgdump.html),
|
|
782
|
+
and [MySQL `mysqldump`](https://dev.mysql.com/doc/refman/8.4/en/mysqldump-definition-data-dumps.html)
|
|
783
|
+
references.
|
|
784
|
+
|
|
734
785
|
| Option | Behavior |
|
|
735
786
|
| :--- | :--- |
|
|
736
|
-
| `--against-orm <paths>` | Repeatable or comma-separated input. DDL inputs support real filesystem globs; matches are deduplicated and put in deterministic path order, then parsed as one shared ordered context so an index in a later file can attach to a table declared in an earlier file. Prisma
|
|
737
|
-
|
|
|
738
|
-
|
|
|
787
|
+
| `--against-orm <paths>` | Repeatable or comma-separated input. DDL-family inputs (raw DDL, TypeORM, and Sequelize) support real filesystem globs; matches are deduplicated and put in deterministic path order, then parsed as one shared ordered context so an index in a later file can attach to a table declared in an earlier file. Prisma, normalized JSON, and Drizzle accept exactly one file, and globs are rejected for those formats. |
|
|
788
|
+
| Drizzle input | Run `drizzle-kit generate`, then pass the PostgreSQL drizzle-kit v7 snapshot at `drizzle/meta/<NNNN>_snapshot.json`. TypeScript ORM schema sources (`.ts` or `.TS`) are rejected with that snapshot-generation hint; dbcli does not parse them directly. |
|
|
789
|
+
| TypeORM / Sequelize input | Generate DDL with the ORM/database tooling, then pass the SQL file with the matching `typeorm` or `sequelize` alias. Entity/model source files are rejected rather than parsed. |
|
|
790
|
+
| `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize` | Override extension/content detection. The `typeorm` and `sequelize` aliases use the DDL adapter while preserving the source tag and ORM-specific default ignores. Without an override, dbcli detects Prisma, raw DDL, normalized JSON, or a Drizzle snapshot from the path and content. |
|
|
791
|
+
| `--ignore <globs>` | Comma-separated, case-sensitive table globs. Patterns match the qualified display identity (for example `public.Users`). `_prisma_migrations` is always unmanaged; the TypeORM alias additionally ignores `typeorm_metadata` and `migrations`, and the Sequelize alias additionally ignores `SequelizeMeta`. |
|
|
739
792
|
| `--format json\|table\|markdown` | Select machine JSON, human table, or Markdown output. Markdown is available only in ORM drift mode. |
|
|
740
793
|
| `--recovery` | On an I/O, configuration, empty-cache, invalid-format, or unsupported-engine failure, emit and save a structured recovery envelope. Invalid Prisma/DDL constructs normally become `unparsed` entries instead of throwing. |
|
|
741
794
|
|
|
@@ -783,9 +836,11 @@ another.
|
|
|
783
836
|
columns, multi-schema datasource configuration, malformed declarations, unknown
|
|
784
837
|
attributes, and unsupported native mappings are never guessed.
|
|
785
838
|
|
|
786
|
-
Prisma and
|
|
839
|
+
Prisma, DDL, and Drizzle constructs outside the supported subset are retained in
|
|
787
840
|
`unparsed` with a `blocked:` reason. These entries are separate from scored drift:
|
|
788
841
|
inspect and resolve them before treating an otherwise clean summary as complete.
|
|
842
|
+
Drizzle enums and other unsupported snapshot constructs therefore appear as blocked
|
|
843
|
+
`unparsed` entries rather than managed tables or columns.
|
|
789
844
|
Multi-file DDL is consumed as one deterministic shared ordered statement context,
|
|
790
845
|
so later `CREATE INDEX` statements can reference tables declared in earlier
|
|
791
846
|
files. PostgreSQL `PARTITION BY` and MySQL/MariaDB table engine, charset, and
|
|
@@ -307,7 +307,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
|
|
|
307
307
|
| `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. Supports `--recovery`. |
|
|
308
308
|
| `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
|
|
309
309
|
| `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
|
|
310
|
-
| `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json`, `--ignore <globs>`, `--format json\|table\|markdown`. |
|
|
310
|
+
| `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize`, `--ignore <globs>`, `--format json\|table\|markdown`. Drizzle: point at `drizzle/meta/<NNNN>_snapshot.json` (run `drizzle-kit generate` first; `.ts` sources are rejected with a hint). TypeORM/Sequelize: feed tool-generated DDL (`schema:log` / a schema-only dump); source files are rejected with the exact generation command to run. |
|
|
311
311
|
| `snapshot` | query-only+ | **(v1.25)** SQL only. Capture a result fingerprint (`rowCount` + per-column null/distinct/min/max/sum + order-independent checksum). `--out` (default `.dbcli/snapshots/snap-<ts>.json`), `--rows`, `--stdout`, `--format`, `--no-limit`. Baseline for `assert --against`. |
|
|
312
312
|
| `assert` | query-only+ | **(v1.25)** SQL only. Verify an invariant; exit 1 on failure unless `--no-fail`. `--expect "rows>0\|value==X\|col:c not null\|unique\|between a and b\|>= n"`, `--vs <query> --compare rows\|value` (reconcile), `--against <snapshot> --tolerance <pct>`. |
|
|
313
313
|
| `verification` | n/a | Inspect and manage local verification artifacts. `list` / `show <id-or-path>` / `summary` are read-only; `prune` is dry-run by default and deletes only with `--execute --force`. Reads `<cwd>/.dbcli/verification/`; no DB connection, no audit writes. |
|
|
@@ -722,6 +722,10 @@ separate `--snapshot` / `--against` workflow.
|
|
|
722
722
|
dbcli diff --against-orm prisma/schema.prisma --format json
|
|
723
723
|
dbcli diff --against-orm schema.normalized.json --orm-format json --format table
|
|
724
724
|
|
|
725
|
+
# Drizzle requires a PostgreSQL drizzle-kit v7 snapshot (generate it first)
|
|
726
|
+
drizzle-kit generate
|
|
727
|
+
dbcli diff --against-orm drizzle/meta/0001_snapshot.json --orm-format drizzle --format table
|
|
728
|
+
|
|
725
729
|
# DDL accepts repeatable or comma-separated paths and real filesystem globs
|
|
726
730
|
dbcli diff --against-orm "migrations/*.sql" --format markdown
|
|
727
731
|
dbcli diff --against-orm migrations/base.sql,migrations/accounts.sql \
|
|
@@ -731,11 +735,60 @@ dbcli diff --against-orm migrations/base.sql,migrations/accounts.sql \
|
|
|
731
735
|
dbcli diff --against-orm prisma/schema.prisma --ignore 'public.audit_*,public.Legacy'
|
|
732
736
|
```
|
|
733
737
|
|
|
738
|
+
##### TypeORM
|
|
739
|
+
|
|
740
|
+
TypeORM entities are not parsed directly. `schema:log` prints the SQL that
|
|
741
|
+
`schema:sync` would execute without applying it; `-d` is the required data-source
|
|
742
|
+
path. Generate that DDL, then select the `typeorm` alias so the report is tagged
|
|
743
|
+
`ormSource: typeorm`:
|
|
744
|
+
|
|
745
|
+
```bash
|
|
746
|
+
bunx typeorm schema:log -d <path/to/datasource> > schema.sql
|
|
747
|
+
dbcli diff --against-orm schema.sql --orm-format typeorm --format table
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
With `--orm-format typeorm`, `typeorm_metadata` and `migrations` are
|
|
751
|
+
default-ignored and appear as `unmanaged` rather than scored drift. Passing a
|
|
752
|
+
TypeORM `.ts`, `.js`, `.mjs`, or `.cjs` source file is rejected with the
|
|
753
|
+
`schema:log` command to run. See the
|
|
754
|
+
[TypeORM CLI documentation](https://typeorm.io/docs/using-cli) and
|
|
755
|
+
[`SchemaLogCommand`](https://github.com/typeorm/typeorm/blob/master/src/commands/SchemaLogCommand.ts).
|
|
756
|
+
|
|
757
|
+
##### Sequelize
|
|
758
|
+
|
|
759
|
+
Sequelize CLI does not provide a universal `db:migrate --dry-run`. Point the
|
|
760
|
+
project's existing Sequelize configuration at an empty scratch database, apply
|
|
761
|
+
the migrations there, and dump definitions without row data:
|
|
762
|
+
|
|
763
|
+
```bash
|
|
764
|
+
# Configure Sequelize for an empty scratch database first
|
|
765
|
+
bunx sequelize-cli db:migrate
|
|
766
|
+
|
|
767
|
+
# PostgreSQL scratch database
|
|
768
|
+
pg_dump --schema-only <scratch-database> > schema.sql
|
|
769
|
+
|
|
770
|
+
# MySQL scratch database
|
|
771
|
+
mysqldump --no-data <database> > schema.sql
|
|
772
|
+
|
|
773
|
+
dbcli diff --against-orm schema.sql --orm-format sequelize --format json
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
With `--orm-format sequelize`, `SequelizeMeta` is default-ignored and appears as
|
|
777
|
+
`unmanaged` rather than scored drift. Passing a Sequelize `.ts`, `.js`, `.mjs`,
|
|
778
|
+
or `.cjs` model file is rejected with the scratch-database and schema-only dump
|
|
779
|
+
recipe. See the
|
|
780
|
+
[Sequelize CLI migration command](https://github.com/sequelize/cli/blob/main/src/commands/migrate.js),
|
|
781
|
+
[PostgreSQL `pg_dump`](https://www.postgresql.org/docs/current/app-pgdump.html),
|
|
782
|
+
and [MySQL `mysqldump`](https://dev.mysql.com/doc/refman/8.4/en/mysqldump-definition-data-dumps.html)
|
|
783
|
+
references.
|
|
784
|
+
|
|
734
785
|
| Option | Behavior |
|
|
735
786
|
| :--- | :--- |
|
|
736
|
-
| `--against-orm <paths>` | Repeatable or comma-separated input. DDL inputs support real filesystem globs; matches are deduplicated and put in deterministic path order, then parsed as one shared ordered context so an index in a later file can attach to a table declared in an earlier file. Prisma
|
|
737
|
-
|
|
|
738
|
-
|
|
|
787
|
+
| `--against-orm <paths>` | Repeatable or comma-separated input. DDL-family inputs (raw DDL, TypeORM, and Sequelize) support real filesystem globs; matches are deduplicated and put in deterministic path order, then parsed as one shared ordered context so an index in a later file can attach to a table declared in an earlier file. Prisma, normalized JSON, and Drizzle accept exactly one file, and globs are rejected for those formats. |
|
|
788
|
+
| Drizzle input | Run `drizzle-kit generate`, then pass the PostgreSQL drizzle-kit v7 snapshot at `drizzle/meta/<NNNN>_snapshot.json`. TypeScript ORM schema sources (`.ts` or `.TS`) are rejected with that snapshot-generation hint; dbcli does not parse them directly. |
|
|
789
|
+
| TypeORM / Sequelize input | Generate DDL with the ORM/database tooling, then pass the SQL file with the matching `typeorm` or `sequelize` alias. Entity/model source files are rejected rather than parsed. |
|
|
790
|
+
| `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize` | Override extension/content detection. The `typeorm` and `sequelize` aliases use the DDL adapter while preserving the source tag and ORM-specific default ignores. Without an override, dbcli detects Prisma, raw DDL, normalized JSON, or a Drizzle snapshot from the path and content. |
|
|
791
|
+
| `--ignore <globs>` | Comma-separated, case-sensitive table globs. Patterns match the qualified display identity (for example `public.Users`). `_prisma_migrations` is always unmanaged; the TypeORM alias additionally ignores `typeorm_metadata` and `migrations`, and the Sequelize alias additionally ignores `SequelizeMeta`. |
|
|
739
792
|
| `--format json\|table\|markdown` | Select machine JSON, human table, or Markdown output. Markdown is available only in ORM drift mode. |
|
|
740
793
|
| `--recovery` | On an I/O, configuration, empty-cache, invalid-format, or unsupported-engine failure, emit and save a structured recovery envelope. Invalid Prisma/DDL constructs normally become `unparsed` entries instead of throwing. |
|
|
741
794
|
|
|
@@ -783,9 +836,11 @@ another.
|
|
|
783
836
|
columns, multi-schema datasource configuration, malformed declarations, unknown
|
|
784
837
|
attributes, and unsupported native mappings are never guessed.
|
|
785
838
|
|
|
786
|
-
Prisma and
|
|
839
|
+
Prisma, DDL, and Drizzle constructs outside the supported subset are retained in
|
|
787
840
|
`unparsed` with a `blocked:` reason. These entries are separate from scored drift:
|
|
788
841
|
inspect and resolve them before treating an otherwise clean summary as complete.
|
|
842
|
+
Drizzle enums and other unsupported snapshot constructs therefore appear as blocked
|
|
843
|
+
`unparsed` entries rather than managed tables or columns.
|
|
789
844
|
Multi-file DDL is consumed as one deterministic shared ordered statement context,
|
|
790
845
|
so later `CREATE INDEX` statements can reference tables declared in earlier
|
|
791
846
|
files. PostgreSQL `PARTITION BY` and MySQL/MariaDB table engine, charset, and
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to dbcli are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.42.0] - 2026-07-20 - Drizzle Snapshot 與 ORM DDL 工作流擴充
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Drizzle Kit snapshot 可直接用於 ORM drift 比對。** `dbcli diff --against-orm` 新增 Drizzle snapshot 格式偵測與 `NormalizedSchema` adapter,支援 PostgreSQL v7 snapshot 的 table、column、primary key、unique constraint、index 與 foreign key metadata。
|
|
13
|
+
- **TypeORM/Sequelize DDL alias。** `--orm-format typeorm`、`typeorm-ddl`、`sequelize` 與 `sequelize-ddl` 可直接走既有 DDL adapter;自動忽略 `typeorm_metadata` 與 `SequelizeMeta` bookkeeping table,並補上 source-file 使用者的可執行匯出/比對指引。
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **ORM drift 文件完整同步。** 英文/繁體中文的 Markdown 與 HTML 使用者文件、skill assets、各平台 plugin 副本及 reference 已補上 Drizzle snapshot、TypeORM/Sequelize DDL 的格式、限制與操作範例。
|
|
18
|
+
- **跨平台發版 metadata 對齊。** npm package、Codex/Claude/Cursor plugin、packaged Codex plugin 與 Gemini extension 統一為 `1.42.0`。
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **不支援的 ORM 輸入改為 fail closed。** Drizzle snapshot 會拒絕不支援的版本/dialect、generated/identity/enum/composite primary key 等結構,以及無法無損轉換的 column default;TypeORM/Sequelize source file 則回報完整的匯出 DDL recipe,不再被 JSON/DDL fallback 誤解析。
|
|
23
|
+
- **Qualified ignore identity 保留完整。** ORM drift 的 ignore 比對不再把 schema-qualified identity 降成 bare table name,避免同名 table 跨 schema 時被錯誤忽略;ORM DDL alias 也會正確沿用 DDL 輸入處理與 bookkeeping ignore。
|
|
24
|
+
|
|
8
25
|
## [1.41.0] - 2026-07-19 - ORM Drift 比對與無損 Schema Identity
|
|
9
26
|
|
|
10
27
|
### Added
|
package/assets/SKILL.md
CHANGED
|
@@ -307,7 +307,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
|
|
|
307
307
|
| `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. Supports `--recovery`. |
|
|
308
308
|
| `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
|
|
309
309
|
| `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
|
|
310
|
-
| `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json`, `--ignore <globs>`, `--format json\|table\|markdown`. |
|
|
310
|
+
| `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize`, `--ignore <globs>`, `--format json\|table\|markdown`. Drizzle: point at `drizzle/meta/<NNNN>_snapshot.json` (run `drizzle-kit generate` first; `.ts` sources are rejected with a hint). TypeORM/Sequelize: feed tool-generated DDL (`schema:log` / a schema-only dump); source files are rejected with the exact generation command to run. |
|
|
311
311
|
| `snapshot` | query-only+ | **(v1.25)** SQL only. Capture a result fingerprint (`rowCount` + per-column null/distinct/min/max/sum + order-independent checksum). `--out` (default `.dbcli/snapshots/snap-<ts>.json`), `--rows`, `--stdout`, `--format`, `--no-limit`. Baseline for `assert --against`. |
|
|
312
312
|
| `assert` | query-only+ | **(v1.25)** SQL only. Verify an invariant; exit 1 on failure unless `--no-fail`. `--expect "rows>0\|value==X\|col:c not null\|unique\|between a and b\|>= n"`, `--vs <query> --compare rows\|value` (reconcile), `--against <snapshot> --tolerance <pct>`. |
|
|
313
313
|
| `verification` | n/a | Inspect and manage local verification artifacts. `list` / `show <id-or-path>` / `summary` are read-only; `prune` is dry-run by default and deletes only with `--execute --force`. Reads `<cwd>/.dbcli/verification/`; no DB connection, no audit writes. |
|
package/assets/SKILL.zh-TW.md
CHANGED
|
@@ -245,7 +245,7 @@ dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-tes
|
|
|
245
245
|
| `export` | query-only+ | SQL、MongoDB 或 **(v1.22)** Elasticsearch(DSL `--index` 或全 index scroll)。Query → `--format json\|jsonl\|csv\|html` 檔案或 stdout。`html` 輸出獨立可互動 dashboard。支援 `--recovery`。 |
|
|
246
246
|
| `blacklist` | n/a | `list` / `table` / `column` 子指令,從查詢結果中遮蔽敏感資料。 |
|
|
247
247
|
| `check` | query-only+ | 僅 SQL(在 MySQL / MariaDB 最佳)。 |
|
|
248
|
-
| `diff` | query-only+ | 僅 SQL。儲存 / 比較 schema snapshot。**(P1b)** `--against-orm <path>` 會將 Prisma schema / DDL 檔 / normalized JSON 與本地 schema cache 比對(不連線 DB):分類為 `missing_in_db`(error)、`missing_in_orm`(warn)、依 tolerance 表判定的 `mismatch`、以及 `unmanaged`,並提供 dry-run `migrate` 提案;出現 error-level drift 時 exit 1。`--orm-format prisma\|ddl\|json`、`--ignore <globs>`、`--format json\|table\|markdown`。 |
|
|
248
|
+
| `diff` | query-only+ | 僅 SQL。儲存 / 比較 schema snapshot。**(P1b)** `--against-orm <path>` 會將 Prisma schema / DDL 檔 / normalized JSON 與本地 schema cache 比對(不連線 DB):分類為 `missing_in_db`(error)、`missing_in_orm`(warn)、依 tolerance 表判定的 `mismatch`、以及 `unmanaged`,並提供 dry-run `migrate` 提案;出現 error-level drift 時 exit 1。`--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize`、`--ignore <globs>`、`--format json\|table\|markdown`。Drizzle:請指向 `drizzle/meta/<NNNN>_snapshot.json`(先執行 `drizzle-kit generate`;`.ts` source 會被拒絕並顯示提示)。TypeORM/Sequelize:傳入工具產生的 DDL(`schema:log` / schema-only dump);source file 會被拒絕,並顯示要執行的精確產生指令。 |
|
|
249
249
|
| `snapshot` | query-only+ | **(v1.25)** 僅 SQL。擷取結果指紋(`rowCount` + 每欄 null/distinct/min/max/sum + 順序無關 checksum)。`--out`(預設 `.dbcli/snapshots/snap-<ts>.json`)、`--rows`、`--stdout`、`--format`、`--no-limit`。作為 `assert --against` 的基準。 |
|
|
250
250
|
| `assert` | query-only+ | **(v1.25)** 僅 SQL。驗證不變量;失敗時 exit 1,除非 `--no-fail`。`--expect "rows>0\|value==X\|col:c not null\|unique\|between a and b\|>= n"`、`--vs <query> --compare rows\|value`(對帳)、`--against <snapshot> --tolerance <pct>`。 |
|
|
251
251
|
| `verification` | n/a | 檢視與管理本機驗證 artifact。`list` / `show <id-or-path>` / `summary` 為唯讀;`prune` 預設 dry-run,僅在 `--execute --force` 時刪除。讀取 `<cwd>/.dbcli/verification/`;不需 DB 連線,不寫入 audit log。 |
|
package/assets/reference.md
CHANGED
|
@@ -722,6 +722,10 @@ separate `--snapshot` / `--against` workflow.
|
|
|
722
722
|
dbcli diff --against-orm prisma/schema.prisma --format json
|
|
723
723
|
dbcli diff --against-orm schema.normalized.json --orm-format json --format table
|
|
724
724
|
|
|
725
|
+
# Drizzle requires a PostgreSQL drizzle-kit v7 snapshot (generate it first)
|
|
726
|
+
drizzle-kit generate
|
|
727
|
+
dbcli diff --against-orm drizzle/meta/0001_snapshot.json --orm-format drizzle --format table
|
|
728
|
+
|
|
725
729
|
# DDL accepts repeatable or comma-separated paths and real filesystem globs
|
|
726
730
|
dbcli diff --against-orm "migrations/*.sql" --format markdown
|
|
727
731
|
dbcli diff --against-orm migrations/base.sql,migrations/accounts.sql \
|
|
@@ -731,11 +735,60 @@ dbcli diff --against-orm migrations/base.sql,migrations/accounts.sql \
|
|
|
731
735
|
dbcli diff --against-orm prisma/schema.prisma --ignore 'public.audit_*,public.Legacy'
|
|
732
736
|
```
|
|
733
737
|
|
|
738
|
+
##### TypeORM
|
|
739
|
+
|
|
740
|
+
TypeORM entities are not parsed directly. `schema:log` prints the SQL that
|
|
741
|
+
`schema:sync` would execute without applying it; `-d` is the required data-source
|
|
742
|
+
path. Generate that DDL, then select the `typeorm` alias so the report is tagged
|
|
743
|
+
`ormSource: typeorm`:
|
|
744
|
+
|
|
745
|
+
```bash
|
|
746
|
+
bunx typeorm schema:log -d <path/to/datasource> > schema.sql
|
|
747
|
+
dbcli diff --against-orm schema.sql --orm-format typeorm --format table
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
With `--orm-format typeorm`, `typeorm_metadata` and `migrations` are
|
|
751
|
+
default-ignored and appear as `unmanaged` rather than scored drift. Passing a
|
|
752
|
+
TypeORM `.ts`, `.js`, `.mjs`, or `.cjs` source file is rejected with the
|
|
753
|
+
`schema:log` command to run. See the
|
|
754
|
+
[TypeORM CLI documentation](https://typeorm.io/docs/using-cli) and
|
|
755
|
+
[`SchemaLogCommand`](https://github.com/typeorm/typeorm/blob/master/src/commands/SchemaLogCommand.ts).
|
|
756
|
+
|
|
757
|
+
##### Sequelize
|
|
758
|
+
|
|
759
|
+
Sequelize CLI does not provide a universal `db:migrate --dry-run`. Point the
|
|
760
|
+
project's existing Sequelize configuration at an empty scratch database, apply
|
|
761
|
+
the migrations there, and dump definitions without row data:
|
|
762
|
+
|
|
763
|
+
```bash
|
|
764
|
+
# Configure Sequelize for an empty scratch database first
|
|
765
|
+
bunx sequelize-cli db:migrate
|
|
766
|
+
|
|
767
|
+
# PostgreSQL scratch database
|
|
768
|
+
pg_dump --schema-only <scratch-database> > schema.sql
|
|
769
|
+
|
|
770
|
+
# MySQL scratch database
|
|
771
|
+
mysqldump --no-data <database> > schema.sql
|
|
772
|
+
|
|
773
|
+
dbcli diff --against-orm schema.sql --orm-format sequelize --format json
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
With `--orm-format sequelize`, `SequelizeMeta` is default-ignored and appears as
|
|
777
|
+
`unmanaged` rather than scored drift. Passing a Sequelize `.ts`, `.js`, `.mjs`,
|
|
778
|
+
or `.cjs` model file is rejected with the scratch-database and schema-only dump
|
|
779
|
+
recipe. See the
|
|
780
|
+
[Sequelize CLI migration command](https://github.com/sequelize/cli/blob/main/src/commands/migrate.js),
|
|
781
|
+
[PostgreSQL `pg_dump`](https://www.postgresql.org/docs/current/app-pgdump.html),
|
|
782
|
+
and [MySQL `mysqldump`](https://dev.mysql.com/doc/refman/8.4/en/mysqldump-definition-data-dumps.html)
|
|
783
|
+
references.
|
|
784
|
+
|
|
734
785
|
| Option | Behavior |
|
|
735
786
|
| :--- | :--- |
|
|
736
|
-
| `--against-orm <paths>` | Repeatable or comma-separated input. DDL inputs support real filesystem globs; matches are deduplicated and put in deterministic path order, then parsed as one shared ordered context so an index in a later file can attach to a table declared in an earlier file. Prisma
|
|
737
|
-
|
|
|
738
|
-
|
|
|
787
|
+
| `--against-orm <paths>` | Repeatable or comma-separated input. DDL-family inputs (raw DDL, TypeORM, and Sequelize) support real filesystem globs; matches are deduplicated and put in deterministic path order, then parsed as one shared ordered context so an index in a later file can attach to a table declared in an earlier file. Prisma, normalized JSON, and Drizzle accept exactly one file, and globs are rejected for those formats. |
|
|
788
|
+
| Drizzle input | Run `drizzle-kit generate`, then pass the PostgreSQL drizzle-kit v7 snapshot at `drizzle/meta/<NNNN>_snapshot.json`. TypeScript ORM schema sources (`.ts` or `.TS`) are rejected with that snapshot-generation hint; dbcli does not parse them directly. |
|
|
789
|
+
| TypeORM / Sequelize input | Generate DDL with the ORM/database tooling, then pass the SQL file with the matching `typeorm` or `sequelize` alias. Entity/model source files are rejected rather than parsed. |
|
|
790
|
+
| `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize` | Override extension/content detection. The `typeorm` and `sequelize` aliases use the DDL adapter while preserving the source tag and ORM-specific default ignores. Without an override, dbcli detects Prisma, raw DDL, normalized JSON, or a Drizzle snapshot from the path and content. |
|
|
791
|
+
| `--ignore <globs>` | Comma-separated, case-sensitive table globs. Patterns match the qualified display identity (for example `public.Users`). `_prisma_migrations` is always unmanaged; the TypeORM alias additionally ignores `typeorm_metadata` and `migrations`, and the Sequelize alias additionally ignores `SequelizeMeta`. |
|
|
739
792
|
| `--format json\|table\|markdown` | Select machine JSON, human table, or Markdown output. Markdown is available only in ORM drift mode. |
|
|
740
793
|
| `--recovery` | On an I/O, configuration, empty-cache, invalid-format, or unsupported-engine failure, emit and save a structured recovery envelope. Invalid Prisma/DDL constructs normally become `unparsed` entries instead of throwing. |
|
|
741
794
|
|
|
@@ -783,9 +836,11 @@ another.
|
|
|
783
836
|
columns, multi-schema datasource configuration, malformed declarations, unknown
|
|
784
837
|
attributes, and unsupported native mappings are never guessed.
|
|
785
838
|
|
|
786
|
-
Prisma and
|
|
839
|
+
Prisma, DDL, and Drizzle constructs outside the supported subset are retained in
|
|
787
840
|
`unparsed` with a `blocked:` reason. These entries are separate from scored drift:
|
|
788
841
|
inspect and resolve them before treating an otherwise clean summary as complete.
|
|
842
|
+
Drizzle enums and other unsupported snapshot constructs therefore appear as blocked
|
|
843
|
+
`unparsed` entries rather than managed tables or columns.
|
|
789
844
|
Multi-file DDL is consumed as one deterministic shared ordered statement context,
|
|
790
845
|
so later `CREATE INDEX` statements can reference tables declared in earlier
|
|
791
846
|
files. PostgreSQL `PARTITION BY` and MySQL/MariaDB table engine, charset, and
|