@dbsp/cli 1.1.11 → 2.0.1
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/dist/{chunk-AQC34IO5.js → chunk-EO3GHEFW.js} +13 -3
- package/dist/chunk-EO3GHEFW.js.map +1 -0
- package/dist/{chunk-YGOS4A3O.js → chunk-V3GXFQNB.js} +1 -1
- package/dist/chunk-V3GXFQNB.js.map +1 -0
- package/dist/{chunk-H2K46TNM.js → chunk-VUNVYYOZ.js} +161 -34
- package/dist/chunk-VUNVYYOZ.js.map +1 -0
- package/dist/generators/schema-codegen.d.ts +11 -6
- package/dist/generators/schema-codegen.js +3 -3
- package/dist/index.js +159 -55
- package/dist/index.js.map +1 -1
- package/dist/repl/batch.d.ts +4 -3
- package/dist/repl/batch.js +1 -1
- package/dist/{repl-G56OK3F7.js → repl-PIFVQAHC.js} +2 -2
- package/dist/utils/schema-loader.d.ts +6 -4
- package/dist/utils/schema-loader.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-AQC34IO5.js.map +0 -1
- package/dist/chunk-H2K46TNM.js.map +0 -1
- package/dist/chunk-YGOS4A3O.js.map +0 -1
- /package/dist/{repl-G56OK3F7.js.map → repl-PIFVQAHC.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createDbConnection,
|
|
4
|
-
|
|
4
|
+
generateSchemaFileWithDiagnostics,
|
|
5
5
|
redactDbUrl
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VUNVYYOZ.js";
|
|
7
7
|
import {
|
|
8
8
|
loadSchema,
|
|
9
9
|
loadSchemaFromCwd
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-EO3GHEFW.js";
|
|
11
11
|
import {
|
|
12
12
|
config,
|
|
13
13
|
validateIdentifier
|
|
@@ -29,6 +29,14 @@ var generateCommand = new Command("generate").description("Generate code from sc
|
|
|
29
29
|
).action(
|
|
30
30
|
async (target, options) => {
|
|
31
31
|
try {
|
|
32
|
+
if (target === "manifest" || target === "kysely") {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Target '${target}' has been removed. Use 'ddl' for SQL generation, or the 'introspect' command to generate a schema file.`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
if (target !== "ddl") {
|
|
38
|
+
throw new Error(`Unknown target: ${target}. Available targets: ddl`);
|
|
39
|
+
}
|
|
32
40
|
let schema;
|
|
33
41
|
let schemaPath;
|
|
34
42
|
if (options.schema) {
|
|
@@ -51,9 +59,9 @@ var generateCommand = new Command("generate").description("Generate code from sc
|
|
|
51
59
|
}
|
|
52
60
|
switch (target) {
|
|
53
61
|
case "ddl": {
|
|
54
|
-
const
|
|
62
|
+
const dbCasing = mapGenerateCasingOption(options.casing) ?? schema.dbCasing ?? "snake_case";
|
|
63
|
+
const casingLabel = formatGenerateCasingLabel(dbCasing);
|
|
55
64
|
const { createPgsqlCompileOnlyAdapter } = await import("@dbsp/adapter-pgsql");
|
|
56
|
-
const dbCasing = casing === "snake" ? "snake_case" : "preserve";
|
|
57
65
|
const adapter = createPgsqlCompileOnlyAdapter({
|
|
58
66
|
dbCasing,
|
|
59
67
|
...options.schemaName ? { schemaName: options.schemaName } : {}
|
|
@@ -73,7 +81,7 @@ var generateCommand = new Command("generate").description("Generate code from sc
|
|
|
73
81
|
console.log(`\u2705 Generated DDL: ${outPath}`);
|
|
74
82
|
console.log(` Tables: ${schema.tableNames.length}`);
|
|
75
83
|
console.log(` Statements: ${ddlStatements.length}`);
|
|
76
|
-
console.log(` Casing: ${
|
|
84
|
+
console.log(` Casing: ${casingLabel}`);
|
|
77
85
|
if (options.drop) {
|
|
78
86
|
console.log(` Includes DROP statements`);
|
|
79
87
|
}
|
|
@@ -86,15 +94,6 @@ var generateCommand = new Command("generate").description("Generate code from sc
|
|
|
86
94
|
}
|
|
87
95
|
break;
|
|
88
96
|
}
|
|
89
|
-
case "manifest":
|
|
90
|
-
case "kysely":
|
|
91
|
-
throw new Error(
|
|
92
|
-
`Target '${target}' has been removed in ARCH-005. These generators required the legacy defineSchema() format. Use 'ddl' target for SQL generation.`
|
|
93
|
-
);
|
|
94
|
-
default:
|
|
95
|
-
throw new Error(
|
|
96
|
-
`Unknown target: ${target}. Available targets: ddl`
|
|
97
|
-
);
|
|
98
97
|
}
|
|
99
98
|
} catch (error) {
|
|
100
99
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -103,11 +102,48 @@ var generateCommand = new Command("generate").description("Generate code from sc
|
|
|
103
102
|
}
|
|
104
103
|
}
|
|
105
104
|
);
|
|
105
|
+
function mapGenerateCasingOption(casing) {
|
|
106
|
+
switch (casing) {
|
|
107
|
+
case "snake":
|
|
108
|
+
return "snake_case";
|
|
109
|
+
case "camel":
|
|
110
|
+
return "camelCase";
|
|
111
|
+
case "none":
|
|
112
|
+
return "preserve";
|
|
113
|
+
default:
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function formatGenerateCasingLabel(dbCasing) {
|
|
118
|
+
switch (dbCasing) {
|
|
119
|
+
case "snake_case":
|
|
120
|
+
return "snake";
|
|
121
|
+
case "camelCase":
|
|
122
|
+
return "camel";
|
|
123
|
+
case "preserve":
|
|
124
|
+
return "none";
|
|
125
|
+
}
|
|
126
|
+
}
|
|
106
127
|
|
|
107
128
|
// src/commands/introspect.ts
|
|
108
129
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
109
130
|
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
110
131
|
import { Command as Command2 } from "commander";
|
|
132
|
+
function uniqueWarnings(warnings) {
|
|
133
|
+
const seen = /* @__PURE__ */ new Set();
|
|
134
|
+
const unique = [];
|
|
135
|
+
for (const warning of warnings) {
|
|
136
|
+
if (seen.has(warning)) continue;
|
|
137
|
+
seen.add(warning);
|
|
138
|
+
unique.push(warning);
|
|
139
|
+
}
|
|
140
|
+
return unique;
|
|
141
|
+
}
|
|
142
|
+
function reportWarnings(warnings) {
|
|
143
|
+
for (const warning of warnings) {
|
|
144
|
+
console.log(` \u26A0\uFE0F ${warning}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
111
147
|
var introspectCommand = new Command2("introspect").description("Generate schema.ts from database introspection").requiredOption("-d, --db <url>", "Database connection URL (required)").option("-o, --out <file>", "Output schema file", "./dbsp.schema.ts").option("--schema-name <name>", "Database schema name", "public").option(
|
|
112
148
|
"--exclude <patterns>",
|
|
113
149
|
"Tables to exclude (comma-separated glob patterns)",
|
|
@@ -128,10 +164,10 @@ var introspectCommand = new Command2("introspect").description("Generate schema.
|
|
|
128
164
|
try {
|
|
129
165
|
const { pool } = await createDbConnection(options.db);
|
|
130
166
|
try {
|
|
131
|
-
const { introspect
|
|
167
|
+
const { introspect } = await import("@dbsp/adapter-pgsql");
|
|
132
168
|
const excludePatterns = options.exclude ? options.exclude.split(",").map((s) => s.trim()) : void 0;
|
|
133
169
|
const includePatterns = options.include ? options.include.split(",").map((s) => s.trim()) : void 0;
|
|
134
|
-
const model = await
|
|
170
|
+
const model = await introspect(pool, {
|
|
135
171
|
schema: options.schemaName,
|
|
136
172
|
...excludePatterns ? { exclude: excludePatterns } : {},
|
|
137
173
|
...includePatterns ? { include: includePatterns } : {}
|
|
@@ -142,23 +178,24 @@ var introspectCommand = new Command2("introspect").description("Generate schema.
|
|
|
142
178
|
console.log(
|
|
143
179
|
`\u{1F4CA} Found ${tableCount} tables, ${relationCount} relations, ${hierarchyCount} hierarchies`
|
|
144
180
|
);
|
|
145
|
-
if (model.warnings?.length) {
|
|
146
|
-
for (const w of model.warnings) {
|
|
147
|
-
console.log(` \u26A0\uFE0F ${w}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
console.log("");
|
|
151
181
|
const codegenOptions = {
|
|
152
182
|
sourceUrl: options.db,
|
|
153
183
|
includeDbTypeComments: options.dbTypeComments,
|
|
154
|
-
warnings: model.warnings,
|
|
155
184
|
introspectedAt: model.introspectedAt,
|
|
156
185
|
dbCasing: options.dbCasing
|
|
157
186
|
};
|
|
158
|
-
const
|
|
187
|
+
const generated = generateSchemaFileWithDiagnostics(
|
|
188
|
+
model,
|
|
189
|
+
codegenOptions
|
|
190
|
+
);
|
|
191
|
+
const warnings = uniqueWarnings(generated.warnings);
|
|
192
|
+
if (warnings.length > 0) {
|
|
193
|
+
reportWarnings(warnings);
|
|
194
|
+
}
|
|
195
|
+
console.log("");
|
|
159
196
|
const outPath = resolve2(process.cwd(), options.out);
|
|
160
197
|
mkdirSync2(dirname2(outPath), { recursive: true });
|
|
161
|
-
writeFileSync2(outPath,
|
|
198
|
+
writeFileSync2(outPath, generated.code, "utf-8");
|
|
162
199
|
console.log(`\u2705 Generated schema: ${outPath}`);
|
|
163
200
|
console.log(` Tables: ${tableCount}`);
|
|
164
201
|
console.log(` Relations: ${relationCount}`);
|
|
@@ -175,13 +212,13 @@ var introspectCommand = new Command2("introspect").description("Generate schema.
|
|
|
175
212
|
|
|
176
213
|
// src/commands/migrate.ts
|
|
177
214
|
import {
|
|
178
|
-
|
|
215
|
+
comparePgsqlDatabaseSchema,
|
|
216
|
+
createPgsqlAdapter,
|
|
179
217
|
ensureMigrationsTable,
|
|
180
218
|
generateMigrationFile,
|
|
181
219
|
generateMigrationSQL,
|
|
182
220
|
getAppliedMigrations,
|
|
183
221
|
getNextSchemaVersion,
|
|
184
|
-
introspect,
|
|
185
222
|
isDestructiveDown,
|
|
186
223
|
parseMigrationFile,
|
|
187
224
|
recordMigration,
|
|
@@ -318,10 +355,12 @@ var devCommand = new Command3("dev").description("Generate a migration from sche
|
|
|
318
355
|
const loaded = await loadSchema(schemaPath);
|
|
319
356
|
const schemaModel = loaded.model;
|
|
320
357
|
await withMigratePool(options.db, async (pool) => {
|
|
321
|
-
const
|
|
322
|
-
|
|
358
|
+
const adapter = createPgsqlAdapter(pool);
|
|
359
|
+
const diff = await comparePgsqlDatabaseSchema(adapter, schemaModel, {
|
|
360
|
+
...options.schemaName ? { schema: options.schemaName } : {},
|
|
361
|
+
...loaded.dbCasing ? { dbCasing: loaded.dbCasing } : {},
|
|
362
|
+
onWarning: (message) => console.warn(`\u26A0\uFE0F ${message}`)
|
|
323
363
|
});
|
|
324
|
-
const diff = compareSchemata(schemaModel, dbModel);
|
|
325
364
|
if (diff.changes.length === 0) {
|
|
326
365
|
console.log("\u2705 No changes detected \u2014 database matches schema.");
|
|
327
366
|
return;
|
|
@@ -640,10 +679,11 @@ var migrateCommand = new Command3("migrate").description("Database migration man
|
|
|
640
679
|
|
|
641
680
|
// src/commands/push.ts
|
|
642
681
|
import {
|
|
643
|
-
|
|
682
|
+
comparePgsqlDatabaseSchema as comparePgsqlDatabaseSchema2,
|
|
683
|
+
createPgsqlAdapter as createPgsqlAdapter2,
|
|
644
684
|
generateDDL,
|
|
645
685
|
generateMigrationSQL as generateMigrationSQL2,
|
|
646
|
-
|
|
686
|
+
getNamingPluginForDbCasing
|
|
647
687
|
} from "@dbsp/adapter-pgsql";
|
|
648
688
|
import { Command as Command4 } from "commander";
|
|
649
689
|
|
|
@@ -706,16 +746,10 @@ var pushCommand = new Command4("push").description("Push schema to database (add
|
|
|
706
746
|
if (options.drop) {
|
|
707
747
|
const statements = generateDDL(schemaModel, {
|
|
708
748
|
includeDropStatements: true,
|
|
709
|
-
...options.schemaName ? { schemaName: options.schemaName } : {}
|
|
749
|
+
...options.schemaName ? { schemaName: options.schemaName } : {},
|
|
750
|
+
...loaded.dbCasing !== void 0 ? { naming: getNamingPluginForDbCasing(loaded.dbCasing) } : {}
|
|
710
751
|
});
|
|
711
|
-
const
|
|
712
|
-
/[.*+?^${}()|[\]\\]/g,
|
|
713
|
-
"\\$&"
|
|
714
|
-
);
|
|
715
|
-
const migrationsPattern = new RegExp(
|
|
716
|
-
`DROP\\s+TABLE(?:\\s+IF\\s+EXISTS)?(?:\\s+"[^"]*"\\s*\\.)?\\s*"${escapedTable}"`,
|
|
717
|
-
"i"
|
|
718
|
-
);
|
|
752
|
+
const migrationsPattern = buildMigrationsTableDropPattern(MIGRATIONS_TABLE);
|
|
719
753
|
const filtered = statements.filter(
|
|
720
754
|
(stmt) => !migrationsPattern.test(stmt)
|
|
721
755
|
);
|
|
@@ -724,10 +758,7 @@ var pushCommand = new Command4("push").description("Push schema to database (add
|
|
|
724
758
|
...options.dryRun !== void 0 ? { dryRun: options.dryRun } : {}
|
|
725
759
|
});
|
|
726
760
|
if (options.json) {
|
|
727
|
-
const droppedTables = statements.filter((s) => /DROP\s+TABLE/i.test(s)).filter((s) => !migrationsPattern.test(s)).map((
|
|
728
|
-
const m = s.match(/"([^"]+)"\s*(?:CASCADE\s*)?;?\s*$/i);
|
|
729
|
-
return m ? m[1] : s;
|
|
730
|
-
}).filter((t) => t !== void 0);
|
|
761
|
+
const droppedTables = statements.filter((s) => /DROP\s+TABLE/i.test(s)).filter((s) => !migrationsPattern.test(s)).map(extractDroppedTableName).filter((t) => t !== void 0);
|
|
731
762
|
console.log(
|
|
732
763
|
JSON.stringify(
|
|
733
764
|
{
|
|
@@ -747,10 +778,17 @@ var pushCommand = new Command4("push").description("Push schema to database (add
|
|
|
747
778
|
);
|
|
748
779
|
}
|
|
749
780
|
} else {
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
781
|
+
const adapter = createPgsqlAdapter2(pool);
|
|
782
|
+
const compareOptions = {
|
|
783
|
+
...options.schemaName ? { schema: options.schemaName } : {},
|
|
784
|
+
...loaded.dbCasing ? { dbCasing: loaded.dbCasing } : {},
|
|
785
|
+
onWarning: (message) => console.warn(`\u26A0\uFE0F ${message}`)
|
|
786
|
+
};
|
|
787
|
+
const diff = await comparePgsqlDatabaseSchema2(
|
|
788
|
+
adapter,
|
|
789
|
+
schemaModel,
|
|
790
|
+
compareOptions
|
|
791
|
+
);
|
|
754
792
|
const statements = generateMigrationSQL2(diff, {
|
|
755
793
|
includeDestructive: false,
|
|
756
794
|
...options.schemaName ? { schemaName: options.schemaName } : {}
|
|
@@ -787,6 +825,17 @@ var pushCommand = new Command4("push").description("Push schema to database (add
|
|
|
787
825
|
const result = await executeDdl(pool, statements, {
|
|
788
826
|
...options.dryRun !== void 0 ? { dryRun: options.dryRun } : {}
|
|
789
827
|
});
|
|
828
|
+
if (!options.dryRun) {
|
|
829
|
+
const postApplyDiff = await comparePgsqlDatabaseSchema2(
|
|
830
|
+
adapter,
|
|
831
|
+
schemaModel,
|
|
832
|
+
{
|
|
833
|
+
...compareOptions,
|
|
834
|
+
previouslyAppliedDiff: diff
|
|
835
|
+
}
|
|
836
|
+
);
|
|
837
|
+
assertNoUnexpectedResidualDrift(postApplyDiff, skippedChanges);
|
|
838
|
+
}
|
|
790
839
|
if (options.json) {
|
|
791
840
|
console.log(
|
|
792
841
|
JSON.stringify(
|
|
@@ -822,6 +871,17 @@ var pushCommand = new Command4("push").description("Push schema to database (add
|
|
|
822
871
|
}
|
|
823
872
|
}
|
|
824
873
|
);
|
|
874
|
+
function buildMigrationsTableDropPattern(tableName) {
|
|
875
|
+
const escaped = tableName.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
876
|
+
return new RegExp(
|
|
877
|
+
`DROP\\s+TABLE(?:\\s+IF\\s+EXISTS)?(?:\\s+"[^"]*"\\s*\\.)?\\s*"${escaped}"`,
|
|
878
|
+
"i"
|
|
879
|
+
);
|
|
880
|
+
}
|
|
881
|
+
function extractDroppedTableName(statement) {
|
|
882
|
+
const match = statement.match(/"([^"]+)"\s*(?:CASCADE\s*)?;?\s*$/iu);
|
|
883
|
+
return match?.[1] ?? statement;
|
|
884
|
+
}
|
|
825
885
|
function outputResult(statements, options) {
|
|
826
886
|
if (options.dryRun && !options.json) {
|
|
827
887
|
console.log(`-- Dry run: ${statements.length} statement(s)
|
|
@@ -832,6 +892,30 @@ function outputResult(statements, options) {
|
|
|
832
892
|
}
|
|
833
893
|
}
|
|
834
894
|
}
|
|
895
|
+
function assertNoUnexpectedResidualDrift(postApplyDiff, skippedChanges) {
|
|
896
|
+
const skippedKeys = new Set(skippedChanges.map(changeIdentity));
|
|
897
|
+
const unexpected = postApplyDiff.changes.filter(
|
|
898
|
+
(change) => !(change.destructive && skippedKeys.has(changeIdentity(change)))
|
|
899
|
+
);
|
|
900
|
+
if (unexpected.length === 0) return;
|
|
901
|
+
throw new Error(
|
|
902
|
+
`Push did not converge after applying DDL; ${unexpected.length} outstanding change(s) remain:
|
|
903
|
+
` + unexpected.map(formatOutstandingChange).join("\n")
|
|
904
|
+
);
|
|
905
|
+
}
|
|
906
|
+
function changeIdentity(change) {
|
|
907
|
+
return JSON.stringify([
|
|
908
|
+
change.kind,
|
|
909
|
+
change.table,
|
|
910
|
+
change.column ?? null,
|
|
911
|
+
change.details,
|
|
912
|
+
change.destructive
|
|
913
|
+
]);
|
|
914
|
+
}
|
|
915
|
+
function formatOutstandingChange(change) {
|
|
916
|
+
const target = change.column ? `${change.table}.${change.column}` : change.table || "schema";
|
|
917
|
+
return ` - ${change.details} (${change.kind}: ${target})`;
|
|
918
|
+
}
|
|
835
919
|
|
|
836
920
|
// src/commands/repl.ts
|
|
837
921
|
import { readFileSync as readFileSync2 } from "fs";
|
|
@@ -888,7 +972,7 @@ var replCommand = new Command5("repl").description("Launch interactive REPL for
|
|
|
888
972
|
if (options.use) {
|
|
889
973
|
validateIdentifier(options.use, "schema");
|
|
890
974
|
}
|
|
891
|
-
const dbCasing = options.casing
|
|
975
|
+
const dbCasing = mapReplCasingOption(options.casing) ?? schema.dbCasing;
|
|
892
976
|
if (options.eval || options.input) {
|
|
893
977
|
const { runBatchMode } = await import("./repl/batch.js");
|
|
894
978
|
const queries = [];
|
|
@@ -926,7 +1010,7 @@ var replCommand = new Command5("repl").description("Launch interactive REPL for
|
|
|
926
1010
|
});
|
|
927
1011
|
return;
|
|
928
1012
|
}
|
|
929
|
-
const { startRepl } = await import("./repl-
|
|
1013
|
+
const { startRepl } = await import("./repl-PIFVQAHC.js");
|
|
930
1014
|
await startRepl({
|
|
931
1015
|
schema,
|
|
932
1016
|
schemaPath,
|
|
@@ -942,9 +1026,24 @@ var replCommand = new Command5("repl").description("Launch interactive REPL for
|
|
|
942
1026
|
process.exit(1);
|
|
943
1027
|
}
|
|
944
1028
|
});
|
|
1029
|
+
function mapReplCasingOption(casing) {
|
|
1030
|
+
switch (casing) {
|
|
1031
|
+
case "snake":
|
|
1032
|
+
return "snake_case";
|
|
1033
|
+
case "camel":
|
|
1034
|
+
return "camelCase";
|
|
1035
|
+
case "none":
|
|
1036
|
+
return "preserve";
|
|
1037
|
+
default:
|
|
1038
|
+
return void 0;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
945
1041
|
|
|
946
1042
|
// src/commands/verify.ts
|
|
947
|
-
import {
|
|
1043
|
+
import {
|
|
1044
|
+
comparePgsqlDatabaseSchema as comparePgsqlDatabaseSchema3,
|
|
1045
|
+
createPgsqlAdapter as createPgsqlAdapter3
|
|
1046
|
+
} from "@dbsp/adapter-pgsql";
|
|
948
1047
|
import { Command as Command6 } from "commander";
|
|
949
1048
|
|
|
950
1049
|
// src/verifier.ts
|
|
@@ -1089,10 +1188,15 @@ var verifyCommand = new Command6("verify").description("Compare schema vs real d
|
|
|
1089
1188
|
const schemaModel = loaded.model;
|
|
1090
1189
|
const { pool } = await createDbConnection(options.db);
|
|
1091
1190
|
try {
|
|
1092
|
-
const
|
|
1191
|
+
const adapter = createPgsqlAdapter3(pool);
|
|
1192
|
+
const diff = await comparePgsqlDatabaseSchema3(adapter, schemaModel, {
|
|
1193
|
+
...options.schemaName ? { schema: options.schemaName } : {},
|
|
1194
|
+
...loaded.dbCasing !== void 0 ? { dbCasing: loaded.dbCasing } : {},
|
|
1195
|
+
onWarning: (message) => console.warn(`\u26A0\uFE0F ${message}`)
|
|
1196
|
+
});
|
|
1197
|
+
const dbModel = await adapter.introspect({
|
|
1093
1198
|
...options.schemaName ? { schema: options.schemaName } : {}
|
|
1094
1199
|
});
|
|
1095
|
-
const diff = compareSchemata3(schemaModel, dbModel);
|
|
1096
1200
|
const schemaTables = Array.from(schemaModel.tables.keys());
|
|
1097
1201
|
const dbTables = Array.from(dbModel.tables.keys());
|
|
1098
1202
|
const result = verifyFromDiff(diff, schemaTables, dbTables);
|