@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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "1.41.0",
3
+ "version": "1.42.0",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "1.41.0",
3
+ "version": "1.42.0",
4
4
  "description": "Database CLI skill and command reference for AI agents",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -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 and normalized JSON accept exactly one file, and globs are rejected for those formats. |
737
- | `--orm-format prisma\|ddl\|json` | Override extension/content detection. Without it, dbcli detects Prisma, DDL, or normalized JSON from the path and content. |
738
- | `--ignore <globs>` | Comma-separated, case-sensitive table globs. Patterns match the qualified display identity (for example `public.Users`). `_prisma_migrations` is always unmanaged. |
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 DDL constructs outside the supported subset are retained in
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
@@ -2,7 +2,7 @@
2
2
  "name": "dbcli-agent",
3
3
  "displayName": "dbcli Agent",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
- "version": "1.41.0",
5
+ "version": "1.42.0",
6
6
  "author": {
7
7
  "name": "Carl Lee",
8
8
  "url": "https://github.com/CarlLee1983"
@@ -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 and normalized JSON accept exactly one file, and globs are rejected for those formats. |
737
- | `--orm-format prisma\|ddl\|json` | Override extension/content detection. Without it, dbcli detects Prisma, DDL, or normalized JSON from the path and content. |
738
- | `--ignore <globs>` | Comma-separated, case-sensitive table globs. Patterns match the qualified display identity (for example `public.Users`). `_prisma_migrations` is always unmanaged. |
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 DDL constructs outside the supported subset are retained in
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. |
@@ -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。 |
@@ -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 and normalized JSON accept exactly one file, and globs are rejected for those formats. |
737
- | `--orm-format prisma\|ddl\|json` | Override extension/content detection. Without it, dbcli detects Prisma, DDL, or normalized JSON from the path and content. |
738
- | `--ignore <globs>` | Comma-separated, case-sensitive table globs. Patterns match the qualified display identity (for example `public.Users`). `_prisma_migrations` is always unmanaged. |
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 DDL constructs outside the supported subset are retained in
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