@memberjunction/cli 6.2.0-edge.0 → 6.2.0-edge.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/baseline/cli-helpers.d.ts +4 -0
- package/dist/baseline/cli-helpers.d.ts.map +1 -1
- package/dist/baseline/cli-helpers.js +18 -10
- package/dist/baseline/cli-helpers.js.map +1 -1
- package/dist/baseline/comparator.d.ts +5 -3
- package/dist/baseline/comparator.d.ts.map +1 -1
- package/dist/baseline/comparator.js +142 -138
- package/dist/baseline/comparator.js.map +1 -1
- package/dist/baseline/connection.d.ts +8 -6
- package/dist/baseline/connection.d.ts.map +1 -1
- package/dist/baseline/connection.js +16 -12
- package/dist/baseline/connection.js.map +1 -1
- package/dist/baseline/data-dumper.d.ts +7 -3
- package/dist/baseline/data-dumper.d.ts.map +1 -1
- package/dist/baseline/data-dumper.js +33 -25
- package/dist/baseline/data-dumper.js.map +1 -1
- package/dist/baseline/emitter.d.ts +5 -3
- package/dist/baseline/emitter.d.ts.map +1 -1
- package/dist/baseline/emitter.js +114 -110
- package/dist/baseline/emitter.js.map +1 -1
- package/dist/baseline/index.d.ts +7 -7
- package/dist/baseline/index.d.ts.map +1 -1
- package/dist/baseline/index.js +7 -7
- package/dist/baseline/index.js.map +1 -1
- package/dist/baseline/introspector-mssql.d.ts +2 -0
- package/dist/baseline/introspector-mssql.d.ts.map +1 -1
- package/dist/baseline/introspector-mssql.js +68 -64
- package/dist/baseline/introspector-mssql.js.map +1 -1
- package/dist/baseline/introspector-postgres.d.ts +2 -0
- package/dist/baseline/introspector-postgres.d.ts.map +1 -1
- package/dist/baseline/introspector-postgres.js +34 -30
- package/dist/baseline/introspector-postgres.js.map +1 -1
- package/dist/baseline/report.d.ts +4 -0
- package/dist/baseline/report.d.ts.map +1 -1
- package/dist/baseline/report.js +25 -17
- package/dist/baseline/report.js.map +1 -1
- package/dist/baseline/types.d.ts +71 -71
- package/dist/baseline/util.d.ts +54 -6
- package/dist/baseline/util.d.ts.map +1 -1
- package/dist/baseline/util.js +112 -36
- package/dist/baseline/util.js.map +1 -1
- package/dist/commands/agent/init.d.ts +12 -0
- package/dist/commands/agent/init.d.ts.map +1 -1
- package/dist/commands/agent/init.js +42 -8
- package/dist/commands/agent/init.js.map +1 -1
- package/dist/commands/ai/actions/list.js +7 -7
- package/dist/commands/ai/actions/run.js +7 -7
- package/dist/commands/ai/agents/list.js +7 -7
- package/dist/commands/ai/agents/run.js +9 -9
- package/dist/commands/ai/audit/agent-run.js +7 -7
- package/dist/commands/ai/prompts/run.js +7 -7
- package/dist/commands/app/check-updates.js +5 -5
- package/dist/commands/app/disable.js +2 -2
- package/dist/commands/app/enable.js +2 -2
- package/dist/commands/app/info.js +2 -2
- package/dist/commands/app/install.js +2 -2
- package/dist/commands/app/list.js +2 -2
- package/dist/commands/app/remove.js +4 -4
- package/dist/commands/app/upgrade.js +2 -2
- package/dist/commands/artifacts/reclassify.js +2 -2
- package/dist/commands/baseline/build.js +31 -31
- package/dist/commands/baseline/build.js.map +1 -1
- package/dist/commands/baseline/compare.js +36 -36
- package/dist/commands/baseline/roundtrip.js +56 -54
- package/dist/commands/baseline/roundtrip.js.map +1 -1
- package/dist/commands/bundle/index.js +4 -4
- package/dist/commands/clean/index.js +3 -3
- package/dist/commands/codegen/manifest.d.ts +2 -0
- package/dist/commands/codegen/manifest.d.ts.map +1 -1
- package/dist/commands/codegen/manifest.js +8 -4
- package/dist/commands/codegen/manifest.js.map +1 -1
- package/dist/commands/dev/workspace/index.d.ts +2 -0
- package/dist/commands/dev/workspace/index.d.ts.map +1 -1
- package/dist/commands/dev/workspace/index.js +8 -4
- package/dist/commands/dev/workspace/index.js.map +1 -1
- package/dist/commands/install/claude.d.ts +2 -0
- package/dist/commands/install/claude.d.ts.map +1 -1
- package/dist/commands/install/claude.js +11 -7
- package/dist/commands/install/claude.js.map +1 -1
- package/dist/commands/install/index.js +3 -3
- package/dist/commands/migrate/convert.d.ts +21 -0
- package/dist/commands/migrate/convert.d.ts.map +1 -1
- package/dist/commands/migrate/convert.js +37 -7
- package/dist/commands/migrate/convert.js.map +1 -1
- package/dist/commands/migrate/create.js +2 -2
- package/dist/commands/migrate/index.js +16 -16
- package/dist/commands/migrate/rebake.d.ts.map +1 -1
- package/dist/commands/migrate/rebake.js +7 -0
- package/dist/commands/migrate/rebake.js.map +1 -1
- package/dist/commands/rubric/diff.d.ts +11 -0
- package/dist/commands/rubric/diff.d.ts.map +1 -0
- package/dist/commands/rubric/diff.js +20 -0
- package/dist/commands/rubric/diff.js.map +1 -0
- package/dist/commands/rubric/evaluate.d.ts +12 -0
- package/dist/commands/rubric/evaluate.d.ts.map +1 -0
- package/dist/commands/rubric/evaluate.js +21 -0
- package/dist/commands/rubric/evaluate.js.map +1 -0
- package/dist/commands/rubric/index.d.ts +6 -0
- package/dist/commands/rubric/index.d.ts.map +1 -0
- package/dist/commands/rubric/index.js +13 -0
- package/dist/commands/rubric/index.js.map +1 -0
- package/dist/commands/rubric/list.d.ts +6 -0
- package/dist/commands/rubric/list.d.ts.map +1 -0
- package/dist/commands/rubric/list.js +14 -0
- package/dist/commands/rubric/list.js.map +1 -0
- package/dist/commands/rubric/show.d.ts +9 -0
- package/dist/commands/rubric/show.d.ts.map +1 -0
- package/dist/commands/rubric/show.js +16 -0
- package/dist/commands/rubric/show.js.map +1 -0
- package/dist/commands/rubric/validate.d.ts +9 -0
- package/dist/commands/rubric/validate.d.ts.map +1 -0
- package/dist/commands/rubric/validate.js +16 -0
- package/dist/commands/rubric/validate.js.map +1 -0
- package/dist/commands/sync/file-reset.js +2 -2
- package/dist/commands/sync/init.js +3 -3
- package/dist/commands/test/compare.js +6 -6
- package/dist/commands/test/history.js +6 -6
- package/dist/commands/test/index.d.ts.map +1 -1
- package/dist/commands/test/index.js +2 -0
- package/dist/commands/test/index.js.map +1 -1
- package/dist/commands/test/list.js +6 -6
- package/dist/commands/test/promote-criteria.d.ts +10 -0
- package/dist/commands/test/promote-criteria.d.ts.map +1 -0
- package/dist/commands/test/promote-criteria.js +25 -0
- package/dist/commands/test/promote-criteria.js.map +1 -0
- package/dist/commands/test/regression/build.js +5 -5
- package/dist/commands/test/regression/compare.js +3 -3
- package/dist/commands/test/regression/down.js +4 -4
- package/dist/commands/test/regression/export.js +4 -4
- package/dist/commands/test/regression/gen-forms.js +3 -3
- package/dist/commands/test/regression/remote.js +10 -10
- package/dist/commands/test/regression/up.js +6 -6
- package/dist/commands/test/report.d.ts +9 -0
- package/dist/commands/test/report.d.ts.map +1 -0
- package/dist/commands/test/report.js +18 -0
- package/dist/commands/test/report.js.map +1 -0
- package/dist/commands/test/run.d.ts +1 -0
- package/dist/commands/test/run.d.ts.map +1 -1
- package/dist/commands/test/run.js +10 -6
- package/dist/commands/test/run.js.map +1 -1
- package/dist/commands/test/suite.d.ts +1 -0
- package/dist/commands/test/suite.d.ts.map +1 -1
- package/dist/commands/test/suite.js +10 -6
- package/dist/commands/test/suite.js.map +1 -1
- package/dist/commands/test/validate.js +6 -6
- package/dist/commands/translate-sql/index.js +25 -25
- package/dist/commands/update/claude.js +7 -7
- package/dist/commands/usage.js +4 -4
- package/dist/config.d.ts +175 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -9
- package/dist/config.js.map +1 -1
- package/dist/hooks/postrun.js +2 -2
- package/dist/hooks/prerun.js +2 -2
- package/dist/hooks/prerun.js.map +1 -1
- package/dist/init-templates/citizen-builder/.env.example +6 -0
- package/dist/init-templates/citizen-builder/docker/Dockerfile +10 -2
- package/dist/init-templates/citizen-builder/docker-compose.yml +6 -0
- package/dist/init-templates/citizen-builder/scripts/docker-entrypoint.sh +56 -20
- package/dist/lib/claude-pack/ManagedBlockEditor.d.ts +6 -0
- package/dist/lib/claude-pack/ManagedBlockEditor.d.ts.map +1 -1
- package/dist/lib/claude-pack/ManagedBlockEditor.js +18 -6
- package/dist/lib/claude-pack/ManagedBlockEditor.js.map +1 -1
- package/dist/lib/claude-pack/PackFetcher.d.ts +8 -3
- package/dist/lib/claude-pack/PackFetcher.d.ts.map +1 -1
- package/dist/lib/claude-pack/PackFetcher.js +26 -18
- package/dist/lib/claude-pack/PackFetcher.js.map +1 -1
- package/dist/lib/claude-pack/PackInstaller.d.ts +6 -2
- package/dist/lib/claude-pack/PackInstaller.d.ts.map +1 -1
- package/dist/lib/claude-pack/PackInstaller.js +19 -13
- package/dist/lib/claude-pack/PackInstaller.js.map +1 -1
- package/dist/lib/claude-pack/PackMerger.d.ts +8 -0
- package/dist/lib/claude-pack/PackMerger.d.ts.map +1 -1
- package/dist/lib/claude-pack/PackMerger.js +63 -57
- package/dist/lib/claude-pack/PackMerger.js.map +1 -1
- package/dist/lib/claude-pack/PackOutputFormatter.d.ts +4 -0
- package/dist/lib/claude-pack/PackOutputFormatter.d.ts.map +1 -1
- package/dist/lib/claude-pack/PackOutputFormatter.js +10 -2
- package/dist/lib/claude-pack/PackOutputFormatter.js.map +1 -1
- package/dist/lib/claude-pack/PackPaths.d.ts +12 -0
- package/dist/lib/claude-pack/PackPaths.d.ts.map +1 -1
- package/dist/lib/claude-pack/PackPaths.js +31 -7
- package/dist/lib/claude-pack/PackPaths.js.map +1 -1
- package/dist/lib/claude-pack/PackTypes.d.ts +18 -14
- package/dist/lib/claude-pack/PackTypes.d.ts.map +1 -1
- package/dist/lib/claude-pack/PackTypes.js +11 -3
- package/dist/lib/claude-pack/PackTypes.js.map +1 -1
- package/dist/lib/claude-pack/SettingsMerger.d.ts +10 -0
- package/dist/lib/claude-pack/SettingsMerger.d.ts.map +1 -1
- package/dist/lib/claude-pack/SettingsMerger.js +36 -16
- package/dist/lib/claude-pack/SettingsMerger.js.map +1 -1
- package/dist/lib/cli-plugins.d.ts +2 -0
- package/dist/lib/cli-plugins.d.ts.map +1 -1
- package/dist/lib/cli-plugins.js +8 -4
- package/dist/lib/cli-plugins.js.map +1 -1
- package/dist/lib/db-preflight.d.ts +2 -0
- package/dist/lib/db-preflight.d.ts.map +1 -1
- package/dist/lib/db-preflight.js +12 -8
- package/dist/lib/db-preflight.js.map +1 -1
- package/dist/lib/db-version.d.ts +2 -0
- package/dist/lib/db-version.d.ts.map +1 -1
- package/dist/lib/db-version.js +5 -1
- package/dist/lib/db-version.js.map +1 -1
- package/dist/lib/derived-usage.d.ts +14 -8
- package/dist/lib/derived-usage.d.ts.map +1 -1
- package/dist/lib/derived-usage.js +30 -18
- package/dist/lib/derived-usage.js.map +1 -1
- package/dist/lib/domain-profiles.d.ts +4 -2
- package/dist/lib/domain-profiles.d.ts.map +1 -1
- package/dist/lib/domain-profiles.js +53 -49
- package/dist/lib/domain-profiles.js.map +1 -1
- package/dist/lib/domain-usage-command.js +4 -4
- package/dist/lib/dynamic-packages.d.ts +4 -2
- package/dist/lib/dynamic-packages.d.ts.map +1 -1
- package/dist/lib/dynamic-packages.js +9 -5
- package/dist/lib/dynamic-packages.js.map +1 -1
- package/dist/lib/format-compat.d.ts +9 -7
- package/dist/lib/format-compat.d.ts.map +1 -1
- package/dist/lib/format-compat.js +12 -8
- package/dist/lib/format-compat.js.map +1 -1
- package/dist/lib/interactive-guard.d.ts +16 -0
- package/dist/lib/interactive-guard.d.ts.map +1 -1
- package/dist/lib/interactive-guard.js +18 -6
- package/dist/lib/interactive-guard.js.map +1 -1
- package/dist/lib/migration-fetch.d.ts +16 -4
- package/dist/lib/migration-fetch.d.ts.map +1 -1
- package/dist/lib/migration-fetch.js +30 -18
- package/dist/lib/migration-fetch.js.map +1 -1
- package/dist/lib/regression/docker-helpers.d.ts +24 -0
- package/dist/lib/regression/docker-helpers.d.ts.map +1 -1
- package/dist/lib/regression/docker-helpers.js +46 -10
- package/dist/lib/regression/docker-helpers.js.map +1 -1
- package/dist/lib/usage-render.d.ts +6 -0
- package/dist/lib/usage-render.d.ts.map +1 -1
- package/dist/lib/usage-render.js +15 -3
- package/dist/lib/usage-render.js.map +1 -1
- package/dist/translate-sql/groundTruth.d.ts +3 -3
- package/dist/translate-sql/groundTruth.js +40 -40
- package/dist/translate-sql/reportGenerator.d.ts +7 -7
- package/dist/translate-sql/reportGenerator.js +18 -18
- package/dist/translate-sql/ruleTranslator.d.ts +3 -3
- package/dist/translate-sql/ruleTranslator.js +8 -8
- package/dist/translate-sql/ruleTranslator.js.map +1 -1
- package/dist/utils/open-app-context.d.ts +21 -0
- package/dist/utils/open-app-context.d.ts.map +1 -1
- package/dist/utils/open-app-context.js +26 -10
- package/dist/utils/open-app-context.js.map +1 -1
- package/oclif.manifest.json +1419 -1160
- package/package.json +22 -22
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { DbConnectionParams, DbConnectionOverrides } from './connection.js';
|
|
9
9
|
import type { Dialect } from './types.js';
|
|
10
|
+
export declare function ResolveConnection(overrides?: DbConnectionOverrides, dialectFlag?: Dialect): DbConnectionParams;
|
|
11
|
+
/** @deprecated Use {@link ResolveConnection}. */
|
|
10
12
|
export declare function resolveConnection(overrides?: DbConnectionOverrides, dialectFlag?: Dialect): DbConnectionParams;
|
|
13
|
+
export declare function IsTty(): boolean;
|
|
14
|
+
/** @deprecated Use {@link IsTty}. */
|
|
11
15
|
export declare function isTty(): boolean;
|
|
12
16
|
//# sourceMappingURL=cli-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-helpers.d.ts","sourceRoot":"","sources":["../../src/baseline/cli-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,qBAA0B,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAwBlH;AAED,wBAAgB,KAAK,IAAI,OAAO,CAE/B"}
|
|
1
|
+
{"version":3,"file":"cli-helpers.d.ts","sourceRoot":"","sources":["../../src/baseline/cli-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,qBAA0B,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAwBlH;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,qBAA0B,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAElH;AAED,wBAAgB,KAAK,IAAI,OAAO,CAE/B;AAED,qCAAqC;AACrC,wBAAgB,KAAK,IAAI,OAAO,CAE/B"}
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* with optional flag overrides (db name, host, etc).
|
|
6
6
|
* - Detect TTY for spinner vs. plain log output.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
export function
|
|
10
|
-
const config =
|
|
8
|
+
import { GetValidatedConfig } from '../config.js';
|
|
9
|
+
export function ResolveConnection(overrides = {}, dialectFlag) {
|
|
10
|
+
const config = GetValidatedConfig();
|
|
11
11
|
const dialect = dialectFlag
|
|
12
12
|
?? (config.dbPlatform === 'postgresql' ? 'postgres' : 'mssql');
|
|
13
|
-
const host = overrides.
|
|
13
|
+
const host = overrides.Host ?? config.dbHost;
|
|
14
14
|
const port = overrides.port ?? (config.dbPort ? Number(config.dbPort) : undefined);
|
|
15
15
|
const database = overrides.database ?? config.dbDatabase;
|
|
16
16
|
const user = overrides.user ?? config.codeGenLogin;
|
|
@@ -24,17 +24,25 @@ export function resolveConnection(overrides = {}, dialectFlag) {
|
|
|
24
24
|
if (!password)
|
|
25
25
|
throw new Error('No DB password configured (set CODEGEN_DB_PASSWORD).');
|
|
26
26
|
return {
|
|
27
|
-
dialect,
|
|
28
|
-
host,
|
|
27
|
+
Dialect: dialect,
|
|
28
|
+
Host: host,
|
|
29
29
|
port,
|
|
30
|
-
database,
|
|
31
|
-
user,
|
|
32
|
-
password,
|
|
30
|
+
Database: database,
|
|
31
|
+
User: user,
|
|
32
|
+
Password: password,
|
|
33
33
|
encrypt: overrides.encrypt ?? Boolean(config.dbEncrypt),
|
|
34
34
|
trustServerCertificate: overrides.trustServerCertificate ?? Boolean(config.dbTrustServerCertificate),
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
/** @deprecated Use {@link ResolveConnection}. */
|
|
38
|
+
export function resolveConnection(overrides = {}, dialectFlag) {
|
|
39
|
+
return ResolveConnection(overrides, dialectFlag);
|
|
40
|
+
}
|
|
41
|
+
export function IsTty() {
|
|
38
42
|
return Boolean(process.stdout.isTTY) && process.env.CI !== 'true';
|
|
39
43
|
}
|
|
44
|
+
/** @deprecated Use {@link IsTty}. */
|
|
45
|
+
export function isTty() {
|
|
46
|
+
return IsTty();
|
|
47
|
+
}
|
|
40
48
|
//# sourceMappingURL=cli-helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-helpers.js","sourceRoot":"","sources":["../../src/baseline/cli-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAI/C,MAAM,UAAU,iBAAiB,CAAC,YAAmC,EAAE,EAAE,WAAqB;IAC5F,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAY,WAAW;WAC/B,CAAC,MAAM,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEjE,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC;IAC7C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC;IACzD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAK,MAAoC,CAAC,YAAY,CAAC;IAClF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAK,MAAuC,CAAC,eAAe,CAAC;IAChG,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IAC9F,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACjH,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC/E,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACvF,OAAO;QACL,OAAO;
|
|
1
|
+
{"version":3,"file":"cli-helpers.js","sourceRoot":"","sources":["../../src/baseline/cli-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAI/C,MAAM,UAAU,iBAAiB,CAAC,YAAmC,EAAE,EAAE,WAAqB;IAC5F,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAY,WAAW;WAC/B,CAAC,MAAM,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEjE,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC;IAC7C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC;IACzD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAK,MAAoC,CAAC,YAAY,CAAC;IAClF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAK,MAAuC,CAAC,eAAe,CAAC;IAChG,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IAC9F,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACjH,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC/E,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACvF,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,IAAI;QACV,IAAI;QACJ,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;QACvD,sBAAsB,EAAE,SAAS,CAAC,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAC;KACrG,CAAC;AACJ,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,iBAAiB,CAAC,YAAmC,EAAE,EAAE,WAAqB;IAC5F,OAAO,iBAAiB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,KAAK;IACnB,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC;AACpE,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,KAAK;IACnB,OAAO,KAAK,EAAE,CAAC;AACjB,CAAC"}
|
|
@@ -10,17 +10,19 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { BaselineCompareOptions, DiffReport, SchemaSnapshot, TableDataDump } from './types.js';
|
|
12
12
|
export interface CompareInput {
|
|
13
|
-
|
|
13
|
+
Left: {
|
|
14
14
|
snapshot: SchemaSnapshot;
|
|
15
15
|
data: readonly TableDataDump[];
|
|
16
16
|
label: string;
|
|
17
17
|
};
|
|
18
|
-
|
|
18
|
+
Right: {
|
|
19
19
|
snapshot: SchemaSnapshot;
|
|
20
20
|
data: readonly TableDataDump[];
|
|
21
21
|
label: string;
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
Options: BaselineCompareOptions;
|
|
24
24
|
}
|
|
25
|
+
export declare function CompareSnapshots(input: CompareInput): DiffReport;
|
|
26
|
+
/** @deprecated Use {@link CompareSnapshots}. */
|
|
25
27
|
export declare function compareSnapshots(input: CompareInput): DiffReport;
|
|
26
28
|
//# sourceMappingURL=comparator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comparator.d.ts","sourceRoot":"","sources":["../../src/baseline/comparator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EACV,sBAAsB,EAGtB,UAAU,EAMV,cAAc,EACd,aAAa,EAKd,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QAAE,QAAQ,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,KAAK,EAAE;QAAE,QAAQ,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,CAoMhE"}
|
|
1
|
+
{"version":3,"file":"comparator.d.ts","sourceRoot":"","sources":["../../src/baseline/comparator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EACV,sBAAsB,EAGtB,UAAU,EAMV,cAAc,EACd,aAAa,EAKd,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QAAE,QAAQ,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,KAAK,EAAE;QAAE,QAAQ,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,CAoMhE;AAED,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,CAEhE"}
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
* Row-by-row comparison (when row data is supplied) walks each table's rows
|
|
9
9
|
* in their canonical order and reports value-level diffs.
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
12
|
-
export function
|
|
13
|
-
const { left, right, options } = input;
|
|
14
|
-
const ignored = options.
|
|
11
|
+
import { DeepValueEqual, IsoUtcSeconds, qname, StableSortBy } from './util.js';
|
|
12
|
+
export function CompareSnapshots(input) {
|
|
13
|
+
const { Left: left, Right: right, Options: options } = input;
|
|
14
|
+
const ignored = options.IgnorePattern;
|
|
15
15
|
const matchesIgnore = (q) => {
|
|
16
16
|
if (!ignored)
|
|
17
17
|
return false;
|
|
@@ -33,10 +33,10 @@ export function compareSnapshots(input) {
|
|
|
33
33
|
objectDiffs.push(...diffs);
|
|
34
34
|
};
|
|
35
35
|
// Schemas
|
|
36
|
-
counted(diffNamedSet('schema', left.snapshot.
|
|
36
|
+
counted(diffNamedSet('schema', left.snapshot.Schemas, right.snapshot.Schemas, (s) => s.name, matchesIgnore));
|
|
37
37
|
// Tables
|
|
38
|
-
const leftTables = new Map(left.snapshot.
|
|
39
|
-
const rightTables = new Map(right.snapshot.
|
|
38
|
+
const leftTables = new Map(left.snapshot.Tables.map((t) => [qname(t.Schema, t.Name), t]));
|
|
39
|
+
const rightTables = new Map(right.snapshot.Tables.map((t) => [qname(t.Schema, t.Name), t]));
|
|
40
40
|
const allTableKeys = new Set([...leftTables.keys(), ...rightTables.keys()]);
|
|
41
41
|
for (const key of [...allTableKeys].sort()) {
|
|
42
42
|
if (matchesIgnore(key))
|
|
@@ -44,12 +44,12 @@ export function compareSnapshots(input) {
|
|
|
44
44
|
const leftT = leftTables.get(key);
|
|
45
45
|
const rightT = rightTables.get(key);
|
|
46
46
|
if (!leftT && rightT) {
|
|
47
|
-
objectDiffs.push({
|
|
47
|
+
objectDiffs.push({ Kind: 'table', DiffKind: 'missing-on-left', QualifiedName: key });
|
|
48
48
|
objectsWithDiffs++;
|
|
49
49
|
continue;
|
|
50
50
|
}
|
|
51
51
|
if (leftT && !rightT) {
|
|
52
|
-
objectDiffs.push({
|
|
52
|
+
objectDiffs.push({ Kind: 'table', DiffKind: 'missing-on-right', QualifiedName: key });
|
|
53
53
|
objectsWithDiffs++;
|
|
54
54
|
continue;
|
|
55
55
|
}
|
|
@@ -58,19 +58,19 @@ export function compareSnapshots(input) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
// Views, procedures, functions, triggers, sequences
|
|
61
|
-
counted(diffNamedSet('view', left.snapshot.
|
|
61
|
+
counted(diffNamedSet('view', left.snapshot.Views, right.snapshot.Views, (v) => `${v.schema}.${v.name}`, matchesIgnore, (l, r) => normalizeBody(l.definition) === normalizeBody(r.definition)
|
|
62
62
|
? null
|
|
63
63
|
: `view body differs`));
|
|
64
|
-
counted(diffNamedSet('procedure', left.snapshot.
|
|
64
|
+
counted(diffNamedSet('procedure', left.snapshot.Procedures, right.snapshot.Procedures, (p) => `${p.schema}.${p.name}`, matchesIgnore, (l, r) => normalizeBody(l.definition) === normalizeBody(r.definition)
|
|
65
65
|
? null
|
|
66
66
|
: `procedure body differs`));
|
|
67
|
-
counted(diffNamedSet('function', left.snapshot.
|
|
67
|
+
counted(diffNamedSet('function', left.snapshot.Functions, right.snapshot.Functions, (p) => `${p.schema}.${p.name}`, matchesIgnore, (l, r) => normalizeBody(l.definition) === normalizeBody(r.definition)
|
|
68
68
|
? null
|
|
69
69
|
: `function body differs`));
|
|
70
|
-
counted(diffNamedSet('trigger', left.snapshot.
|
|
70
|
+
counted(diffNamedSet('trigger', left.snapshot.Triggers, right.snapshot.Triggers, (t) => `${t.schema}.${t.name}`, matchesIgnore, (l, r) => normalizeBody(l.definition) === normalizeBody(r.definition)
|
|
71
71
|
? null
|
|
72
72
|
: `trigger body differs`));
|
|
73
|
-
counted(diffNamedSet('sequence', left.snapshot.
|
|
73
|
+
counted(diffNamedSet('sequence', left.snapshot.Sequences, right.snapshot.Sequences, (s) => `${s.schema}.${s.name}`, matchesIgnore, (l, r) => {
|
|
74
74
|
const fields = [];
|
|
75
75
|
if (l.startValue !== r.startValue)
|
|
76
76
|
fields.push(`startValue: ${l.startValue} vs ${r.startValue}`);
|
|
@@ -81,21 +81,21 @@ export function compareSnapshots(input) {
|
|
|
81
81
|
return fields.length === 0 ? null : fields.join('; ');
|
|
82
82
|
}));
|
|
83
83
|
// User-defined types (table types)
|
|
84
|
-
counted(diffUserDefinedTypes(left.snapshot.
|
|
84
|
+
counted(diffUserDefinedTypes(left.snapshot.UserDefinedTypes, right.snapshot.UserDefinedTypes, matchesIgnore));
|
|
85
85
|
// Extended properties (sp_addextendedproperty entries — MS_Description etc.)
|
|
86
|
-
counted(diffExtendedProperties(left.snapshot.
|
|
86
|
+
counted(diffExtendedProperties(left.snapshot.ExtendedProperties, right.snapshot.ExtendedProperties));
|
|
87
87
|
// Database principals (users + custom roles)
|
|
88
|
-
counted(diffPrincipals(left.snapshot.
|
|
88
|
+
counted(diffPrincipals(left.snapshot.Principals, right.snapshot.Principals));
|
|
89
89
|
// Role memberships
|
|
90
|
-
counted(diffRoleMemberships(left.snapshot.
|
|
90
|
+
counted(diffRoleMemberships(left.snapshot.RoleMemberships, right.snapshot.RoleMemberships));
|
|
91
91
|
// Permissions (GRANT/DENY entries)
|
|
92
|
-
counted(diffPermissions(left.snapshot.
|
|
92
|
+
counted(diffPermissions(left.snapshot.Permissions, right.snapshot.Permissions));
|
|
93
93
|
// Row data
|
|
94
94
|
const tableRowDiffs = [];
|
|
95
95
|
let totalRowDiffs = 0;
|
|
96
|
-
if (options.
|
|
97
|
-
const leftDumps = new Map(left.data.map((d) => [qname(d.
|
|
98
|
-
const rightDumps = new Map(right.data.map((d) => [qname(d.
|
|
96
|
+
if (options.RowCompareMode !== 'none') {
|
|
97
|
+
const leftDumps = new Map(left.data.map((d) => [qname(d.Schema, d.Table), d]));
|
|
98
|
+
const rightDumps = new Map(right.data.map((d) => [qname(d.Schema, d.Table), d]));
|
|
99
99
|
for (const key of [...new Set([...leftDumps.keys(), ...rightDumps.keys()])].sort()) {
|
|
100
100
|
if (matchesIgnore(key))
|
|
101
101
|
continue;
|
|
@@ -104,40 +104,44 @@ export function compareSnapshots(input) {
|
|
|
104
104
|
if (!leftD || !rightD)
|
|
105
105
|
continue; // missing tables already reported as objectDiff
|
|
106
106
|
const td = diffTableRows(leftD, rightD, options);
|
|
107
|
-
if (td.
|
|
107
|
+
if (td.DiffCount > 0 || leftD.RowCount !== rightD.RowCount) {
|
|
108
108
|
tableRowDiffs.push(td);
|
|
109
|
-
totalRowDiffs += td.
|
|
109
|
+
totalRowDiffs += td.DiffCount;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
const summary = {
|
|
114
|
-
schemasChecked: left.snapshot.
|
|
114
|
+
schemasChecked: left.snapshot.Schemas.length,
|
|
115
115
|
tablesChecked: allTableKeys.size,
|
|
116
|
-
viewsChecked: Math.max(left.snapshot.
|
|
117
|
-
proceduresChecked: Math.max(left.snapshot.
|
|
118
|
-
functionsChecked: Math.max(left.snapshot.
|
|
119
|
-
triggersChecked: Math.max(left.snapshot.
|
|
120
|
-
sequencesChecked: Math.max(left.snapshot.
|
|
121
|
-
userDefinedTypesChecked: Math.max(left.snapshot.
|
|
122
|
-
extendedPropertiesChecked: Math.max(left.snapshot.
|
|
123
|
-
principalsChecked: Math.max(left.snapshot.
|
|
124
|
-
roleMembershipsChecked: Math.max(left.snapshot.
|
|
125
|
-
permissionsChecked: Math.max(left.snapshot.
|
|
116
|
+
viewsChecked: Math.max(left.snapshot.Views.length, right.snapshot.Views.length),
|
|
117
|
+
proceduresChecked: Math.max(left.snapshot.Procedures.length, right.snapshot.Procedures.length),
|
|
118
|
+
functionsChecked: Math.max(left.snapshot.Functions.length, right.snapshot.Functions.length),
|
|
119
|
+
triggersChecked: Math.max(left.snapshot.Triggers.length, right.snapshot.Triggers.length),
|
|
120
|
+
sequencesChecked: Math.max(left.snapshot.Sequences.length, right.snapshot.Sequences.length),
|
|
121
|
+
userDefinedTypesChecked: Math.max(left.snapshot.UserDefinedTypes.length, right.snapshot.UserDefinedTypes.length),
|
|
122
|
+
extendedPropertiesChecked: Math.max(left.snapshot.ExtendedProperties.length, right.snapshot.ExtendedProperties.length),
|
|
123
|
+
principalsChecked: Math.max(left.snapshot.Principals.length, right.snapshot.Principals.length),
|
|
124
|
+
roleMembershipsChecked: Math.max(left.snapshot.RoleMemberships.length, right.snapshot.RoleMemberships.length),
|
|
125
|
+
permissionsChecked: Math.max(left.snapshot.Permissions.length, right.snapshot.Permissions.length),
|
|
126
126
|
objectsWithDiffs,
|
|
127
127
|
tablesWithRowDiffs: tableRowDiffs.length,
|
|
128
128
|
totalRowDiffs,
|
|
129
129
|
};
|
|
130
130
|
return {
|
|
131
|
-
generatedAt:
|
|
131
|
+
generatedAt: IsoUtcSeconds(new Date()),
|
|
132
132
|
leftLabel: left.label,
|
|
133
133
|
rightLabel: right.label,
|
|
134
|
-
rowCompareMode: options.
|
|
134
|
+
rowCompareMode: options.RowCompareMode,
|
|
135
135
|
isClean: objectsWithDiffs === 0 && tableRowDiffs.length === 0,
|
|
136
|
-
objectDiffs:
|
|
136
|
+
objectDiffs: StableSortBy(objectDiffs, (d) => `${d.Kind}:${d.QualifiedName}`),
|
|
137
137
|
tableRowDiffs,
|
|
138
138
|
summary,
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
|
+
/** @deprecated Use {@link CompareSnapshots}. */
|
|
142
|
+
export function compareSnapshots(input) {
|
|
143
|
+
return CompareSnapshots(input);
|
|
144
|
+
}
|
|
141
145
|
function diffNamedSet(kind, leftItems, rightItems, qname, ignore, bodyDiff) {
|
|
142
146
|
const leftMap = new Map(leftItems.map((i) => [qname(i).toLowerCase(), i]));
|
|
143
147
|
const rightMap = new Map(rightItems.map((i) => [qname(i).toLowerCase(), i]));
|
|
@@ -149,31 +153,31 @@ function diffNamedSet(kind, leftItems, rightItems, qname, ignore, bodyDiff) {
|
|
|
149
153
|
const l = leftMap.get(key);
|
|
150
154
|
const r = rightMap.get(key);
|
|
151
155
|
if (!l && r)
|
|
152
|
-
out.push({ kind,
|
|
156
|
+
out.push({ Kind: kind, DiffKind: 'missing-on-left', QualifiedName: key });
|
|
153
157
|
else if (l && !r)
|
|
154
|
-
out.push({ kind,
|
|
158
|
+
out.push({ Kind: kind, DiffKind: 'missing-on-right', QualifiedName: key });
|
|
155
159
|
else if (l && r && bodyDiff) {
|
|
156
160
|
const detail = bodyDiff(l, r);
|
|
157
161
|
if (detail)
|
|
158
|
-
out.push({ kind,
|
|
162
|
+
out.push({ Kind: kind, DiffKind: 'changed', QualifiedName: key, Details: detail });
|
|
159
163
|
}
|
|
160
164
|
}
|
|
161
165
|
return out;
|
|
162
166
|
}
|
|
163
167
|
function diffTable(left, right) {
|
|
164
168
|
const out = [];
|
|
165
|
-
const tableQ = `${left.
|
|
169
|
+
const tableQ = `${left.Schema}.${left.Name}`;
|
|
166
170
|
// Columns
|
|
167
|
-
const lCols = new Map(left.
|
|
168
|
-
const rCols = new Map(right.
|
|
171
|
+
const lCols = new Map(left.Columns.map((c) => [c.name.toLowerCase(), c]));
|
|
172
|
+
const rCols = new Map(right.Columns.map((c) => [c.name.toLowerCase(), c]));
|
|
169
173
|
for (const name of new Set([...lCols.keys(), ...rCols.keys()])) {
|
|
170
174
|
const l = lCols.get(name);
|
|
171
175
|
const r = rCols.get(name);
|
|
172
176
|
const q = `${tableQ}.${name}`;
|
|
173
177
|
if (!l && r)
|
|
174
|
-
out.push({
|
|
178
|
+
out.push({ Kind: 'column', DiffKind: 'missing-on-left', QualifiedName: q });
|
|
175
179
|
else if (l && !r)
|
|
176
|
-
out.push({
|
|
180
|
+
out.push({ Kind: 'column', DiffKind: 'missing-on-right', QualifiedName: q });
|
|
177
181
|
else if (l && r) {
|
|
178
182
|
const fields = [];
|
|
179
183
|
if (l.dataType.toLowerCase() !== r.dataType.toLowerCase())
|
|
@@ -195,36 +199,36 @@ function diffTable(left, right) {
|
|
|
195
199
|
if (normalizeDefault(l.defaultExpression) !== normalizeDefault(r.defaultExpression))
|
|
196
200
|
fields.push(`default: ${l.defaultExpression} vs ${r.defaultExpression}`);
|
|
197
201
|
if (fields.length)
|
|
198
|
-
out.push({
|
|
202
|
+
out.push({ Kind: 'column', DiffKind: 'changed', QualifiedName: q, Details: fields.join('; ') });
|
|
199
203
|
}
|
|
200
204
|
}
|
|
201
205
|
// Primary key
|
|
202
|
-
if (!!left.
|
|
206
|
+
if (!!left.PrimaryKey !== !!right.PrimaryKey) {
|
|
203
207
|
out.push({
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
Kind: 'primaryKey',
|
|
209
|
+
DiffKind: left.PrimaryKey ? 'missing-on-right' : 'missing-on-left',
|
|
210
|
+
QualifiedName: tableQ,
|
|
207
211
|
});
|
|
208
212
|
}
|
|
209
|
-
else if (left.
|
|
213
|
+
else if (left.PrimaryKey && right.PrimaryKey) {
|
|
210
214
|
const reasons = [];
|
|
211
|
-
if (left.
|
|
212
|
-
reasons.push(`pk columns: ${left.
|
|
213
|
-
if (left.
|
|
214
|
-
reasons.push(`pk clustered: ${left.
|
|
215
|
-
if (left.
|
|
216
|
-
reasons.push(`pk name: ${left.
|
|
215
|
+
if (left.PrimaryKey.Columns.join(',') !== right.PrimaryKey.Columns.join(','))
|
|
216
|
+
reasons.push(`pk columns: ${left.PrimaryKey.Columns} vs ${right.PrimaryKey.Columns}`);
|
|
217
|
+
if (left.PrimaryKey.Clustered !== right.PrimaryKey.Clustered)
|
|
218
|
+
reasons.push(`pk clustered: ${left.PrimaryKey.Clustered} vs ${right.PrimaryKey.Clustered}`);
|
|
219
|
+
if (left.PrimaryKey.Name !== right.PrimaryKey.Name)
|
|
220
|
+
reasons.push(`pk name: ${left.PrimaryKey.Name} vs ${right.PrimaryKey.Name}`);
|
|
217
221
|
if (reasons.length) {
|
|
218
222
|
out.push({
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
Kind: 'primaryKey',
|
|
224
|
+
DiffKind: 'changed',
|
|
225
|
+
QualifiedName: tableQ,
|
|
226
|
+
Details: reasons.join('; '),
|
|
223
227
|
});
|
|
224
228
|
}
|
|
225
229
|
}
|
|
226
230
|
// Unique constraints (previously uncompared — silent gap)
|
|
227
|
-
out.push(...diffNamedSet('uniqueConstraint', left.
|
|
231
|
+
out.push(...diffNamedSet('uniqueConstraint', left.UniqueConstraints, right.UniqueConstraints, (u) => `${tableQ}.${u.name}`, () => false, (l, r) => {
|
|
228
232
|
if (l.columns.join(',') !== r.columns.join(','))
|
|
229
233
|
return 'unique constraint columns differ';
|
|
230
234
|
if (l.clustered !== r.clustered)
|
|
@@ -232,7 +236,7 @@ function diffTable(left, right) {
|
|
|
232
236
|
return null;
|
|
233
237
|
}));
|
|
234
238
|
// Indexes
|
|
235
|
-
out.push(...diffNamedSet('index', left.
|
|
239
|
+
out.push(...diffNamedSet('index', left.Indexes, right.Indexes, (i) => `${tableQ}.${i.name}`, () => false, (l, r) => {
|
|
236
240
|
if (l.columns.join(',') !== r.columns.join(','))
|
|
237
241
|
return `index columns differ: ${l.columns} vs ${r.columns}`;
|
|
238
242
|
if (l.includes.join(',') !== r.includes.join(','))
|
|
@@ -246,7 +250,7 @@ function diffTable(left, right) {
|
|
|
246
250
|
return null;
|
|
247
251
|
}));
|
|
248
252
|
// FKs
|
|
249
|
-
out.push(...diffNamedSet('foreignKey', left.
|
|
253
|
+
out.push(...diffNamedSet('foreignKey', left.ForeignKeys, right.ForeignKeys, (f) => `${tableQ}.${f.name}`, () => false, (l, r) => {
|
|
250
254
|
if (l.columns.join(',') !== r.columns.join(','))
|
|
251
255
|
return 'fk columns differ';
|
|
252
256
|
if (l.referencedSchema !== r.referencedSchema || l.referencedTable !== r.referencedTable)
|
|
@@ -260,74 +264,74 @@ function diffTable(left, right) {
|
|
|
260
264
|
return null;
|
|
261
265
|
}));
|
|
262
266
|
// Checks
|
|
263
|
-
out.push(...diffNamedSet('check', left.
|
|
267
|
+
out.push(...diffNamedSet('check', left.Checks, right.Checks, (c) => `${tableQ}.${c.name}`, () => false, (l, r) => normalizeBody(l.expression) === normalizeBody(r.expression) ? null : 'check expression differs'));
|
|
264
268
|
return out;
|
|
265
269
|
}
|
|
266
270
|
function diffTableRows(left, right, options) {
|
|
267
271
|
const sample = [];
|
|
268
272
|
let diffCount = 0;
|
|
269
|
-
const limit = options.
|
|
273
|
+
const limit = options.RowDiffSampleLimit;
|
|
270
274
|
const cap = (rd) => {
|
|
271
275
|
diffCount++;
|
|
272
276
|
if (sample.length < limit)
|
|
273
277
|
sample.push(rd);
|
|
274
278
|
};
|
|
275
|
-
if (options.
|
|
276
|
-
if (left.
|
|
277
|
-
cap({
|
|
279
|
+
if (options.RowCompareMode === 'counts') {
|
|
280
|
+
if (left.RowCount !== right.RowCount)
|
|
281
|
+
cap({ DiffKind: 'changed', Key: '*', ColumnDiffs: [] });
|
|
278
282
|
return {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
diffCount,
|
|
283
|
+
Schema: left.Schema,
|
|
284
|
+
Table: left.Table,
|
|
285
|
+
LeftRowCount: left.RowCount,
|
|
286
|
+
RightRowCount: right.RowCount,
|
|
287
|
+
SampleDiffs: sample,
|
|
288
|
+
Truncated: false,
|
|
289
|
+
DiffCount: diffCount,
|
|
286
290
|
};
|
|
287
291
|
}
|
|
288
292
|
// Both rows[] are pre-ordered (PK then col order). Walk in lock-step using
|
|
289
293
|
// a stringified row key to align even when the two sides have inserts/deletes.
|
|
290
|
-
const leftKeys = left.
|
|
291
|
-
const rightKeys = right.
|
|
294
|
+
const leftKeys = left.Rows.map((r) => keyForRow(r, left.Columns));
|
|
295
|
+
const rightKeys = right.Rows.map((r) => keyForRow(r, right.Columns));
|
|
292
296
|
const leftIndex = new Map(leftKeys.map((k, i) => [k, i]));
|
|
293
297
|
const rightIndex = new Map(rightKeys.map((k, i) => [k, i]));
|
|
294
298
|
for (let i = 0; i < leftKeys.length; i++) {
|
|
295
299
|
const k = leftKeys[i];
|
|
296
300
|
const ri = rightIndex.get(k);
|
|
297
301
|
if (ri === undefined) {
|
|
298
|
-
cap({
|
|
302
|
+
cap({ DiffKind: 'missing-on-right', Key: k });
|
|
299
303
|
continue;
|
|
300
304
|
}
|
|
301
|
-
if (options.
|
|
302
|
-
const lRow = left.
|
|
303
|
-
const rRow = right.
|
|
305
|
+
if (options.RowCompareMode === 'full') {
|
|
306
|
+
const lRow = left.Rows[i];
|
|
307
|
+
const rRow = right.Rows[ri];
|
|
304
308
|
const colDiffs = [];
|
|
305
|
-
for (let c = 0; c < left.
|
|
306
|
-
const colName = left.
|
|
307
|
-
const rIdx = right.
|
|
309
|
+
for (let c = 0; c < left.Columns.length; c++) {
|
|
310
|
+
const colName = left.Columns[c];
|
|
311
|
+
const rIdx = right.Columns.indexOf(colName);
|
|
308
312
|
if (rIdx === -1)
|
|
309
313
|
continue;
|
|
310
|
-
if (!
|
|
311
|
-
colDiffs.push({
|
|
314
|
+
if (!DeepValueEqual(lRow[c], rRow[rIdx])) {
|
|
315
|
+
colDiffs.push({ Column: colName, LeftValue: lRow[c], RightValue: rRow[rIdx] });
|
|
312
316
|
}
|
|
313
317
|
}
|
|
314
318
|
if (colDiffs.length > 0)
|
|
315
|
-
cap({
|
|
319
|
+
cap({ DiffKind: 'changed', Key: k, ColumnDiffs: colDiffs });
|
|
316
320
|
}
|
|
317
321
|
}
|
|
318
322
|
for (let i = 0; i < rightKeys.length; i++) {
|
|
319
323
|
const k = rightKeys[i];
|
|
320
324
|
if (!leftIndex.has(k))
|
|
321
|
-
cap({
|
|
325
|
+
cap({ DiffKind: 'missing-on-left', Key: k });
|
|
322
326
|
}
|
|
323
327
|
return {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
diffCount,
|
|
328
|
+
Schema: left.Schema,
|
|
329
|
+
Table: left.Table,
|
|
330
|
+
LeftRowCount: left.RowCount,
|
|
331
|
+
RightRowCount: right.RowCount,
|
|
332
|
+
SampleDiffs: sample,
|
|
333
|
+
Truncated: diffCount > sample.length,
|
|
334
|
+
DiffCount: diffCount,
|
|
331
335
|
};
|
|
332
336
|
}
|
|
333
337
|
function keyForRow(row, _columns) {
|
|
@@ -381,21 +385,21 @@ function normalizeDefault(value) {
|
|
|
381
385
|
}
|
|
382
386
|
/** Diff user-defined types (table types). Comparison is structural: same columns, same PK, same memory-optimization. */
|
|
383
387
|
function diffUserDefinedTypes(left, right, ignore) {
|
|
384
|
-
return diffNamedSet('userDefinedType', left, right, (t) => `${t.
|
|
388
|
+
return diffNamedSet('userDefinedType', left, right, (t) => `${t.Schema}.${t.Name}`, ignore, (l, r) => {
|
|
385
389
|
const reasons = [];
|
|
386
|
-
if (l.
|
|
387
|
-
reasons.push(`kind: ${l.
|
|
388
|
-
if (l.
|
|
390
|
+
if (l.Kind !== r.Kind)
|
|
391
|
+
reasons.push(`kind: ${l.Kind} vs ${r.Kind}`);
|
|
392
|
+
if (l.IsMemoryOptimized !== r.IsMemoryOptimized)
|
|
389
393
|
reasons.push('memory-optimized differs');
|
|
390
394
|
// Column-by-column structural diff. Order matters (TVPs have a fixed
|
|
391
395
|
// column ordinal that affects INSERT compatibility).
|
|
392
|
-
if (l.
|
|
393
|
-
reasons.push(`column count: ${l.
|
|
396
|
+
if (l.Columns.length !== r.Columns.length) {
|
|
397
|
+
reasons.push(`column count: ${l.Columns.length} vs ${r.Columns.length}`);
|
|
394
398
|
}
|
|
395
399
|
else {
|
|
396
|
-
for (let i = 0; i < l.
|
|
397
|
-
const lc = l.
|
|
398
|
-
const rc = r.
|
|
400
|
+
for (let i = 0; i < l.Columns.length; i++) {
|
|
401
|
+
const lc = l.Columns[i];
|
|
402
|
+
const rc = r.Columns[i];
|
|
399
403
|
if (lc.name !== rc.name)
|
|
400
404
|
reasons.push(`col[${i}] name: ${lc.name} vs ${rc.name}`);
|
|
401
405
|
if (lc.dataType.toLowerCase() !== rc.dataType.toLowerCase())
|
|
@@ -404,8 +408,8 @@ function diffUserDefinedTypes(left, right, ignore) {
|
|
|
404
408
|
reasons.push(`col[${i}] nullable: ${lc.isNullable} vs ${rc.isNullable}`);
|
|
405
409
|
}
|
|
406
410
|
}
|
|
407
|
-
const lPkCols = l.
|
|
408
|
-
const rPkCols = r.
|
|
411
|
+
const lPkCols = l.PrimaryKey?.Columns.join(',') ?? '';
|
|
412
|
+
const rPkCols = r.PrimaryKey?.Columns.join(',') ?? '';
|
|
409
413
|
if (lPkCols !== rPkCols)
|
|
410
414
|
reasons.push(`pk columns: ${lPkCols} vs ${rPkCols}`);
|
|
411
415
|
return reasons.length === 0 ? null : reasons.join('; ');
|
|
@@ -417,12 +421,12 @@ function diffUserDefinedTypes(left, right, ignore) {
|
|
|
417
421
|
*/
|
|
418
422
|
function diffExtendedProperties(left, right) {
|
|
419
423
|
const key = (p) => [
|
|
420
|
-
p.
|
|
421
|
-
p.
|
|
422
|
-
p.
|
|
423
|
-
p.
|
|
424
|
-
p.
|
|
425
|
-
p.
|
|
424
|
+
p.SchemaName,
|
|
425
|
+
p.Level1Type ?? '',
|
|
426
|
+
p.Level1Name ?? '',
|
|
427
|
+
p.Level2Type ?? '',
|
|
428
|
+
p.Level2Name ?? '',
|
|
429
|
+
p.Name,
|
|
426
430
|
]
|
|
427
431
|
.join('::')
|
|
428
432
|
.toLowerCase();
|
|
@@ -434,17 +438,17 @@ function diffExtendedProperties(left, right) {
|
|
|
434
438
|
const l = leftMap.get(k);
|
|
435
439
|
const r = rightMap.get(k);
|
|
436
440
|
if (!l && r)
|
|
437
|
-
out.push({
|
|
441
|
+
out.push({ Kind: 'extendedProperty', DiffKind: 'missing-on-left', QualifiedName: k });
|
|
438
442
|
else if (l && !r)
|
|
439
|
-
out.push({
|
|
440
|
-
else if (l && r && l.
|
|
443
|
+
out.push({ Kind: 'extendedProperty', DiffKind: 'missing-on-right', QualifiedName: k });
|
|
444
|
+
else if (l && r && l.Value !== r.Value) {
|
|
441
445
|
out.push({
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
446
|
+
Kind: 'extendedProperty',
|
|
447
|
+
DiffKind: 'changed',
|
|
448
|
+
QualifiedName: k,
|
|
449
|
+
Details: `value differs`,
|
|
450
|
+
LeftValue: l.Value,
|
|
451
|
+
RightValue: r.Value,
|
|
448
452
|
});
|
|
449
453
|
}
|
|
450
454
|
}
|
|
@@ -452,18 +456,18 @@ function diffExtendedProperties(left, right) {
|
|
|
452
456
|
}
|
|
453
457
|
/** Diff database principals (users + custom roles). Matched by name; kind/owner/defaultSchema compared. */
|
|
454
458
|
function diffPrincipals(left, right) {
|
|
455
|
-
return diffNamedSet('principal', left, right, (p) => p.
|
|
459
|
+
return diffNamedSet('principal', left, right, (p) => p.Name, () => false, (l, r) => {
|
|
456
460
|
const reasons = [];
|
|
457
|
-
if (l.
|
|
458
|
-
reasons.push(`kind: ${l.
|
|
461
|
+
if (l.Kind !== r.Kind)
|
|
462
|
+
reasons.push(`kind: ${l.Kind} vs ${r.Kind}`);
|
|
459
463
|
// Owner mismatch is informational only — emitted CREATE ROLE matches the
|
|
460
464
|
// source's AUTHORIZATION clause. Skip if either side is missing the owner
|
|
461
465
|
// (older snapshots / future formats may omit it).
|
|
462
|
-
if (l.
|
|
463
|
-
reasons.push(`owner: ${l.
|
|
466
|
+
if (l.Owner && r.Owner && l.Owner.toLowerCase() !== r.Owner.toLowerCase()) {
|
|
467
|
+
reasons.push(`owner: ${l.Owner} vs ${r.Owner}`);
|
|
464
468
|
}
|
|
465
|
-
if ((l.
|
|
466
|
-
reasons.push(`defaultSchema: ${l.
|
|
469
|
+
if ((l.DefaultSchema || '').toLowerCase() !== (r.DefaultSchema || '').toLowerCase()) {
|
|
470
|
+
reasons.push(`defaultSchema: ${l.DefaultSchema} vs ${r.DefaultSchema}`);
|
|
467
471
|
}
|
|
468
472
|
return reasons.length === 0 ? null : reasons.join('; ');
|
|
469
473
|
});
|
|
@@ -479,9 +483,9 @@ function diffRoleMemberships(left, right) {
|
|
|
479
483
|
const inL = leftMap.has(k);
|
|
480
484
|
const inR = rightMap.has(k);
|
|
481
485
|
if (inL && !inR)
|
|
482
|
-
out.push({
|
|
486
|
+
out.push({ Kind: 'roleMembership', DiffKind: 'missing-on-right', QualifiedName: k });
|
|
483
487
|
else if (!inL && inR)
|
|
484
|
-
out.push({
|
|
488
|
+
out.push({ Kind: 'roleMembership', DiffKind: 'missing-on-left', QualifiedName: k });
|
|
485
489
|
}
|
|
486
490
|
return out;
|
|
487
491
|
}
|
|
@@ -510,15 +514,15 @@ function diffPermissions(left, right) {
|
|
|
510
514
|
const l = leftMap.get(k);
|
|
511
515
|
const r = rightMap.get(k);
|
|
512
516
|
if (l && !r)
|
|
513
|
-
out.push({
|
|
517
|
+
out.push({ Kind: 'permission', DiffKind: 'missing-on-right', QualifiedName: k });
|
|
514
518
|
else if (!l && r)
|
|
515
|
-
out.push({
|
|
519
|
+
out.push({ Kind: 'permission', DiffKind: 'missing-on-left', QualifiedName: k });
|
|
516
520
|
else if (l && r && l.state !== r.state) {
|
|
517
521
|
out.push({
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
+
Kind: 'permission',
|
|
523
|
+
DiffKind: 'changed',
|
|
524
|
+
QualifiedName: k,
|
|
525
|
+
Details: `state: ${l.state} vs ${r.state}`,
|
|
522
526
|
});
|
|
523
527
|
}
|
|
524
528
|
}
|