@memberjunction/cli 5.37.0 → 5.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -0
- package/dist/baseline/cli-helpers.d.ts +12 -0
- package/dist/baseline/cli-helpers.d.ts.map +1 -0
- package/dist/baseline/cli-helpers.js +40 -0
- package/dist/baseline/cli-helpers.js.map +1 -0
- package/dist/baseline/comparator.d.ts +26 -0
- package/dist/baseline/comparator.d.ts.map +1 -0
- package/dist/baseline/comparator.js +527 -0
- package/dist/baseline/comparator.js.map +1 -0
- package/dist/baseline/connection.d.ts +39 -0
- package/dist/baseline/connection.d.ts.map +1 -0
- package/dist/baseline/connection.js +104 -0
- package/dist/baseline/connection.js.map +1 -0
- package/dist/baseline/data-dumper.d.ts +23 -0
- package/dist/baseline/data-dumper.d.ts.map +1 -0
- package/dist/baseline/data-dumper.js +94 -0
- package/dist/baseline/data-dumper.js.map +1 -0
- package/dist/baseline/emitter.d.ts +36 -0
- package/dist/baseline/emitter.d.ts.map +1 -0
- package/dist/baseline/emitter.js +512 -0
- package/dist/baseline/emitter.js.map +1 -0
- package/dist/baseline/index.d.ts +18 -0
- package/dist/baseline/index.d.ts.map +1 -0
- package/dist/baseline/index.js +14 -0
- package/dist/baseline/index.js.map +1 -0
- package/dist/baseline/introspector-mssql.d.ts +15 -0
- package/dist/baseline/introspector-mssql.d.ts.map +1 -0
- package/dist/baseline/introspector-mssql.js +673 -0
- package/dist/baseline/introspector-mssql.js.map +1 -0
- package/dist/baseline/introspector-postgres.d.ts +14 -0
- package/dist/baseline/introspector-postgres.d.ts.map +1 -0
- package/dist/baseline/introspector-postgres.js +277 -0
- package/dist/baseline/introspector-postgres.js.map +1 -0
- package/dist/baseline/report.d.ts +7 -0
- package/dist/baseline/report.d.ts.map +1 -0
- package/dist/baseline/report.js +105 -0
- package/dist/baseline/report.js.map +1 -0
- package/dist/baseline/types.d.ts +286 -0
- package/dist/baseline/types.d.ts.map +1 -0
- package/dist/baseline/types.js +10 -0
- package/dist/baseline/types.js.map +1 -0
- package/dist/baseline/util.d.ts +112 -0
- package/dist/baseline/util.d.ts.map +1 -0
- package/dist/baseline/util.js +325 -0
- package/dist/baseline/util.js.map +1 -0
- package/dist/commands/baseline/build.d.ts +29 -0
- package/dist/commands/baseline/build.d.ts.map +1 -0
- package/dist/commands/baseline/build.js +188 -0
- package/dist/commands/baseline/build.js.map +1 -0
- package/dist/commands/baseline/compare.d.ts +19 -0
- package/dist/commands/baseline/compare.d.ts.map +1 -0
- package/dist/commands/baseline/compare.js +133 -0
- package/dist/commands/baseline/compare.js.map +1 -0
- package/dist/commands/baseline/roundtrip.d.ts +23 -0
- package/dist/commands/baseline/roundtrip.d.ts.map +1 -0
- package/dist/commands/baseline/roundtrip.js +245 -0
- package/dist/commands/baseline/roundtrip.js.map +1 -0
- package/dist/commands/test/compare.d.ts +3 -0
- package/dist/commands/test/compare.d.ts.map +1 -1
- package/dist/commands/test/compare.js +23 -3
- package/dist/commands/test/compare.js.map +1 -1
- package/dist/commands/test/regression/build.d.ts +14 -0
- package/dist/commands/test/regression/build.d.ts.map +1 -0
- package/dist/commands/test/regression/build.js +48 -0
- package/dist/commands/test/regression/build.js.map +1 -0
- package/dist/commands/test/regression/compare.d.ts +15 -0
- package/dist/commands/test/regression/compare.d.ts.map +1 -0
- package/dist/commands/test/regression/compare.js +66 -0
- package/dist/commands/test/regression/compare.js.map +1 -0
- package/dist/commands/test/regression/down.d.ts +10 -0
- package/dist/commands/test/regression/down.d.ts.map +1 -0
- package/dist/commands/test/regression/down.js +29 -0
- package/dist/commands/test/regression/down.js.map +1 -0
- package/dist/commands/test/regression/export.d.ts +11 -0
- package/dist/commands/test/regression/export.d.ts.map +1 -0
- package/dist/commands/test/regression/export.js +56 -0
- package/dist/commands/test/regression/export.js.map +1 -0
- package/dist/commands/test/regression/gen-forms.d.ts +7 -0
- package/dist/commands/test/regression/gen-forms.d.ts.map +1 -0
- package/dist/commands/test/regression/gen-forms.js +18 -0
- package/dist/commands/test/regression/gen-forms.js.map +1 -0
- package/dist/commands/test/regression/index.d.ts +7 -0
- package/dist/commands/test/regression/index.d.ts.map +1 -0
- package/dist/commands/test/regression/index.js +33 -0
- package/dist/commands/test/regression/index.js.map +1 -0
- package/dist/commands/test/regression/init.d.ts +21 -0
- package/dist/commands/test/regression/init.d.ts.map +1 -0
- package/dist/commands/test/regression/init.js +111 -0
- package/dist/commands/test/regression/init.js.map +1 -0
- package/dist/commands/test/regression/remote.d.ts +23 -0
- package/dist/commands/test/regression/remote.d.ts.map +1 -0
- package/dist/commands/test/regression/remote.js +140 -0
- package/dist/commands/test/regression/remote.js.map +1 -0
- package/dist/commands/test/regression/up.d.ts +21 -0
- package/dist/commands/test/regression/up.d.ts.map +1 -0
- package/dist/commands/test/regression/up.js +111 -0
- package/dist/commands/test/regression/up.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 +6 -0
- package/dist/commands/test/run.js.map +1 -1
- package/dist/commands/test/suite.d.ts +5 -0
- package/dist/commands/test/suite.d.ts.map +1 -1
- package/dist/commands/test/suite.js +27 -0
- package/dist/commands/test/suite.js.map +1 -1
- package/dist/commands/translate-sql/index.d.ts.map +1 -1
- package/dist/commands/translate-sql/index.js +3 -2
- package/dist/commands/translate-sql/index.js.map +1 -1
- package/dist/init-templates/bring-your-own-app/README.md +74 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/.mj-sync.json +10 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/test-suites/.byo-suite.json +51 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/test-suites/.mj-sync.json +12 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/tests/.T01-counter-increment.json +63 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/tests/.T02-contact-form-submit.json +63 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/tests/.mj-sync.json +12 -0
- package/dist/init-templates/bring-your-own-app/docker-compose.app.yml +76 -0
- package/dist/init-templates/bring-your-own-app/target.json +23 -0
- package/dist/init-templates/generic-web/README.md +115 -0
- package/dist/init-templates/generic-web/metadata/.mj-sync.json +10 -0
- package/dist/init-templates/generic-web/metadata/test-suites/.generic-web-suite.json +48 -0
- package/dist/init-templates/generic-web/metadata/test-suites/.mj-sync.json +12 -0
- package/dist/init-templates/generic-web/metadata/tests/.GW01-home-loads.json +74 -0
- package/dist/init-templates/generic-web/metadata/tests/.GW02-search-array-map.json +82 -0
- package/dist/init-templates/generic-web/metadata/tests/.mj-sync.json +12 -0
- package/dist/init-templates/generic-web/oracles/mdn-oracles.cjs +121 -0
- package/dist/init-templates/generic-web/target.json +25 -0
- package/dist/init-templates/github-actions/README.md +26 -0
- package/dist/init-templates/github-actions/regression.yml +52 -0
- package/dist/init-templates/remote-mj/README.md +95 -0
- package/dist/init-templates/remote-mj/target.json +22 -0
- package/dist/init-templates/static-file-server/Dockerfile +23 -0
- package/dist/init-templates/static-file-server/README.md +88 -0
- package/dist/init-templates/static-file-server/docker-compose.app.yml +44 -0
- package/dist/init-templates/static-file-server/metadata/.mj-sync.json +10 -0
- package/dist/init-templates/static-file-server/metadata/test-suites/.mj-sync.json +12 -0
- package/dist/init-templates/static-file-server/metadata/test-suites/.static-server-suite.json +27 -0
- package/dist/init-templates/static-file-server/metadata/tests/.SS01-home-loads.json +45 -0
- package/dist/init-templates/static-file-server/metadata/tests/.SS02-navigate-about.json +45 -0
- package/dist/init-templates/static-file-server/metadata/tests/.mj-sync.json +12 -0
- package/dist/init-templates/static-file-server/public/about.html +12 -0
- package/dist/init-templates/static-file-server/public/index.html +27 -0
- package/dist/init-templates/static-file-server/target.json +16 -0
- package/dist/lib/regression/docker-helpers.d.ts +98 -0
- package/dist/lib/regression/docker-helpers.d.ts.map +1 -0
- package/dist/lib/regression/docker-helpers.js +184 -0
- package/dist/lib/regression/docker-helpers.js.map +1 -0
- package/oclif.manifest.json +1356 -509
- package/package.json +22 -17
- package/regression-compose/docker-compose.bacpac-standalone.yml +109 -0
- package/regression-compose/docker-compose.standalone.yml +50 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical formatting helpers used by the emitter and comparator.
|
|
3
|
+
*
|
|
4
|
+
* Determinism is the contract: identical input must produce byte-identical
|
|
5
|
+
* output, regardless of host OS, locale, or run order.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
/** Lower-case schema-qualified name used for sort keys and sets. */
|
|
10
|
+
export function qname(schema, name) {
|
|
11
|
+
return `${schema}.${name}`.toLowerCase();
|
|
12
|
+
}
|
|
13
|
+
/** Quote a T-SQL identifier with brackets, escaping any embedded `]`. */
|
|
14
|
+
export function quoteIdent(name) {
|
|
15
|
+
return `[${name.replace(/]/g, ']]')}]`;
|
|
16
|
+
}
|
|
17
|
+
/** Quote a T-SQL string literal, escaping single quotes. */
|
|
18
|
+
export function quoteString(value) {
|
|
19
|
+
return `N'${value.replace(/'/g, "''")}'`;
|
|
20
|
+
}
|
|
21
|
+
/** Stable sort by a key extractor; preserves input order for ties. */
|
|
22
|
+
export function stableSortBy(items, key) {
|
|
23
|
+
return items
|
|
24
|
+
.map((item, index) => ({ item, index, key: key(item) }))
|
|
25
|
+
.sort((a, b) => {
|
|
26
|
+
if (a.key < b.key)
|
|
27
|
+
return -1;
|
|
28
|
+
if (a.key > b.key)
|
|
29
|
+
return 1;
|
|
30
|
+
return a.index - b.index;
|
|
31
|
+
})
|
|
32
|
+
.map((wrapped) => wrapped.item);
|
|
33
|
+
}
|
|
34
|
+
/** Cross-platform line endings: emit LF only. Caller normalizes if needed. */
|
|
35
|
+
export const NL = '\n';
|
|
36
|
+
/**
|
|
37
|
+
* Tables that must never appear in the emitted baseline — they belong to the
|
|
38
|
+
* migration tool itself and get created automatically before the baseline runs.
|
|
39
|
+
* Match by table name only (schema-independent) because Skyway can be configured
|
|
40
|
+
* to put `flyway_schema_history` in any schema (MJ uses `__mj`, default is `dbo`).
|
|
41
|
+
*/
|
|
42
|
+
export const EXCLUDED_TABLE_NAMES = new Set(['flyway_schema_history']);
|
|
43
|
+
/** Returns true if a table (by bare name) is one we never emit in a baseline. */
|
|
44
|
+
export function isExcludedTable(name) {
|
|
45
|
+
return EXCLUDED_TABLE_NAMES.has(name.toLowerCase());
|
|
46
|
+
}
|
|
47
|
+
/** Canonical ISO-8601 UTC stamp without milliseconds: 2026-05-02T19:47:00Z. */
|
|
48
|
+
export function isoUtcSeconds(date) {
|
|
49
|
+
return date.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
50
|
+
}
|
|
51
|
+
/** Filename timestamp: YYYYMMDDHHMM in UTC. */
|
|
52
|
+
export function fileStamp(date) {
|
|
53
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
54
|
+
return (date.getUTCFullYear().toString() +
|
|
55
|
+
pad(date.getUTCMonth() + 1) +
|
|
56
|
+
pad(date.getUTCDate()) +
|
|
57
|
+
pad(date.getUTCHours()) +
|
|
58
|
+
pad(date.getUTCMinutes()));
|
|
59
|
+
}
|
|
60
|
+
/** Build the canonical filename for a baseline migration. */
|
|
61
|
+
export function baselineFilename(opts) {
|
|
62
|
+
return `B${fileStamp(opts.generatedAtUtc)}__v${opts.baselineVersion}.x__Baseline.sql`;
|
|
63
|
+
}
|
|
64
|
+
/** Inverse of {@link fileStamp}: parses a YYYYMMDDHHMM string into a UTC Date. */
|
|
65
|
+
export function parseFileStamp(stamp) {
|
|
66
|
+
if (!/^\d{12}$/.test(stamp)) {
|
|
67
|
+
throw new Error(`Invalid YYYYMMDDHHMM stamp: ${stamp}`);
|
|
68
|
+
}
|
|
69
|
+
const y = Number(stamp.slice(0, 4));
|
|
70
|
+
const mo = Number(stamp.slice(4, 6)) - 1;
|
|
71
|
+
const d = Number(stamp.slice(6, 8));
|
|
72
|
+
const h = Number(stamp.slice(8, 10));
|
|
73
|
+
const mi = Number(stamp.slice(10, 12));
|
|
74
|
+
return new Date(Date.UTC(y, mo, d, h, mi));
|
|
75
|
+
}
|
|
76
|
+
/** Return a new Date offset by N minutes (negative for past). */
|
|
77
|
+
export function addMinutes(date, minutes) {
|
|
78
|
+
return new Date(date.getTime() + minutes * 60_000);
|
|
79
|
+
}
|
|
80
|
+
export function parseMigrationFilename(filename) {
|
|
81
|
+
const match = /^([VB])(\d{12})__v(\d+)\.(\d+)/.exec(filename);
|
|
82
|
+
if (!match)
|
|
83
|
+
return null;
|
|
84
|
+
return {
|
|
85
|
+
kind: match[1],
|
|
86
|
+
timestamp: match[2],
|
|
87
|
+
major: Number(match[3]),
|
|
88
|
+
minor: Number(match[4]),
|
|
89
|
+
majorMinor: `${match[3]}.${match[4]}`,
|
|
90
|
+
filename,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Scan a migrations source directory and return the latest V-file by timestamp.
|
|
95
|
+
* Files that don't match the expected shape are silently ignored.
|
|
96
|
+
*
|
|
97
|
+
* Used by within-major rebaseline to derive the new baseline's version + timestamp
|
|
98
|
+
* from the head of the existing V-stack.
|
|
99
|
+
*/
|
|
100
|
+
export function findLatestVersionedMigration(sourceDir) {
|
|
101
|
+
if (!fs.existsSync(sourceDir) || !fs.statSync(sourceDir).isDirectory()) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const entries = fs.readdirSync(sourceDir);
|
|
105
|
+
let best = null;
|
|
106
|
+
for (const name of entries) {
|
|
107
|
+
if (!name.toLowerCase().endsWith('.sql'))
|
|
108
|
+
continue;
|
|
109
|
+
const parsed = parseMigrationFilename(name);
|
|
110
|
+
if (!parsed || parsed.kind !== 'V')
|
|
111
|
+
continue;
|
|
112
|
+
if (!best || parsed.timestamp > best.timestamp)
|
|
113
|
+
best = parsed;
|
|
114
|
+
}
|
|
115
|
+
return best;
|
|
116
|
+
}
|
|
117
|
+
/** Same as {@link findLatestVersionedMigration} but for `B`-prefixed baseline files. */
|
|
118
|
+
export function findLatestBaselineMigration(sourceDir) {
|
|
119
|
+
if (!fs.existsSync(sourceDir) || !fs.statSync(sourceDir).isDirectory()) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
const entries = fs.readdirSync(sourceDir);
|
|
123
|
+
let best = null;
|
|
124
|
+
for (const name of entries) {
|
|
125
|
+
if (!name.toLowerCase().endsWith('.sql'))
|
|
126
|
+
continue;
|
|
127
|
+
const parsed = parseMigrationFilename(name);
|
|
128
|
+
if (!parsed || parsed.kind !== 'B')
|
|
129
|
+
continue;
|
|
130
|
+
if (!best || parsed.timestamp > best.timestamp)
|
|
131
|
+
best = parsed;
|
|
132
|
+
}
|
|
133
|
+
return best;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Walk up from `cwd` looking for a `migrations/` directory, then return the path
|
|
137
|
+
* to the highest-numbered `vN/` subdirectory inside it. Returns null if nothing
|
|
138
|
+
* suitable is found.
|
|
139
|
+
*
|
|
140
|
+
* Stops walking at the filesystem root. Used so the CLI can auto-locate the
|
|
141
|
+
* source dir for within-major rebaseline without forcing the caller to pass `--source-dir`.
|
|
142
|
+
*/
|
|
143
|
+
export function discoverMigrationsSourceDir(cwd) {
|
|
144
|
+
let dir = path.resolve(cwd);
|
|
145
|
+
for (let i = 0; i < 16; i++) {
|
|
146
|
+
const candidate = path.join(dir, 'migrations');
|
|
147
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
|
|
148
|
+
const versioned = fs
|
|
149
|
+
.readdirSync(candidate)
|
|
150
|
+
.filter((name) => /^v\d+$/i.test(name))
|
|
151
|
+
.map((name) => ({ name, n: Number(name.slice(1)) }))
|
|
152
|
+
.sort((a, b) => b.n - a.n);
|
|
153
|
+
if (versioned.length > 0) {
|
|
154
|
+
return path.join(candidate, versioned[0].name);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const parent = path.dirname(dir);
|
|
158
|
+
if (parent === dir)
|
|
159
|
+
break;
|
|
160
|
+
dir = parent;
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Compute the canonical generated-at timestamp for a within-major rebaseline.
|
|
166
|
+
* The new baseline's filename timestamp is exactly 1 minute after the latest
|
|
167
|
+
* V-file's timestamp — guaranteeing the new B-file sorts after the V-stack it
|
|
168
|
+
* succeeds, while remaining deterministic across re-runs against the same input.
|
|
169
|
+
*/
|
|
170
|
+
export function computeAutoBaselineStamp(latestVTimestamp) {
|
|
171
|
+
const parsed = parseFileStamp(latestVTimestamp);
|
|
172
|
+
const next = addMinutes(parsed, 1);
|
|
173
|
+
return { generatedAtUtc: next, fileStamp: fileStamp(next) };
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Format a JS value as a T-SQL literal. Used by the data dumper.
|
|
177
|
+
* Returns `NULL` for null/undefined, otherwise a typed literal.
|
|
178
|
+
*/
|
|
179
|
+
export function formatTsqlValue(value) {
|
|
180
|
+
if (value === null || value === undefined)
|
|
181
|
+
return 'NULL';
|
|
182
|
+
if (typeof value === 'boolean')
|
|
183
|
+
return value ? '1' : '0';
|
|
184
|
+
if (typeof value === 'number') {
|
|
185
|
+
if (!Number.isFinite(value)) {
|
|
186
|
+
throw new Error(`Cannot serialize non-finite number: ${value}`);
|
|
187
|
+
}
|
|
188
|
+
return String(value);
|
|
189
|
+
}
|
|
190
|
+
if (typeof value === 'bigint')
|
|
191
|
+
return value.toString();
|
|
192
|
+
if (value instanceof Date) {
|
|
193
|
+
// datetime2 with full precision
|
|
194
|
+
const iso = value.toISOString(); // 2026-05-02T19:47:23.123Z
|
|
195
|
+
const stripped = iso.replace('T', ' ').replace('Z', '');
|
|
196
|
+
return `N'${stripped}'`;
|
|
197
|
+
}
|
|
198
|
+
if (Buffer.isBuffer(value)) {
|
|
199
|
+
return '0x' + value.toString('hex').toUpperCase();
|
|
200
|
+
}
|
|
201
|
+
if (value instanceof Uint8Array) {
|
|
202
|
+
return '0x' + Buffer.from(value).toString('hex').toUpperCase();
|
|
203
|
+
}
|
|
204
|
+
if (typeof value === 'string')
|
|
205
|
+
return quoteString(value);
|
|
206
|
+
if (typeof value === 'object') {
|
|
207
|
+
// Fallback: JSON-serialize objects (rare; mssql driver returns primitives)
|
|
208
|
+
return quoteString(JSON.stringify(value));
|
|
209
|
+
}
|
|
210
|
+
throw new Error(`Unsupported value type for T-SQL literal: ${typeof value}`);
|
|
211
|
+
}
|
|
212
|
+
/** Strict equality used by the comparator for column values. */
|
|
213
|
+
export function deepValueEqual(a, b) {
|
|
214
|
+
if (a === b)
|
|
215
|
+
return true;
|
|
216
|
+
if (a === null || a === undefined)
|
|
217
|
+
return b === null || b === undefined;
|
|
218
|
+
if (b === null || b === undefined)
|
|
219
|
+
return false;
|
|
220
|
+
if (a instanceof Date && b instanceof Date)
|
|
221
|
+
return a.getTime() === b.getTime();
|
|
222
|
+
// Byte-wise compare for Buffer / Uint8Array. We avoid Buffer.equals / Buffer.compare
|
|
223
|
+
// because @types/node 20.x parameterizes them with `Uint8Array<ArrayBuffer>`, which
|
|
224
|
+
// is narrower than the `Uint8Array<ArrayBufferLike>` actually held by Buffer instances.
|
|
225
|
+
if (a instanceof Uint8Array && b instanceof Uint8Array) {
|
|
226
|
+
if (a.byteLength !== b.byteLength)
|
|
227
|
+
return false;
|
|
228
|
+
for (let i = 0; i < a.byteLength; i++) {
|
|
229
|
+
if (a[i] !== b[i])
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
235
|
+
return a === b || (Number.isNaN(a) && Number.isNaN(b));
|
|
236
|
+
}
|
|
237
|
+
// Fall back to JSON for plain objects (driver-native types should already
|
|
238
|
+
// have been normalized to Date/Buffer above).
|
|
239
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
240
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
/** Truncate a string with an ellipsis for diff output. */
|
|
245
|
+
export function ellipsize(value, max = 80) {
|
|
246
|
+
return value.length <= max ? value : value.slice(0, max - 1) + '…';
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Topologically sort a list of SQL routines (views/functions/procs/triggers)
|
|
250
|
+
* by inferred dependencies. A routine A depends on B if A's `definition` text
|
|
251
|
+
* mentions B's name (case-insensitive, schema-qualified or bare with word
|
|
252
|
+
* boundaries). Stable for equal items; sorts cycles by qname so the result is
|
|
253
|
+
* still deterministic.
|
|
254
|
+
*
|
|
255
|
+
* Reference extraction is heuristic — comments and string literals are not
|
|
256
|
+
* stripped — but false positives only add edges that don't hurt correctness.
|
|
257
|
+
* MSSQL `CREATE VIEW`/`CREATE FUNCTION` reject forward references at create
|
|
258
|
+
* time, so without this sort we hit `Invalid object name` errors on apply.
|
|
259
|
+
*/
|
|
260
|
+
export function topoSortRoutinesByDefinition(items) {
|
|
261
|
+
if (items.length <= 1)
|
|
262
|
+
return items.slice();
|
|
263
|
+
const byKey = new Map();
|
|
264
|
+
for (const r of items)
|
|
265
|
+
byKey.set(qname(r.schema, r.name), r);
|
|
266
|
+
// Precompute lowercased bodies, with bracket-quoted identifiers normalized
|
|
267
|
+
// so that `[__mj].[vwEntities]` matches the qname `__mj.vwentities`. Without
|
|
268
|
+
// this we miss bracket-style references — which is the form MSSQL routines
|
|
269
|
+
// use almost universally.
|
|
270
|
+
const bodyLower = new Map();
|
|
271
|
+
for (const [key, r] of byKey) {
|
|
272
|
+
bodyLower.set(key, r.definition.toLowerCase().replace(/[[\]]/g, ''));
|
|
273
|
+
}
|
|
274
|
+
// Build deps: routine -> set of other routines it references.
|
|
275
|
+
const deps = new Map();
|
|
276
|
+
const allKeys = [...byKey.keys()].sort();
|
|
277
|
+
for (const key of allKeys)
|
|
278
|
+
deps.set(key, new Set());
|
|
279
|
+
for (const key of allKeys) {
|
|
280
|
+
const body = bodyLower.get(key);
|
|
281
|
+
for (const otherKey of allKeys) {
|
|
282
|
+
if (otherKey === key)
|
|
283
|
+
continue;
|
|
284
|
+
const bare = otherKey.includes('.') ? otherKey.slice(otherKey.lastIndexOf('.') + 1) : otherKey;
|
|
285
|
+
if (body.includes(otherKey) || matchBareWord(body, bare)) {
|
|
286
|
+
deps.get(key).add(otherKey);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Kahn's algorithm with deterministic tie-breaking.
|
|
291
|
+
const result = [];
|
|
292
|
+
const remaining = new Map();
|
|
293
|
+
for (const [k, v] of deps)
|
|
294
|
+
remaining.set(k, new Set(v));
|
|
295
|
+
while (remaining.size > 0) {
|
|
296
|
+
const ready = [...remaining.entries()]
|
|
297
|
+
.filter(([, refs]) => refs.size === 0)
|
|
298
|
+
.map(([k]) => k)
|
|
299
|
+
.sort();
|
|
300
|
+
if (ready.length === 0) {
|
|
301
|
+
// Cycle — emit remaining in qname order so output stays deterministic.
|
|
302
|
+
for (const k of [...remaining.keys()].sort())
|
|
303
|
+
result.push(byKey.get(k));
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
for (const k of ready) {
|
|
307
|
+
result.push(byKey.get(k));
|
|
308
|
+
remaining.delete(k);
|
|
309
|
+
for (const refs of remaining.values())
|
|
310
|
+
refs.delete(k);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
/** Word-boundary substring search (lowercased input only). */
|
|
316
|
+
function matchBareWord(haystack, needle) {
|
|
317
|
+
if (!needle)
|
|
318
|
+
return false;
|
|
319
|
+
const re = new RegExp(`(?<![\\w.])${escapeRegExp(needle)}(?!\\w)`);
|
|
320
|
+
return re.test(haystack);
|
|
321
|
+
}
|
|
322
|
+
function escapeRegExp(s) {
|
|
323
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/baseline/util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class BaselineBuild extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
'baseline-version': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
'source-dir': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
description: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
database: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
out: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
'exclude-data': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
'batch-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
'no-data': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
};
|
|
17
|
+
run(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Decide the baseline version + filename timestamp.
|
|
20
|
+
*
|
|
21
|
+
* - **Explicit mode**: caller passes `--baseline-version 6.0`. Timestamp = now (UTC).
|
|
22
|
+
* - **Auto / within-major mode**: caller omits `--baseline-version`. Scan
|
|
23
|
+
* `--source-dir` (or auto-discover one) for the latest V-file; new baseline
|
|
24
|
+
* inherits its `Major.Minor` and uses `latestVTimestamp + 1 minute` so the
|
|
25
|
+
* B-file always sorts after the V-stack it succeeds.
|
|
26
|
+
*/
|
|
27
|
+
private resolveVersionAndStamp;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/commands/baseline/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAkB7C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,MAAM,CAAC,WAAW,SAAmG;IAErH,MAAM,CAAC,QAAQ,WAKb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;MA2CV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA2G1B;;;;;;;;OAQG;IACH,OAAO,CAAC,sBAAsB;CAmC/B"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import ora from 'ora-classic';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { resolveConnection, isTty } from '../../baseline/cli-helpers.js';
|
|
7
|
+
import { openConnection } from '../../baseline/connection.js';
|
|
8
|
+
import { introspectMssql } from '../../baseline/introspector-mssql.js';
|
|
9
|
+
import { dumpTables } from '../../baseline/data-dumper.js';
|
|
10
|
+
import { emitBaselineTsql } from '../../baseline/emitter.js';
|
|
11
|
+
import { baselineFilename, computeAutoBaselineStamp, discoverMigrationsSourceDir, findLatestVersionedMigration, } from '../../baseline/util.js';
|
|
12
|
+
export default class BaselineBuild extends Command {
|
|
13
|
+
static { this.description = 'Generate a deterministic baseline SQL script from the END-STATE of a migrated MSSQL database.'; }
|
|
14
|
+
static { this.examples = [
|
|
15
|
+
'<%= config.bin %> <%= command.id %> --out ./migrations/v5/ # auto: within-major rebaseline',
|
|
16
|
+
'<%= config.bin %> <%= command.id %> --source-dir ./migrations/v5 --out ./migrations/v5/',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> --baseline-version 6.0 --out ./migrations/v6/ # explicit major-boundary',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> --baseline-version 5.32 --database MJ_BL_Stack --out /tmp/baseline/',
|
|
19
|
+
]; }
|
|
20
|
+
static { this.flags = {
|
|
21
|
+
'baseline-version': Flags.string({
|
|
22
|
+
description: 'Baseline version stamp in Major.Minor format (literal x is appended for patch, matching the V-file convention). ' +
|
|
23
|
+
'Omit to auto-detect from --source-dir (within-major rebaseline mode).',
|
|
24
|
+
}),
|
|
25
|
+
'source-dir': Flags.string({
|
|
26
|
+
description: 'Migrations source directory (e.g. ./migrations/v5). Used to auto-detect the next baseline ' +
|
|
27
|
+
'version + timestamp when --baseline-version is omitted. Defaults to the highest migrations/v*/ ' +
|
|
28
|
+
'directory walked up from cwd.',
|
|
29
|
+
}),
|
|
30
|
+
'description': Flags.string({
|
|
31
|
+
description: 'Human-readable description embedded in the file header.',
|
|
32
|
+
default: 'MemberJunction Baseline',
|
|
33
|
+
}),
|
|
34
|
+
'database': Flags.string({
|
|
35
|
+
description: 'Override database name (host/user/password come from MJ config).',
|
|
36
|
+
}),
|
|
37
|
+
'out': Flags.string({
|
|
38
|
+
description: 'Output directory. Filename is auto-generated.',
|
|
39
|
+
default: '.',
|
|
40
|
+
}),
|
|
41
|
+
'exclude-data': Flags.string({
|
|
42
|
+
description: 'Comma-separated list of tables (schema-qualified or not) to skip data dump for.',
|
|
43
|
+
default: '',
|
|
44
|
+
}),
|
|
45
|
+
'batch-size': Flags.integer({
|
|
46
|
+
description: 'Rows per INSERT batch.',
|
|
47
|
+
default: 1000,
|
|
48
|
+
}),
|
|
49
|
+
'no-data': Flags.boolean({
|
|
50
|
+
description: 'Emit schema only, no data inserts.',
|
|
51
|
+
default: false,
|
|
52
|
+
}),
|
|
53
|
+
'verbose': Flags.boolean({
|
|
54
|
+
description: 'Print per-object progress.',
|
|
55
|
+
default: false,
|
|
56
|
+
}),
|
|
57
|
+
'dry-run': Flags.boolean({
|
|
58
|
+
description: 'Print to stdout instead of writing a file.',
|
|
59
|
+
default: false,
|
|
60
|
+
}),
|
|
61
|
+
}; }
|
|
62
|
+
async run() {
|
|
63
|
+
const { flags } = await this.parse(BaselineBuild);
|
|
64
|
+
const { baselineVersion, generatedAtUtc, autoSource } = this.resolveVersionAndStamp(flags);
|
|
65
|
+
const connectionParams = resolveConnection({ database: flags.database }, 'mssql');
|
|
66
|
+
const excludedDataTables = new Set(flags['exclude-data']
|
|
67
|
+
.split(',')
|
|
68
|
+
.map((s) => s.trim().toLowerCase())
|
|
69
|
+
.filter(Boolean)
|
|
70
|
+
.map((s) => (s.includes('.') ? s : `dbo.${s}`)));
|
|
71
|
+
excludedDataTables.add('flyway_schema_history');
|
|
72
|
+
excludedDataTables.add('dbo.flyway_schema_history');
|
|
73
|
+
const useSpinner = isTty();
|
|
74
|
+
const spinner = useSpinner ? ora() : null;
|
|
75
|
+
const phase = (text) => {
|
|
76
|
+
if (spinner) {
|
|
77
|
+
spinner.text = text;
|
|
78
|
+
if (!spinner.isSpinning)
|
|
79
|
+
spinner.start();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
this.log(`• ${text}`);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const succeed = (text) => spinner ? spinner.succeed(text) : this.log(`✓ ${text}`);
|
|
86
|
+
const fail = (text) => spinner ? spinner.fail(text) : this.logToStderr(`✗ ${text}`);
|
|
87
|
+
const startedAt = Date.now();
|
|
88
|
+
if (autoSource) {
|
|
89
|
+
this.log(chalk.dim(` Auto-detected baseline: v${baselineVersion}.x (from ${autoSource.filename})`));
|
|
90
|
+
this.log(chalk.dim(` Auto timestamp : ${autoSource.timestamp} + 1m`));
|
|
91
|
+
}
|
|
92
|
+
phase(`Connecting to ${connectionParams.database}@${connectionParams.host}`);
|
|
93
|
+
const db = await openConnection(connectionParams);
|
|
94
|
+
try {
|
|
95
|
+
succeed(`Connected to ${connectionParams.database}`);
|
|
96
|
+
phase(`Introspecting schema`);
|
|
97
|
+
const snapshot = await introspectMssql(db, {
|
|
98
|
+
onPhase: (p) => { if (flags.verbose)
|
|
99
|
+
this.log(` - ${p}`); },
|
|
100
|
+
});
|
|
101
|
+
succeed(`Introspected ${snapshot.tables.length} tables, ` +
|
|
102
|
+
`${snapshot.views.length} views, ` +
|
|
103
|
+
`${snapshot.procedures.length} procs, ` +
|
|
104
|
+
`${snapshot.functions.length} functions`);
|
|
105
|
+
const dumps = flags['no-data'] ? [] : await (async () => {
|
|
106
|
+
phase(`Dumping table data (every row, every column)`);
|
|
107
|
+
const result = await dumpTables(db, snapshot.tables, { excludedTables: excludedDataTables }, {
|
|
108
|
+
onTable: (table, count) => {
|
|
109
|
+
if (flags.verbose)
|
|
110
|
+
this.log(` ${table.schema}.${table.name}: ${count} rows`);
|
|
111
|
+
else if (spinner)
|
|
112
|
+
spinner.text = `Dumping ${table.schema}.${table.name} (${count} rows)`;
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
const totalRows = result.reduce((sum, d) => sum + d.rowCount, 0);
|
|
116
|
+
succeed(`Dumped ${totalRows.toLocaleString()} rows across ${result.length} tables`);
|
|
117
|
+
return result;
|
|
118
|
+
})();
|
|
119
|
+
phase('Emitting baseline SQL');
|
|
120
|
+
const sql = emitBaselineTsql({
|
|
121
|
+
snapshot,
|
|
122
|
+
dataDumps: dumps,
|
|
123
|
+
options: {
|
|
124
|
+
baselineVersion,
|
|
125
|
+
description: flags.description,
|
|
126
|
+
generatedAtUtc,
|
|
127
|
+
includeData: !flags['no-data'],
|
|
128
|
+
excludedDataTables,
|
|
129
|
+
batchSize: flags['batch-size'],
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
succeed(`Emitted ${sql.length.toLocaleString()} bytes of T-SQL`);
|
|
133
|
+
if (flags['dry-run']) {
|
|
134
|
+
process.stdout.write(sql);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const filename = baselineFilename({ generatedAtUtc, baselineVersion });
|
|
138
|
+
fs.mkdirSync(flags.out, { recursive: true });
|
|
139
|
+
const fullPath = path.resolve(flags.out, filename);
|
|
140
|
+
fs.writeFileSync(fullPath, sql, 'utf8');
|
|
141
|
+
const elapsed = ((Date.now() - startedAt) / 1000).toFixed(1);
|
|
142
|
+
this.log('');
|
|
143
|
+
this.log(chalk.green(`✓ Baseline written: ${fullPath}`));
|
|
144
|
+
this.log(chalk.dim(` Generated in ${elapsed}s`));
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
fail(`Build failed: ${err.message}`);
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
await db.close();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Decide the baseline version + filename timestamp.
|
|
156
|
+
*
|
|
157
|
+
* - **Explicit mode**: caller passes `--baseline-version 6.0`. Timestamp = now (UTC).
|
|
158
|
+
* - **Auto / within-major mode**: caller omits `--baseline-version`. Scan
|
|
159
|
+
* `--source-dir` (or auto-discover one) for the latest V-file; new baseline
|
|
160
|
+
* inherits its `Major.Minor` and uses `latestVTimestamp + 1 minute` so the
|
|
161
|
+
* B-file always sorts after the V-stack it succeeds.
|
|
162
|
+
*/
|
|
163
|
+
resolveVersionAndStamp(flags) {
|
|
164
|
+
const explicit = flags['baseline-version'];
|
|
165
|
+
if (explicit) {
|
|
166
|
+
if (!/^\d+\.\d+$/.test(explicit)) {
|
|
167
|
+
this.error(`--baseline-version must be Major.Minor (got "${explicit}")`);
|
|
168
|
+
}
|
|
169
|
+
return { baselineVersion: explicit, generatedAtUtc: new Date(), autoSource: null };
|
|
170
|
+
}
|
|
171
|
+
const sourceDir = flags['source-dir'] ?? discoverMigrationsSourceDir(process.cwd());
|
|
172
|
+
if (!sourceDir) {
|
|
173
|
+
this.error('No --baseline-version provided and could not auto-discover a migrations directory. ' +
|
|
174
|
+
'Pass --source-dir or --baseline-version.');
|
|
175
|
+
}
|
|
176
|
+
const latest = findLatestVersionedMigration(sourceDir);
|
|
177
|
+
if (!latest) {
|
|
178
|
+
this.error(`No V-files found in ${sourceDir}. Pass --baseline-version explicitly or point --source-dir at a folder with V<ts>__v<Major>.<Minor>...sql migrations.`);
|
|
179
|
+
}
|
|
180
|
+
const { generatedAtUtc } = computeAutoBaselineStamp(latest.timestamp);
|
|
181
|
+
return {
|
|
182
|
+
baselineVersion: latest.majorMinor,
|
|
183
|
+
generatedAtUtc,
|
|
184
|
+
autoSource: { filename: latest.filename, timestamp: latest.timestamp },
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/commands/baseline/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class BaselineCompare extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
left: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
right: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
dialect: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
'row-compare': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
'row-hash-algo': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
ignore: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
'sample-limit': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
out: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
|
+
'fail-on-diff': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
};
|
|
17
|
+
run(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/commands/baseline/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAe7C,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;IAClD,MAAM,CAAC,WAAW,SAA8E;IAEhG,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;MA6BV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAoF3B"}
|