@memberjunction/cli 6.2.0-edge.7 → 6.2.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/dist/commands/diag/export.d.ts +16 -0
- package/dist/commands/diag/export.d.ts.map +1 -0
- package/dist/commands/diag/export.js +37 -0
- package/dist/commands/diag/export.js.map +1 -0
- package/dist/commands/diag/inspect.d.ts +14 -0
- package/dist/commands/diag/inspect.d.ts.map +1 -0
- package/dist/commands/diag/inspect.js +45 -0
- package/dist/commands/diag/inspect.js.map +1 -0
- package/dist/commands/diag/keygen.d.ts +11 -0
- package/dist/commands/diag/keygen.d.ts.map +1 -0
- package/dist/commands/diag/keygen.js +36 -0
- package/dist/commands/diag/keygen.js.map +1 -0
- package/dist/commands/diag/scrub.d.ts +15 -0
- package/dist/commands/diag/scrub.d.ts.map +1 -0
- package/dist/commands/diag/scrub.js +34 -0
- package/dist/commands/diag/scrub.js.map +1 -0
- package/dist/commands/diag/slow.d.ts +14 -0
- package/dist/commands/diag/slow.d.ts.map +1 -0
- package/dist/commands/diag/slow.js +32 -0
- package/dist/commands/diag/slow.js.map +1 -0
- package/dist/commands/diag/timeline.d.ts +14 -0
- package/dist/commands/diag/timeline.d.ts.map +1 -0
- package/dist/commands/diag/timeline.js +29 -0
- package/dist/commands/diag/timeline.js.map +1 -0
- package/dist/commands/install/index.d.ts +12 -0
- package/dist/commands/install/index.d.ts.map +1 -1
- package/dist/commands/install/index.js +32 -5
- package/dist/commands/install/index.js.map +1 -1
- package/dist/commands/migrate/index.d.ts +26 -6
- package/dist/commands/migrate/index.d.ts.map +1 -1
- package/dist/commands/migrate/index.js +93 -21
- package/dist/commands/migrate/index.js.map +1 -1
- package/dist/commands/test/suite.d.ts +2 -0
- package/dist/commands/test/suite.d.ts.map +1 -1
- package/dist/commands/test/suite.js +10 -0
- package/dist/commands/test/suite.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/lib/db-version.d.ts +34 -7
- package/dist/lib/db-version.d.ts.map +1 -1
- package/dist/lib/db-version.js +45 -17
- package/dist/lib/db-version.js.map +1 -1
- package/dist/lib/migration-fetch.d.ts +17 -14
- package/dist/lib/migration-fetch.d.ts.map +1 -1
- package/dist/lib/migration-fetch.js +35 -25
- package/dist/lib/migration-fetch.js.map +1 -1
- package/dist/lib/migration-timeout.d.ts +15 -0
- package/dist/lib/migration-timeout.d.ts.map +1 -0
- package/dist/lib/migration-timeout.js +23 -0
- package/dist/lib/migration-timeout.js.map +1 -0
- package/dist/lib/out-of-order.d.ts +56 -0
- package/dist/lib/out-of-order.d.ts.map +1 -0
- package/dist/lib/out-of-order.js +37 -0
- package/dist/lib/out-of-order.js.map +1 -0
- package/dist/light-commands.d.ts.map +1 -1
- package/dist/light-commands.js +13 -0
- package/dist/light-commands.js.map +1 -1
- package/dist/utils/diag-utils.d.ts +34 -0
- package/dist/utils/diag-utils.d.ts.map +1 -0
- package/dist/utils/diag-utils.js +147 -0
- package/dist/utils/diag-utils.js.map +1 -0
- package/oclif.manifest.json +901 -564
- package/package.json +28 -27
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AppliedMigrationState } from './db-version.js';
|
|
1
2
|
export type MigrationDialect = 'sqlserver' | 'postgresql';
|
|
2
3
|
export interface MigrationFetchResult {
|
|
3
4
|
/** Temp clone root to hand to Skyway as the migration location. */
|
|
@@ -21,23 +22,25 @@ export declare function resolveGitRef(tagOrBranch: string): string;
|
|
|
21
22
|
* Pure selector: given the repo-relative migration paths present at a ref, return
|
|
22
23
|
* the minimal slice Skyway needs. Repeatable migrations are always included.
|
|
23
24
|
*
|
|
24
|
-
* Two modes, keyed on `
|
|
25
|
-
*
|
|
25
|
+
* Two modes, keyed on `applied` (what the target database's history says, or `null`
|
|
26
|
+
* for a fresh database):
|
|
26
27
|
*
|
|
27
|
-
* - **Fresh install** (`
|
|
28
|
+
* - **Fresh install** (`applied` null, or a history table with nothing successfully
|
|
29
|
+
* applied yet — Skyway still baselines that database): `baseline + tail` — the highest `B`
|
|
28
30
|
* baseline plus every `V` after it. Skyway applies the baseline (consolidated schema)
|
|
29
31
|
* then the tail. This is the bandwidth-optimal path for a brand-new database.
|
|
30
|
-
* - **Existing-DB upgrade** (`
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* - **Existing-DB upgrade** (`applied` set): every `V` whose version is not in
|
|
33
|
+
* `applied.AppliedVersions` and is strictly above `applied.BaselineFloor`, with **no
|
|
34
|
+
* baseline**. Skyway never applies a `B` file to a database that already has history.
|
|
35
|
+
* Files older than the highest applied version are still selected when they were never
|
|
36
|
+
* run (a database coming from a release line); the caller decides whether Skyway may
|
|
37
|
+
* apply them out of order.
|
|
35
38
|
*
|
|
36
39
|
* With no baseline present (e.g. legacy v2) the fresh path returns the full versioned history.
|
|
37
40
|
*/
|
|
38
|
-
export declare function SelectMigrationSlice(paths: readonly string[],
|
|
41
|
+
export declare function SelectMigrationSlice(paths: readonly string[], applied?: AppliedMigrationState | null): string[];
|
|
39
42
|
/** @deprecated Use {@link SelectMigrationSlice}. */
|
|
40
|
-
export declare function selectMigrationSlice(paths: readonly string[],
|
|
43
|
+
export declare function selectMigrationSlice(paths: readonly string[], applied?: AppliedMigrationState | null): string[];
|
|
41
44
|
/**
|
|
42
45
|
* SIDE EFFECTS: clones from `repoUrl` over the network into a temp dir and checks out
|
|
43
46
|
* only the selected migration slice. Returns the temp dir plus a `cleanup` the caller
|
|
@@ -47,15 +50,15 @@ export declare function FetchMigrationSlice(opts: {
|
|
|
47
50
|
repoUrl: string;
|
|
48
51
|
ref: string;
|
|
49
52
|
dialect: MigrationDialect;
|
|
50
|
-
/**
|
|
51
|
-
|
|
53
|
+
/** What the target DB has already applied; `null`/omitted = fresh install (baseline + tail). */
|
|
54
|
+
applied?: AppliedMigrationState | null;
|
|
52
55
|
}): Promise<MigrationFetchResult>;
|
|
53
56
|
/** @deprecated Use {@link FetchMigrationSlice}. */
|
|
54
57
|
export declare function fetchMigrationSlice(opts: {
|
|
55
58
|
repoUrl: string;
|
|
56
59
|
ref: string;
|
|
57
60
|
dialect: MigrationDialect;
|
|
58
|
-
/**
|
|
59
|
-
|
|
61
|
+
/** What the target DB has already applied; `null`/omitted = fresh install (baseline + tail). */
|
|
62
|
+
applied?: AppliedMigrationState | null;
|
|
60
63
|
}): Promise<MigrationFetchResult>;
|
|
61
64
|
//# sourceMappingURL=migration-fetch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-fetch.d.ts","sourceRoot":"","sources":["../../src/lib/migration-fetch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migration-fetch.d.ts","sourceRoot":"","sources":["../../src/lib/migration-fetch.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,YAAY,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ,iGAAiG;IACjG,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kGAAkG;IAClG,YAAY,EAAE,OAAO,CAAC;IACtB,wFAAwF;IACxF,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAKD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,GAAG,MAAM,EAAE,CAc/G;AAED,oDAAoD;AACpD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,GAAG,MAAM,EAAE,CAE/G;AA8BD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,gBAAgB,CAAC;IAC1B,gGAAgG;IAChG,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACxC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA2BhC;AAED,mDAAmD;AACnD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,gBAAgB,CAAC;IAC1B,gGAAgG;IAChG,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACxC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAEhC"}
|
|
@@ -7,14 +7,18 @@
|
|
|
7
7
|
* The selection depends on whether the target database is fresh or existing, because
|
|
8
8
|
* Skyway only ever applies baselines to a fresh (no-history) database:
|
|
9
9
|
*
|
|
10
|
-
* fresh install
|
|
11
|
-
* existing upgrade → [ every `V`
|
|
10
|
+
* fresh install → [ highest `B` baseline ] + [ every `V` after it ] + [ all `R` repeatables ]
|
|
11
|
+
* existing upgrade → [ every `V` not yet applied and above the DB's baseline floor ] + [ all `R` repeatables ] (no baseline)
|
|
12
12
|
*
|
|
13
|
-
* The existing-upgrade path
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* The existing-upgrade path selects by set difference against the history table, not by
|
|
14
|
+
* "newer than the highest applied version". Release lines make that distinction matter: a
|
|
15
|
+
* database upgraded from a patch line has applied files that are newer than migrations it
|
|
16
|
+
* has never run, and a "newer than the max" filter would drop those older files silently.
|
|
17
|
+
* The floor is the highest baseline row in history; Skyway never runs a `V` file at or
|
|
18
|
+
* below it, so fetching one would only make the CLI and Skyway disagree about what is
|
|
19
|
+
* pending. The git ref bounds the top of the range (only migrations at/below the target
|
|
20
|
+
* are in the tree). Selection uses the numeric `<timestamp>` filename token — Skyway's
|
|
21
|
+
* version key — via the shared {@link ParseMigrationFilename}.
|
|
18
22
|
*/
|
|
19
23
|
import { mkdtempSync } from 'node:fs';
|
|
20
24
|
import { rm } from 'node:fs/promises';
|
|
@@ -42,26 +46,28 @@ export function resolveGitRef(tagOrBranch) {
|
|
|
42
46
|
* Pure selector: given the repo-relative migration paths present at a ref, return
|
|
43
47
|
* the minimal slice Skyway needs. Repeatable migrations are always included.
|
|
44
48
|
*
|
|
45
|
-
* Two modes, keyed on `
|
|
46
|
-
*
|
|
49
|
+
* Two modes, keyed on `applied` (what the target database's history says, or `null`
|
|
50
|
+
* for a fresh database):
|
|
47
51
|
*
|
|
48
|
-
* - **Fresh install** (`
|
|
52
|
+
* - **Fresh install** (`applied` null, or a history table with nothing successfully
|
|
53
|
+
* applied yet — Skyway still baselines that database): `baseline + tail` — the highest `B`
|
|
49
54
|
* baseline plus every `V` after it. Skyway applies the baseline (consolidated schema)
|
|
50
55
|
* then the tail. This is the bandwidth-optimal path for a brand-new database.
|
|
51
|
-
* - **Existing-DB upgrade** (`
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
+
* - **Existing-DB upgrade** (`applied` set): every `V` whose version is not in
|
|
57
|
+
* `applied.AppliedVersions` and is strictly above `applied.BaselineFloor`, with **no
|
|
58
|
+
* baseline**. Skyway never applies a `B` file to a database that already has history.
|
|
59
|
+
* Files older than the highest applied version are still selected when they were never
|
|
60
|
+
* run (a database coming from a release line); the caller decides whether Skyway may
|
|
61
|
+
* apply them out of order.
|
|
56
62
|
*
|
|
57
63
|
* With no baseline present (e.g. legacy v2) the fresh path returns the full versioned history.
|
|
58
64
|
*/
|
|
59
|
-
export function SelectMigrationSlice(paths,
|
|
65
|
+
export function SelectMigrationSlice(paths, applied) {
|
|
60
66
|
const sqlPaths = paths.filter((p) => p.toLowerCase().endsWith('.sql'));
|
|
61
67
|
const repeatables = sqlPaths.filter((p) => REPEATABLE_PATTERN.test(path.basename(p)));
|
|
62
|
-
if (
|
|
63
|
-
// Existing DB:
|
|
64
|
-
const versioned = sqlPaths.filter((p) =>
|
|
68
|
+
if (applied != null && applied.AppliedVersions.size > 0) {
|
|
69
|
+
// Existing DB: every versioned migration it has not applied, above its baseline floor.
|
|
70
|
+
const versioned = sqlPaths.filter((p) => isUnappliedAboveFloor(p, applied));
|
|
65
71
|
return Array.from(new Set([...versioned, ...repeatables]));
|
|
66
72
|
}
|
|
67
73
|
// Fresh DB: baseline + everything after it.
|
|
@@ -70,13 +76,17 @@ export function SelectMigrationSlice(paths, currentVersion) {
|
|
|
70
76
|
return Array.from(new Set([...versioned, ...repeatables]));
|
|
71
77
|
}
|
|
72
78
|
/** @deprecated Use {@link SelectMigrationSlice}. */
|
|
73
|
-
export function selectMigrationSlice(paths,
|
|
74
|
-
return SelectMigrationSlice(paths,
|
|
79
|
+
export function selectMigrationSlice(paths, applied) {
|
|
80
|
+
return SelectMigrationSlice(paths, applied);
|
|
75
81
|
}
|
|
76
|
-
/** True if `filePath` is a versioned (`V`) migration
|
|
77
|
-
function
|
|
82
|
+
/** True if `filePath` is a versioned (`V`) migration the database has not applied and that lies above its baseline floor. */
|
|
83
|
+
function isUnappliedAboveFloor(filePath, applied) {
|
|
78
84
|
const parsed = ParseMigrationFilename(path.basename(filePath));
|
|
79
|
-
|
|
85
|
+
if (parsed?.Kind !== 'V')
|
|
86
|
+
return false;
|
|
87
|
+
if (applied.AppliedVersions.has(parsed.Timestamp))
|
|
88
|
+
return false;
|
|
89
|
+
return applied.BaselineFloor === null || parsed.Timestamp > applied.BaselineFloor;
|
|
80
90
|
}
|
|
81
91
|
/** Returns the timestamp of the latest `B` baseline among the paths, or null if none. */
|
|
82
92
|
function highestBaselineTimestamp(sqlPaths) {
|
|
@@ -123,7 +133,7 @@ export async function FetchMigrationSlice(opts) {
|
|
|
123
133
|
return { Dir: dir, Selected: [], UsedFallback: true, Cleanup: cleanup };
|
|
124
134
|
}
|
|
125
135
|
const allPaths = await listTreePaths(git, migrationsRoot);
|
|
126
|
-
const selected = SelectMigrationSlice(allPaths, opts.
|
|
136
|
+
const selected = SelectMigrationSlice(allPaths, opts.applied);
|
|
127
137
|
const checkoutTargets = selected.length > 0 ? selected : [migrationsRoot];
|
|
128
138
|
await git.raw(['sparse-checkout', 'set', '--no-cone', ...checkoutTargets]);
|
|
129
139
|
await git.raw(['checkout']);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-fetch.js","sourceRoot":"","sources":["../../src/lib/migration-fetch.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"migration-fetch.js","sourceRoot":"","sources":["../../src/lib/migration-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default per-request timeout for `mj migrate` (30 minutes). Skyway's own default
|
|
3
|
+
* is 5 minutes, which at least one baseline batch exceeds (#3168). Override with
|
|
4
|
+
* `MJ_MIGRATION_REQUEST_TIMEOUT` (milliseconds) or `dbRequestTimeout` in mj.config.cjs.
|
|
5
|
+
*/
|
|
6
|
+
export declare const DEFAULT_MIGRATION_REQUEST_TIMEOUT_MS = 1800000;
|
|
7
|
+
/**
|
|
8
|
+
* Returns a hint naming `MJ_MIGRATION_REQUEST_TIMEOUT` when any of the given error
|
|
9
|
+
* texts is a request timeout, otherwise `undefined`.
|
|
10
|
+
*
|
|
11
|
+
* @param texts - Error messages and log lines from the failed migration run.
|
|
12
|
+
* @param currentTimeoutMs - The request timeout the run used.
|
|
13
|
+
*/
|
|
14
|
+
export declare function MigrationTimeoutHint(texts: ReadonlyArray<string | undefined>, currentTimeoutMs: number): string | undefined;
|
|
15
|
+
//# sourceMappingURL=migration-timeout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-timeout.d.ts","sourceRoot":"","sources":["../../src/lib/migration-timeout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,oCAAoC,UAAY,CAAC;AAK9D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO3H"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default per-request timeout for `mj migrate` (30 minutes). Skyway's own default
|
|
3
|
+
* is 5 minutes, which at least one baseline batch exceeds (#3168). Override with
|
|
4
|
+
* `MJ_MIGRATION_REQUEST_TIMEOUT` (milliseconds) or `dbRequestTimeout` in mj.config.cjs.
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_MIGRATION_REQUEST_TIMEOUT_MS = 1_800_000;
|
|
7
|
+
/** Messages the SQL Server driver produces when a request runs past its timeout. */
|
|
8
|
+
const TIMEOUT_PATTERN = /Request failed to complete in \d+ms|Failed to cancel request in \d+ms|ETIMEOUT/i;
|
|
9
|
+
/**
|
|
10
|
+
* Returns a hint naming `MJ_MIGRATION_REQUEST_TIMEOUT` when any of the given error
|
|
11
|
+
* texts is a request timeout, otherwise `undefined`.
|
|
12
|
+
*
|
|
13
|
+
* @param texts - Error messages and log lines from the failed migration run.
|
|
14
|
+
* @param currentTimeoutMs - The request timeout the run used.
|
|
15
|
+
*/
|
|
16
|
+
export function MigrationTimeoutHint(texts, currentTimeoutMs) {
|
|
17
|
+
if (!texts.some((t) => t !== undefined && TIMEOUT_PATTERN.test(t)))
|
|
18
|
+
return undefined;
|
|
19
|
+
return (`A migration request timed out (limit ${currentTimeoutMs}ms). ` +
|
|
20
|
+
'Raise the limit with MJ_MIGRATION_REQUEST_TIMEOUT=<milliseconds> (or dbRequestTimeout in mj.config.cjs) and re-run. ' +
|
|
21
|
+
'On SQL Server a timed-out batch can leave the database partly migrated; check the history table before retrying.');
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=migration-timeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-timeout.js","sourceRoot":"","sources":["../../src/lib/migration-timeout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,SAAS,CAAC;AAE9D,oFAAoF;AACpF,MAAM,eAAe,GAAG,iFAAiF,CAAC;AAE1G;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAwC,EAAE,gBAAwB;IACnG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACrF,OAAO,CACH,wCAAwC,gBAAgB,OAAO;QAC/D,sHAAsH;QACtH,kHAAkH,CACrH,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module lib/out-of-order
|
|
3
|
+
*
|
|
4
|
+
* Decides whether `mj migrate` lets Skyway apply versioned migrations older than the
|
|
5
|
+
* database's highest applied version.
|
|
6
|
+
*
|
|
7
|
+
* Release lines make this a normal upgrade case: a fix backported to a patch line ships
|
|
8
|
+
* byte-identical (same timestamp) on both lines, so a database upgraded from that line
|
|
9
|
+
* has applied files that are newer than migrations it has never run. With `outOfOrder`
|
|
10
|
+
* off, Skyway marks those older files IGNORED and refuses the whole run.
|
|
11
|
+
*
|
|
12
|
+
* Policy:
|
|
13
|
+
* - `outOfOrder` set explicitly in the config file: honoured as written.
|
|
14
|
+
* - Not set, and the run targets the core schema: enabled for this run when Skyway
|
|
15
|
+
* reports pending files older than the highest applied version; each one is logged.
|
|
16
|
+
* - Not set, any other schema (Open Apps): left off, as before.
|
|
17
|
+
*
|
|
18
|
+
* Files at or below a baseline row in history are never affected: Skyway reports them
|
|
19
|
+
* as ABOVE_BASELINE before it considers `outOfOrder`.
|
|
20
|
+
*/
|
|
21
|
+
import type { MigrationStatus } from '@memberjunction/skyway-core';
|
|
22
|
+
/** Inputs to {@link DecideOutOfOrder}. */
|
|
23
|
+
export interface OutOfOrderInputs {
|
|
24
|
+
/** The `outOfOrder` value written in the config file, or undefined when it is not set. */
|
|
25
|
+
ExplicitSetting: boolean | undefined;
|
|
26
|
+
/** True when the run targets the core schema (`coreSchema`, normally `__mj`). */
|
|
27
|
+
IsCoreSchema: boolean;
|
|
28
|
+
/** Pending versioned migrations older than the highest applied version (see {@link FindOutOfOrderPending}). */
|
|
29
|
+
OutOfOrderPending: readonly MigrationStatus[];
|
|
30
|
+
}
|
|
31
|
+
/** Result of {@link DecideOutOfOrder}. */
|
|
32
|
+
export interface OutOfOrderDecision {
|
|
33
|
+
/** Value to hand Skyway as `Migrations.OutOfOrder` for this run. */
|
|
34
|
+
OutOfOrder: boolean;
|
|
35
|
+
/** True when the CLI turned `outOfOrder` on for this run (it was not set in config). */
|
|
36
|
+
EnabledAutomatically: boolean;
|
|
37
|
+
/** True when out-of-order files exist but the config explicitly sets `outOfOrder: false`. */
|
|
38
|
+
BlockedByExplicitSetting: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Reads `outOfOrder` from the raw (pre-Zod) config. The CLI's built-in defaults do not
|
|
42
|
+
* include the key and the schema default is applied only at parse time, so the key is
|
|
43
|
+
* present in the raw config only when the user's config file sets it.
|
|
44
|
+
*/
|
|
45
|
+
export declare function ReadExplicitOutOfOrder(rawConfig: Record<string, unknown> | undefined): boolean | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Pure: picks the versioned migrations Skyway would refuse as out of order. Skyway marks a
|
|
48
|
+
* versioned file IGNORED only when it is unapplied, above any baseline floor, below the
|
|
49
|
+
* highest applied version, and `outOfOrder` is off — exactly the files this run would skip.
|
|
50
|
+
*/
|
|
51
|
+
export declare function FindOutOfOrderPending(statusReport: readonly MigrationStatus[]): MigrationStatus[];
|
|
52
|
+
/** Pure: applies the policy described in the module header. */
|
|
53
|
+
export declare function DecideOutOfOrder(inputs: OutOfOrderInputs): OutOfOrderDecision;
|
|
54
|
+
/** True when the probe for out-of-order files is worth running (it costs one history read). */
|
|
55
|
+
export declare function ShouldProbeOutOfOrder(explicitSetting: boolean | undefined, isCoreSchema: boolean): boolean;
|
|
56
|
+
//# sourceMappingURL=out-of-order.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"out-of-order.d.ts","sourceRoot":"","sources":["../../src/lib/out-of-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,0FAA0F;IAC1F,eAAe,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,iFAAiF;IACjF,YAAY,EAAE,OAAO,CAAC;IACtB,+GAA+G;IAC/G,iBAAiB,EAAE,SAAS,eAAe,EAAE,CAAC;CAC/C;AAED,0CAA0C;AAC1C,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,UAAU,EAAE,OAAO,CAAC;IACpB,wFAAwF;IACxF,oBAAoB,EAAE,OAAO,CAAC;IAC9B,6FAA6F;IAC7F,wBAAwB,EAAE,OAAO,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAG1G;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,SAAS,eAAe,EAAE,GAAG,eAAe,EAAE,CAEjG;AAED,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,kBAAkB,CAW7E;AAED,+FAA+F;AAC/F,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,OAAO,GAAG,SAAS,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAI1G"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads `outOfOrder` from the raw (pre-Zod) config. The CLI's built-in defaults do not
|
|
3
|
+
* include the key and the schema default is applied only at parse time, so the key is
|
|
4
|
+
* present in the raw config only when the user's config file sets it.
|
|
5
|
+
*/
|
|
6
|
+
export function ReadExplicitOutOfOrder(rawConfig) {
|
|
7
|
+
const value = rawConfig?.outOfOrder;
|
|
8
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Pure: picks the versioned migrations Skyway would refuse as out of order. Skyway marks a
|
|
12
|
+
* versioned file IGNORED only when it is unapplied, above any baseline floor, below the
|
|
13
|
+
* highest applied version, and `outOfOrder` is off — exactly the files this run would skip.
|
|
14
|
+
*/
|
|
15
|
+
export function FindOutOfOrderPending(statusReport) {
|
|
16
|
+
return statusReport.filter((s) => s.Type === 'versioned' && s.State === 'IGNORED');
|
|
17
|
+
}
|
|
18
|
+
/** Pure: applies the policy described in the module header. */
|
|
19
|
+
export function DecideOutOfOrder(inputs) {
|
|
20
|
+
const hasOutOfOrder = inputs.OutOfOrderPending.length > 0;
|
|
21
|
+
if (inputs.ExplicitSetting !== undefined) {
|
|
22
|
+
return {
|
|
23
|
+
OutOfOrder: inputs.ExplicitSetting,
|
|
24
|
+
EnabledAutomatically: false,
|
|
25
|
+
BlockedByExplicitSetting: !inputs.ExplicitSetting && hasOutOfOrder,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const enable = inputs.IsCoreSchema && hasOutOfOrder;
|
|
29
|
+
return { OutOfOrder: enable, EnabledAutomatically: enable, BlockedByExplicitSetting: false };
|
|
30
|
+
}
|
|
31
|
+
/** True when the probe for out-of-order files is worth running (it costs one history read). */
|
|
32
|
+
export function ShouldProbeOutOfOrder(explicitSetting, isCoreSchema) {
|
|
33
|
+
// An explicit `true` needs no probe, and a non-core run never auto-enables. An explicit
|
|
34
|
+
// `false` on the core schema is probed only to explain the refusal Skyway will report.
|
|
35
|
+
return explicitSetting !== true && isCoreSchema;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=out-of-order.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"out-of-order.js","sourceRoot":"","sources":["../../src/lib/out-of-order.ts"],"names":[],"mappings":"AA0CA;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAA8C;IACnF,MAAM,KAAK,GAAG,SAAS,EAAE,UAAU,CAAC;IACpC,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,YAAwC;IAC5E,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;AACrF,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,gBAAgB,CAAC,MAAwB;IACvD,MAAM,aAAa,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1D,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACzC,OAAO;YACL,UAAU,EAAE,MAAM,CAAC,eAAe;YAClC,oBAAoB,EAAE,KAAK;YAC3B,wBAAwB,EAAE,CAAC,MAAM,CAAC,eAAe,IAAI,aAAa;SACnE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,IAAI,aAAa,CAAC;IACpD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC;AAC/F,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,qBAAqB,CAAC,eAAoC,EAAE,YAAqB;IAC/F,wFAAwF;IACxF,uFAAuF;IACvF,OAAO,eAAe,KAAK,IAAI,IAAI,YAAY,CAAC;AAClD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"light-commands.d.ts","sourceRoot":"","sources":["../src/light-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"light-commands.d.ts","sourceRoot":"","sources":["../src/light-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CA0J7C,CAAC"}
|
package/dist/light-commands.js
CHANGED
|
@@ -147,5 +147,18 @@ export const LIGHT_COMMANDS = new Set([
|
|
|
147
147
|
'dbdoc:reset',
|
|
148
148
|
'dbdoc status',
|
|
149
149
|
'dbdoc:status',
|
|
150
|
+
// Diagnostic Bundles offline inspection & keygen - uses @memberjunction/diagnostics (L0, zero bootstrap)
|
|
151
|
+
'diag inspect',
|
|
152
|
+
'diag:inspect',
|
|
153
|
+
'diag scrub',
|
|
154
|
+
'diag:scrub',
|
|
155
|
+
'diag keygen',
|
|
156
|
+
'diag:keygen',
|
|
157
|
+
'diag timeline',
|
|
158
|
+
'diag:timeline',
|
|
159
|
+
'diag slow',
|
|
160
|
+
'diag:slow',
|
|
161
|
+
'diag export',
|
|
162
|
+
'diag:export',
|
|
150
163
|
]);
|
|
151
164
|
//# sourceMappingURL=light-commands.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"light-commands.js","sourceRoot":"","sources":["../src/light-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IACzD,yBAAyB;IACzB,SAAS;IACT,MAAM;IAEN,0EAA0E;IAC1E,qEAAqE;IACrE,OAAO;IACP,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,eAAe;IACf,WAAW;IACX,WAAW;IACX,oFAAoF;IACpF,kFAAkF;IAClF,kFAAkF;IAClF,oFAAoF;IACpF,2CAA2C;IAC3C,UAAU;IACV,UAAU;IACV,aAAa;IACb,aAAa;IACb,WAAW;IACX,WAAW;IACX,iBAAiB;IACjB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,cAAc;IACd,aAAa;IACb,aAAa;IACb,aAAa;IACb,aAAa;IACb,cAAc;IACd,cAAc;IACd,eAAe;IACf,eAAe;IACf,eAAe;IACf,eAAe;IACf,cAAc;IACd,cAAc;IACd,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,mBAAmB;IACnB,mBAAmB;IACnB,iBAAiB;IACjB,iBAAiB;IACjB,YAAY;IACZ,YAAY;IACZ,qBAAqB;IACrB,qBAAqB;IACrB,cAAc;IACd,cAAc;IAEd,4DAA4D;IAC5D,YAAY;IACZ,YAAY;IAEZ,sCAAsC;IACtC,MAAM;IAEN,2EAA2E;IAC3E,OAAO;IACP,aAAa;IACb,aAAa;IACb,aAAa;IACb,aAAa;IAEb,oEAAoE;IACpE,OAAO;IACP,SAAS;IACT,iBAAiB;IACjB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAEhB,qFAAqF;IACrF,SAAS;IAET,6EAA6E;IAC7E,QAAQ;IAER,4FAA4F;IAC5F,QAAQ;IAER,kEAAkE;IAClE,IAAI;IACJ,OAAO;IACP,UAAU;IACV,UAAU;IACV,MAAM;IACN,OAAO;IACP,KAAK;IAEL,mEAAmE;IACnE,eAAe;IACf,eAAe;IACf,sBAAsB;IACtB,sBAAsB;IACtB,sBAAsB;IACtB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IAErB,gFAAgF;IAChF,aAAa;IACb,WAAW;IAEX,8EAA8E;IAC9E,oCAAoC;IACpC,gBAAgB;IAChB,eAAe;IAEf,kGAAkG;IAClG,yFAAyF;IACzF,+FAA+F;IAC/F,kBAAkB;IAClB,kBAAkB;IAElB,0DAA0D;IAC1D,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,eAAe;IACf,cAAc;IACd,cAAc;IACd,6BAA6B;IAC7B,6BAA6B;IAC7B,wBAAwB;IACxB,wBAAwB;IACxB,aAAa;IACb,aAAa;IACb,cAAc;IACd,cAAc;
|
|
1
|
+
{"version":3,"file":"light-commands.js","sourceRoot":"","sources":["../src/light-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IACzD,yBAAyB;IACzB,SAAS;IACT,MAAM;IAEN,0EAA0E;IAC1E,qEAAqE;IACrE,OAAO;IACP,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,eAAe;IACf,WAAW;IACX,WAAW;IACX,oFAAoF;IACpF,kFAAkF;IAClF,kFAAkF;IAClF,oFAAoF;IACpF,2CAA2C;IAC3C,UAAU;IACV,UAAU;IACV,aAAa;IACb,aAAa;IACb,WAAW;IACX,WAAW;IACX,iBAAiB;IACjB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,cAAc;IACd,aAAa;IACb,aAAa;IACb,aAAa;IACb,aAAa;IACb,cAAc;IACd,cAAc;IACd,eAAe;IACf,eAAe;IACf,eAAe;IACf,eAAe;IACf,cAAc;IACd,cAAc;IACd,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,mBAAmB;IACnB,mBAAmB;IACnB,iBAAiB;IACjB,iBAAiB;IACjB,YAAY;IACZ,YAAY;IACZ,qBAAqB;IACrB,qBAAqB;IACrB,cAAc;IACd,cAAc;IAEd,4DAA4D;IAC5D,YAAY;IACZ,YAAY;IAEZ,sCAAsC;IACtC,MAAM;IAEN,2EAA2E;IAC3E,OAAO;IACP,aAAa;IACb,aAAa;IACb,aAAa;IACb,aAAa;IAEb,oEAAoE;IACpE,OAAO;IACP,SAAS;IACT,iBAAiB;IACjB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAEhB,qFAAqF;IACrF,SAAS;IAET,6EAA6E;IAC7E,QAAQ;IAER,4FAA4F;IAC5F,QAAQ;IAER,kEAAkE;IAClE,IAAI;IACJ,OAAO;IACP,UAAU;IACV,UAAU;IACV,MAAM;IACN,OAAO;IACP,KAAK;IAEL,mEAAmE;IACnE,eAAe;IACf,eAAe;IACf,sBAAsB;IACtB,sBAAsB;IACtB,sBAAsB;IACtB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IAErB,gFAAgF;IAChF,aAAa;IACb,WAAW;IAEX,8EAA8E;IAC9E,oCAAoC;IACpC,gBAAgB;IAChB,eAAe;IAEf,kGAAkG;IAClG,yFAAyF;IACzF,+FAA+F;IAC/F,kBAAkB;IAClB,kBAAkB;IAElB,0DAA0D;IAC1D,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,eAAe;IACf,cAAc;IACd,cAAc;IACd,6BAA6B;IAC7B,6BAA6B;IAC7B,wBAAwB;IACxB,wBAAwB;IACxB,aAAa;IACb,aAAa;IACb,cAAc;IACd,cAAc;IAEd,yGAAyG;IACzG,cAAc;IACd,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,aAAa;IACb,eAAe;IACf,eAAe;IACf,WAAW;IACX,WAAW;IACX,aAAa;IACb,aAAa;CACd,CAAC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type DiagnosticBundleData, type DiagnosticBundleManifest, type DiagnosticScrubberProfile } from '@memberjunction/diagnostics';
|
|
2
|
+
/** Environment variable that holds the base64 PKCS#8 X25519 private key for encrypted bundles. */
|
|
3
|
+
export declare const DIAG_PRIVATE_KEY_ENV_VAR = "MJ_DIAG_PRIVATE_KEY";
|
|
4
|
+
/** Private key flags shared by the `mj diag` commands that read bundles. */
|
|
5
|
+
export declare const DiagPrivateKeyFlags: {
|
|
6
|
+
'private-key': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
'private-key-file': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
export interface DiagPrivateKeyFlagValues {
|
|
10
|
+
'private-key'?: string;
|
|
11
|
+
'private-key-file'?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Returns the private key from `--private-key`, then `--private-key-file`, then `MJ_DIAG_PRIVATE_KEY`.
|
|
15
|
+
* Returns undefined when none is given. Throws when the key file cannot be read or is empty.
|
|
16
|
+
*/
|
|
17
|
+
export declare function ResolveDiagnosticPrivateKey(flags: DiagPrivateKeyFlagValues, env?: NodeJS.ProcessEnv): string | undefined;
|
|
18
|
+
export interface LoadedDiagnosticBundle {
|
|
19
|
+
WasEncrypted: boolean;
|
|
20
|
+
Manifest: DiagnosticBundleManifest;
|
|
21
|
+
Data: DiagnosticBundleData;
|
|
22
|
+
}
|
|
23
|
+
export declare function LoadAndVerifyDiagnosticBundle(filePath: string, recipientPrivateKeyBase64?: string): Promise<LoadedDiagnosticBundle>;
|
|
24
|
+
export declare function RescrubDiagnosticBundle(manifest: DiagnosticBundleManifest, data: DiagnosticBundleData, profile: DiagnosticScrubberProfile): Promise<Uint8Array>;
|
|
25
|
+
export interface TimelineRow {
|
|
26
|
+
TimestampUnixMs: number;
|
|
27
|
+
Source: 'client-span' | 'server-span' | 'sql' | 'breadcrumb';
|
|
28
|
+
DurationMs: number;
|
|
29
|
+
Label: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function BuildBundleTimeline(data: DiagnosticBundleData, limit?: number): TimelineRow[];
|
|
32
|
+
export declare function FindSlowBundleOperations(data: DiagnosticBundleData, thresholdMs?: number): TimelineRow[];
|
|
33
|
+
export declare function ExportBundleTraces(data: DiagnosticBundleData, format: 'perfetto' | 'otlp'): string;
|
|
34
|
+
//# sourceMappingURL=diag-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diag-utils.d.ts","sourceRoot":"","sources":["../../src/utils/diag-utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAUH,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EACjC,MAAM,6BAA6B,CAAC;AAErC,kGAAkG;AAClG,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB;;;CAQ/B,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACvC,KAAK,EAAE,wBAAwB,EAC/B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACrC,MAAM,GAAG,SAAS,CAqBpB;AAED,MAAM,WAAW,sBAAsB;IACnC,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,IAAI,EAAE,oBAAoB,CAAC;CAC9B;AAED,wBAAsB,6BAA6B,CAC/C,QAAQ,EAAE,MAAM,EAChB,yBAAyB,CAAC,EAAE,MAAM,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAoCjC;AAED,wBAAsB,uBAAuB,CACzC,QAAQ,EAAE,wBAAwB,EAClC,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,yBAAyB,GACnC,OAAO,CAAC,UAAU,CAAC,CAarB;AAED,MAAM,WAAW,WAAW;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,aAAa,GAAG,aAAa,GAAG,KAAK,GAAG,YAAY,CAAC;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACjB;AAeD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,SAAK,GAAG,WAAW,EAAE,CAsCzF;AAED,wBAAgB,wBAAwB,CACpC,IAAI,EAAE,oBAAoB,EAC1B,WAAW,SAAM,GAClB,WAAW,EAAE,CAKf;AAED,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,UAAU,GAAG,MAAM,GAC5B,MAAM,CAKR"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
3
|
+
import { BuildMjdiagArchive, VerifyBundleArchive, ParseBundleDataFromArchive, DecryptDiagnosticBundle, InspectEncryptedEnvelopeHeader, ScrubBundleDataWithCount, ExportToPerfettoTrace, ExportToOtlpJson, } from '@memberjunction/diagnostics';
|
|
4
|
+
/** Environment variable that holds the base64 PKCS#8 X25519 private key for encrypted bundles. */
|
|
5
|
+
export const DIAG_PRIVATE_KEY_ENV_VAR = 'MJ_DIAG_PRIVATE_KEY';
|
|
6
|
+
/** Private key flags shared by the `mj diag` commands that read bundles. */
|
|
7
|
+
export const DiagPrivateKeyFlags = {
|
|
8
|
+
'private-key': Flags.string({
|
|
9
|
+
description: 'Base64 PKCS#8 X25519 private key for an encrypted MJDB envelope. The value is visible to other processes and stays in shell history; prefer --private-key-file or MJ_DIAG_PRIVATE_KEY',
|
|
10
|
+
}),
|
|
11
|
+
'private-key-file': Flags.string({
|
|
12
|
+
description: 'Path to a file that holds the base64 PKCS#8 X25519 private key for an encrypted MJDB envelope',
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Returns the private key from `--private-key`, then `--private-key-file`, then `MJ_DIAG_PRIVATE_KEY`.
|
|
17
|
+
* Returns undefined when none is given. Throws when the key file cannot be read or is empty.
|
|
18
|
+
*/
|
|
19
|
+
export function ResolveDiagnosticPrivateKey(flags, env = process.env) {
|
|
20
|
+
if (flags['private-key']) {
|
|
21
|
+
return flags['private-key'];
|
|
22
|
+
}
|
|
23
|
+
const keyFile = flags['private-key-file'];
|
|
24
|
+
if (keyFile) {
|
|
25
|
+
let fileText;
|
|
26
|
+
try {
|
|
27
|
+
fileText = fs.readFileSync(keyFile, 'utf8');
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
31
|
+
throw new Error(`Cannot read the private key file "${keyFile}": ${reason}`);
|
|
32
|
+
}
|
|
33
|
+
const key = fileText.trim();
|
|
34
|
+
if (!key) {
|
|
35
|
+
throw new Error(`The private key file "${keyFile}" is empty.`);
|
|
36
|
+
}
|
|
37
|
+
return key;
|
|
38
|
+
}
|
|
39
|
+
const envKey = env[DIAG_PRIVATE_KEY_ENV_VAR]?.trim();
|
|
40
|
+
return envKey ? envKey : undefined;
|
|
41
|
+
}
|
|
42
|
+
export async function LoadAndVerifyDiagnosticBundle(filePath, recipientPrivateKeyBase64) {
|
|
43
|
+
const rawBytes = new Uint8Array(fs.readFileSync(filePath));
|
|
44
|
+
const envelopeCheck = InspectEncryptedEnvelopeHeader(rawBytes);
|
|
45
|
+
let zipBytes = rawBytes;
|
|
46
|
+
let wasEncrypted = false;
|
|
47
|
+
if (envelopeCheck.valid && envelopeCheck.header) {
|
|
48
|
+
if (!recipientPrivateKeyBase64) {
|
|
49
|
+
throw new Error(`File "${filePath}" is an encrypted MJDB envelope (recipientKeyId=${envelopeCheck.header.recipientKeyId}). Pass --private-key-file, set ${DIAG_PRIVATE_KEY_ENV_VAR}, or pass --private-key to decrypt.`);
|
|
50
|
+
}
|
|
51
|
+
const decrypted = await DecryptDiagnosticBundle(rawBytes, {
|
|
52
|
+
PrivateKeysByKeyId: {
|
|
53
|
+
[envelopeCheck.header.recipientKeyId]: recipientPrivateKeyBase64,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
if (!decrypted.valid || !decrypted.decryptedZipBytes) {
|
|
57
|
+
throw new Error(`Failed to decrypt "${filePath}": ${decrypted.reason}`);
|
|
58
|
+
}
|
|
59
|
+
zipBytes = decrypted.decryptedZipBytes;
|
|
60
|
+
wasEncrypted = true;
|
|
61
|
+
}
|
|
62
|
+
const verification = await VerifyBundleArchive(zipBytes);
|
|
63
|
+
if (!verification.valid || !verification.manifest) {
|
|
64
|
+
throw new Error(`Invalid .mjdiag bundle "${filePath}": ${verification.reason}`);
|
|
65
|
+
}
|
|
66
|
+
const data = ParseBundleDataFromArchive(verification);
|
|
67
|
+
return {
|
|
68
|
+
WasEncrypted: wasEncrypted,
|
|
69
|
+
Manifest: verification.manifest,
|
|
70
|
+
Data: data,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export async function RescrubDiagnosticBundle(manifest, data, profile) {
|
|
74
|
+
const scrubbed = ScrubBundleDataWithCount(data, profile);
|
|
75
|
+
return BuildMjdiagArchive(scrubbed.Data, {
|
|
76
|
+
bundleId: manifest.bundleId,
|
|
77
|
+
sessionId: manifest.sessionId,
|
|
78
|
+
captureReason: manifest.captureReason,
|
|
79
|
+
scrubberProfile: profile,
|
|
80
|
+
redactionSummary: {
|
|
81
|
+
credentialsScrubbedCount: scrubbed.CredentialsScrubbedCount,
|
|
82
|
+
sqlLiteralsNormalizedCount: profile === 'Standard' ? scrubbed.Data.serverSql.length : 0,
|
|
83
|
+
customPatternsAppliedCount: 0,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/** Milliseconds since the epoch for an ISO timestamp, or 0 when it does not parse. */
|
|
88
|
+
function isoToUnixMs(timestamp) {
|
|
89
|
+
const parsedMs = Date.parse(timestamp);
|
|
90
|
+
return Number.isNaN(parsedMs) ? 0 : parsedMs;
|
|
91
|
+
}
|
|
92
|
+
/** `[type] target (detail) on route` for a breadcrumb. The route is left out when it is the target. */
|
|
93
|
+
function breadcrumbLabel(crumb) {
|
|
94
|
+
const detail = crumb.detail ? ` (${crumb.detail})` : '';
|
|
95
|
+
const route = crumb.route && crumb.route !== crumb.target ? ` on ${crumb.route}` : '';
|
|
96
|
+
return `[${crumb.type ?? crumb.kind ?? 'step'}] ${crumb.target}${detail}${route}`;
|
|
97
|
+
}
|
|
98
|
+
export function BuildBundleTimeline(data, limit = 50) {
|
|
99
|
+
const rows = [];
|
|
100
|
+
for (const wf of data.clientWaterfall) {
|
|
101
|
+
rows.push({
|
|
102
|
+
TimestampUnixMs: wf.startTimeUnixMs,
|
|
103
|
+
Source: 'client-span',
|
|
104
|
+
DurationMs: wf.durationMs,
|
|
105
|
+
Label: `[${wf.operationKind}] ${wf.operationName}`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
for (const s of data.serverTraces) {
|
|
109
|
+
rows.push({
|
|
110
|
+
TimestampUnixMs: s.startTimeUnixMs,
|
|
111
|
+
Source: 'server-span',
|
|
112
|
+
DurationMs: s.durationMs,
|
|
113
|
+
Label: `[${s.layer}] ${s.name}`,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
for (const q of data.serverSql) {
|
|
117
|
+
rows.push({
|
|
118
|
+
TimestampUnixMs: isoToUnixMs(q.timestamp),
|
|
119
|
+
Source: 'sql',
|
|
120
|
+
DurationMs: q.durationMs,
|
|
121
|
+
Label: q.sql,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
for (const crumb of data.repro.breadcrumbs) {
|
|
125
|
+
rows.push({
|
|
126
|
+
TimestampUnixMs: isoToUnixMs(crumb.timestamp),
|
|
127
|
+
Source: 'breadcrumb',
|
|
128
|
+
DurationMs: 0,
|
|
129
|
+
Label: breadcrumbLabel(crumb),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
rows.sort((a, b) => a.TimestampUnixMs - b.TimestampUnixMs);
|
|
133
|
+
return rows.slice(0, limit);
|
|
134
|
+
}
|
|
135
|
+
export function FindSlowBundleOperations(data, thresholdMs = 500) {
|
|
136
|
+
const all = BuildBundleTimeline(data, Number.MAX_SAFE_INTEGER);
|
|
137
|
+
return all
|
|
138
|
+
.filter((r) => r.DurationMs >= thresholdMs)
|
|
139
|
+
.sort((a, b) => b.DurationMs - a.DurationMs);
|
|
140
|
+
}
|
|
141
|
+
export function ExportBundleTraces(data, format) {
|
|
142
|
+
if (format === 'perfetto') {
|
|
143
|
+
return JSON.stringify(ExportToPerfettoTrace(data), null, 2);
|
|
144
|
+
}
|
|
145
|
+
return JSON.stringify(ExportToOtlpJson(data), null, 2);
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=diag-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diag-utils.js","sourceRoot":"","sources":["../../src/utils/diag-utils.ts"],"names":[],"mappings":"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"}
|