@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,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin connection helper. Uses `mssql` (tedious) and `pg` directly via dynamic
|
|
3
|
+
* imports — both packages ship transitively with @memberjunction/skyway-*.
|
|
4
|
+
*
|
|
5
|
+
* Connections are derived from the merged MJ config (`getValidatedConfig`)
|
|
6
|
+
* with optional `--database` override so that compare/roundtrip can target
|
|
7
|
+
* two scratch DBs on the same server with one config.
|
|
8
|
+
*/
|
|
9
|
+
export async function openConnection(params) {
|
|
10
|
+
if (params.dialect === 'mssql')
|
|
11
|
+
return openMssql(params);
|
|
12
|
+
return openPostgres(params);
|
|
13
|
+
}
|
|
14
|
+
async function openMssql(params) {
|
|
15
|
+
// mssql is a CJS package; under `await import()` its actual exports may live
|
|
16
|
+
// under `.default` depending on Node/TS interop. Mirror the pg branch below.
|
|
17
|
+
const mssqlMod = await import('mssql');
|
|
18
|
+
const mssql = mssqlMod.ConnectionPool
|
|
19
|
+
? mssqlMod
|
|
20
|
+
: mssqlMod.default;
|
|
21
|
+
const config = {
|
|
22
|
+
server: params.host,
|
|
23
|
+
port: params.port ?? 1433,
|
|
24
|
+
user: params.user,
|
|
25
|
+
password: params.password,
|
|
26
|
+
database: params.database,
|
|
27
|
+
options: {
|
|
28
|
+
encrypt: params.encrypt ?? false,
|
|
29
|
+
trustServerCertificate: params.trustServerCertificate ?? true,
|
|
30
|
+
enableArithAbort: true,
|
|
31
|
+
},
|
|
32
|
+
requestTimeout: 600000,
|
|
33
|
+
};
|
|
34
|
+
const pool = await new mssql.ConnectionPool(config).connect();
|
|
35
|
+
return {
|
|
36
|
+
dialect: 'mssql',
|
|
37
|
+
database: params.database,
|
|
38
|
+
async query(sql) {
|
|
39
|
+
const result = await pool.request().query(sql);
|
|
40
|
+
return result.recordset;
|
|
41
|
+
},
|
|
42
|
+
async stream(sql, onRow) {
|
|
43
|
+
const request = pool.request();
|
|
44
|
+
request.stream = true;
|
|
45
|
+
let pending = Promise.resolve();
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
request.on('row', (row) => {
|
|
48
|
+
pending = pending.then(() => onRow(row));
|
|
49
|
+
});
|
|
50
|
+
request.on('error', (err) => reject(err));
|
|
51
|
+
request.on('done', () => {
|
|
52
|
+
pending.then(() => resolve()).catch(reject);
|
|
53
|
+
});
|
|
54
|
+
request.query(sql);
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
async close() {
|
|
58
|
+
await pool.close();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async function openPostgres(params) {
|
|
63
|
+
const pg = await import('pg');
|
|
64
|
+
const Client = pg.Client ?? pg.default.Client;
|
|
65
|
+
const client = new Client({
|
|
66
|
+
host: params.host,
|
|
67
|
+
port: params.port ?? 5432,
|
|
68
|
+
user: params.user,
|
|
69
|
+
password: params.password,
|
|
70
|
+
database: params.database,
|
|
71
|
+
});
|
|
72
|
+
await client.connect();
|
|
73
|
+
return {
|
|
74
|
+
dialect: 'postgres',
|
|
75
|
+
database: params.database,
|
|
76
|
+
async query(sql, values) {
|
|
77
|
+
const result = await client.query(sql, values);
|
|
78
|
+
return result.rows;
|
|
79
|
+
},
|
|
80
|
+
async stream(sql, onRow) {
|
|
81
|
+
const QueryStream = await import('pg-query-stream').then((m) => {
|
|
82
|
+
const ctor = m.default
|
|
83
|
+
?? m;
|
|
84
|
+
return ctor ?? null;
|
|
85
|
+
}).catch(() => null);
|
|
86
|
+
if (!QueryStream) {
|
|
87
|
+
// Fallback: load all rows. Acceptable for compare runs where rows
|
|
88
|
+
// are bounded by the baseline data size (shippable metadata).
|
|
89
|
+
const result = await client.query(sql);
|
|
90
|
+
for (const row of result.rows)
|
|
91
|
+
await onRow(row);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const stream = client.query(new QueryStream(sql, []));
|
|
95
|
+
for await (const row of stream) {
|
|
96
|
+
await onRow(row);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
async close() {
|
|
100
|
+
await client.end();
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/baseline/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-table data dumper.
|
|
3
|
+
*
|
|
4
|
+
* Streams every row of every table from a live MSSQL connection in a stable
|
|
5
|
+
* order (PK, falling back to all columns) and emits the result as a
|
|
6
|
+
* TableDataDump. The emitter renders these as batched INSERT ... VALUES
|
|
7
|
+
* statements with `SET IDENTITY_INSERT` bookends.
|
|
8
|
+
*/
|
|
9
|
+
import type { QueryRunner } from './connection.js';
|
|
10
|
+
import type { TableDataDump, TableDef } from './types.js';
|
|
11
|
+
export interface DumpProgress {
|
|
12
|
+
onTable?(table: TableDef, rowsSoFar: number, rowsTotal?: number): void;
|
|
13
|
+
}
|
|
14
|
+
export interface DumpOptions {
|
|
15
|
+
excludedTables: Set<string>;
|
|
16
|
+
/** Hard cap per table (defensive — baselines should not have huge tables). */
|
|
17
|
+
maxRowsPerTable?: number;
|
|
18
|
+
}
|
|
19
|
+
/** Dump every non-excluded table. Computed columns are skipped. */
|
|
20
|
+
export declare function dumpTables(db: QueryRunner, tables: readonly TableDef[], options: DumpOptions, progress?: DumpProgress): Promise<TableDataDump[]>;
|
|
21
|
+
/** Construct an ORDER BY clause for deterministic streaming. */
|
|
22
|
+
export declare function buildOrderBy(table: TableDef): string;
|
|
23
|
+
//# sourceMappingURL=data-dumper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-dumper.d.ts","sourceRoot":"","sources":["../../src/baseline/data-dumper.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAa,aAAa,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAElE,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxE;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,mEAAmE;AACnE,wBAAsB,UAAU,CAC9B,EAAE,EAAE,WAAW,EACf,MAAM,EAAE,SAAS,QAAQ,EAAE,EAC3B,OAAO,EAAE,WAAW,EACpB,QAAQ,GAAE,YAAiB,GAC1B,OAAO,CAAC,aAAa,EAAE,CAAC,CAsC1B;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAcpD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-table data dumper.
|
|
3
|
+
*
|
|
4
|
+
* Streams every row of every table from a live MSSQL connection in a stable
|
|
5
|
+
* order (PK, falling back to all columns) and emits the result as a
|
|
6
|
+
* TableDataDump. The emitter renders these as batched INSERT ... VALUES
|
|
7
|
+
* statements with `SET IDENTITY_INSERT` bookends.
|
|
8
|
+
*/
|
|
9
|
+
import { quoteIdent, stableSortBy } from './util.js';
|
|
10
|
+
/** Dump every non-excluded table. Computed columns are skipped. */
|
|
11
|
+
export async function dumpTables(db, tables, options, progress = {}) {
|
|
12
|
+
const dumps = [];
|
|
13
|
+
for (const table of tables) {
|
|
14
|
+
const key = `${table.schema}.${table.name}`.toLowerCase();
|
|
15
|
+
if (options.excludedTables.has(key))
|
|
16
|
+
continue;
|
|
17
|
+
const includedColumns = table.columns.filter((c) => !c.isComputed);
|
|
18
|
+
if (includedColumns.length === 0)
|
|
19
|
+
continue;
|
|
20
|
+
const rows = [];
|
|
21
|
+
let count = 0;
|
|
22
|
+
const orderBy = buildOrderBy(table);
|
|
23
|
+
const select = `SELECT ${includedColumns.map(selectExpressionForColumn).join(', ')} ` +
|
|
24
|
+
`FROM ${quoteIdent(table.schema)}.${quoteIdent(table.name)} ${orderBy}`;
|
|
25
|
+
let truncated = false;
|
|
26
|
+
await db.stream(select, (row) => {
|
|
27
|
+
if (options.maxRowsPerTable && count >= options.maxRowsPerTable) {
|
|
28
|
+
truncated = true;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const ordered = includedColumns.map((c) => row[c.name]);
|
|
32
|
+
rows.push(ordered);
|
|
33
|
+
count++;
|
|
34
|
+
if (count % 5000 === 0)
|
|
35
|
+
progress.onTable?.(table, count);
|
|
36
|
+
});
|
|
37
|
+
progress.onTable?.(table, count);
|
|
38
|
+
dumps.push({
|
|
39
|
+
schema: table.schema,
|
|
40
|
+
table: table.name,
|
|
41
|
+
columns: includedColumns.map((c) => c.name),
|
|
42
|
+
rows,
|
|
43
|
+
rowCount: rows.length,
|
|
44
|
+
truncated,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return dumps;
|
|
48
|
+
}
|
|
49
|
+
/** Construct an ORDER BY clause for deterministic streaming. */
|
|
50
|
+
export function buildOrderBy(table) {
|
|
51
|
+
const orderColumns = (() => {
|
|
52
|
+
if (table.primaryKey && table.primaryKey.columns.length)
|
|
53
|
+
return table.primaryKey.columns;
|
|
54
|
+
if (table.uniqueConstraints[0]?.columns.length)
|
|
55
|
+
return table.uniqueConstraints[0].columns;
|
|
56
|
+
// Fall back to ALL non-LOB columns sorted by ordinal so we still get a
|
|
57
|
+
// deterministic order. LOB types can't appear in ORDER BY in MSSQL.
|
|
58
|
+
const sortable = stableSortBy(table.columns.filter((c) => !c.isComputed && !isLobType(c.dataType)), (c) => String(c.ordinal).padStart(6, '0'));
|
|
59
|
+
return sortable.map((c) => c.name);
|
|
60
|
+
})();
|
|
61
|
+
if (orderColumns.length === 0)
|
|
62
|
+
return '';
|
|
63
|
+
return 'ORDER BY ' + orderColumns.map((n) => quoteIdent(n)).join(', ');
|
|
64
|
+
}
|
|
65
|
+
function isLobType(dataType) {
|
|
66
|
+
const lower = dataType.toLowerCase();
|
|
67
|
+
return (lower.includes('text') ||
|
|
68
|
+
lower.includes('image') ||
|
|
69
|
+
lower.includes('xml') ||
|
|
70
|
+
lower === 'sql_variant' ||
|
|
71
|
+
lower.endsWith('(max)'));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Build the SELECT expression for a column.
|
|
75
|
+
*
|
|
76
|
+
* Datetime2 / datetimeoffset / time columns carry up to 7 fractional-second
|
|
77
|
+
* digits (100ns ticks). When the mssql driver hands them back as a JS `Date`
|
|
78
|
+
* we lose everything past milliseconds — the resulting INSERTs round to
|
|
79
|
+
* `.SSS000`, producing systematic row-level diffs against the source DB.
|
|
80
|
+
* Wrapping these in `CONVERT(NVARCHAR(50), col, 121)` returns the raw
|
|
81
|
+
* datetime string with full precision; SQL Server then implicitly converts
|
|
82
|
+
* the string literal back to datetime2 at INSERT time.
|
|
83
|
+
*
|
|
84
|
+
* `datetime` (legacy) is 3.33ms precision so JS Date is sufficient; we leave
|
|
85
|
+
* it alone. `smalldatetime` is minute-precision; also fine.
|
|
86
|
+
*/
|
|
87
|
+
function selectExpressionForColumn(c) {
|
|
88
|
+
const lc = c.dataType.toLowerCase();
|
|
89
|
+
if (lc.startsWith('datetime2') || lc.startsWith('datetimeoffset') || lc.startsWith('time')) {
|
|
90
|
+
return `CONVERT(NVARCHAR(50), ${quoteIdent(c.name)}, 121) AS ${quoteIdent(c.name)}`;
|
|
91
|
+
}
|
|
92
|
+
return quoteIdent(c.name);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=data-dumper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-dumper.js","sourceRoot":"","sources":["../../src/baseline/data-dumper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical T-SQL emitter.
|
|
3
|
+
*
|
|
4
|
+
* Produces a single, deterministic T-SQL script from a SchemaSnapshot plus
|
|
5
|
+
* (optional) per-table data dumps. The output ordering is dependency-aware
|
|
6
|
+
* and stable: identical input → byte-identical output.
|
|
7
|
+
*
|
|
8
|
+
* Order of emission:
|
|
9
|
+
* 1. Header banner
|
|
10
|
+
* 2. CREATE SCHEMA statements
|
|
11
|
+
* 3. CREATE SEQUENCE statements
|
|
12
|
+
* 4. CREATE TABLE statements (no FKs yet — those come later)
|
|
13
|
+
* 5. Default constraints
|
|
14
|
+
* 6. Check constraints
|
|
15
|
+
* 7. Indexes (non-PK, non-unique-constraint)
|
|
16
|
+
* 8. Data inserts (with SET IDENTITY_INSERT bookends)
|
|
17
|
+
* 9. Reseed identity columns
|
|
18
|
+
* 10. CREATE USER / CREATE ROLE (database principals — required before any GRANT)
|
|
19
|
+
* 11. CREATE TYPE … AS TABLE (UDTs — before functions/procs that take TVPs)
|
|
20
|
+
* 12. CREATE FUNCTION statements (before views — MJ views reference UDFs)
|
|
21
|
+
* 13. CREATE VIEW statements
|
|
22
|
+
* 14. CREATE PROCEDURE statements
|
|
23
|
+
* 15. CREATE TRIGGER statements
|
|
24
|
+
* 16. ALTER TABLE ADD CONSTRAINT … FOREIGN KEY (last so order doesn't matter)
|
|
25
|
+
* 17. ALTER ROLE … ADD MEMBER (role memberships — requires both principals to exist)
|
|
26
|
+
* 18. GRANT/DENY permissions (last so every grantee + every target object exists)
|
|
27
|
+
* 19. EXEC sp_addextendedproperty calls (after every object that can carry them)
|
|
28
|
+
*/
|
|
29
|
+
import type { BaselineEmitOptions, SchemaSnapshot, TableDataDump } from './types.js';
|
|
30
|
+
export interface EmitInput {
|
|
31
|
+
snapshot: SchemaSnapshot;
|
|
32
|
+
dataDumps: readonly TableDataDump[];
|
|
33
|
+
options: BaselineEmitOptions;
|
|
34
|
+
}
|
|
35
|
+
export declare function emitBaselineTsql(input: EmitInput): string;
|
|
36
|
+
//# sourceMappingURL=emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/baseline/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAWH,OAAO,KAAK,EACV,mBAAmB,EASnB,cAAc,EAEd,aAAa,EAKd,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IACpC,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CA+CzD"}
|