@prisma-next/cli 0.12.0-dev.48 → 0.12.0-dev.49
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/cli.mjs +12 -12
- package/dist/{client-CJWPvdKj.mjs → client-DC-UlBLy.mjs} +4 -4
- package/dist/{client-CJWPvdKj.mjs.map → client-DC-UlBLy.mjs.map} +1 -1
- package/dist/{command-helpers-C6lqKJG1.mjs → command-helpers-esJGBD4W.mjs} +5 -5
- package/dist/command-helpers-esJGBD4W.mjs.map +1 -0
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +3 -3
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +4 -4
- package/dist/commands/db-update.mjs +4 -4
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.mjs +4 -4
- package/dist/commands/migration-check.d.mts +3 -15
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +3 -2
- package/dist/commands/migration-graph.d.mts +9 -18
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +33 -20
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.d.mts +4 -4
- package/dist/commands/migration-list.mjs +1 -1
- package/dist/commands/migration-log.d.mts +5 -20
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +1 -1
- package/dist/commands/migration-new.mjs +3 -3
- package/dist/commands/migration-plan.d.mts +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +17 -18
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +13 -13
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +24 -26
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +3 -2
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +2 -2
- package/dist/commands/telemetry/index.mjs +1 -1
- package/dist/{contract-at-errors-CVQsgp3V.mjs → contract-at-errors-COZAemUl.mjs} +2 -2
- package/dist/{contract-at-errors-CVQsgp3V.mjs.map → contract-at-errors-COZAemUl.mjs.map} +1 -1
- package/dist/{contract-emit-DnUkRd-7.mjs → contract-emit-Bv46RAIO.mjs} +3 -3
- package/dist/{contract-emit-DnUkRd-7.mjs.map → contract-emit-Bv46RAIO.mjs.map} +1 -1
- package/dist/{contract-emit-Iyq5V7OU.mjs → contract-emit-DIWImLqS.mjs} +3 -3
- package/dist/{contract-emit-Iyq5V7OU.mjs.map → contract-emit-DIWImLqS.mjs.map} +1 -1
- package/dist/{contract-infer-MmQMIms7.mjs → contract-infer-DpGN9SAj.mjs} +3 -3
- package/dist/{contract-infer-MmQMIms7.mjs.map → contract-infer-DpGN9SAj.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-BSWfMkFY.mjs → contract-space-aggregate-loader-CpNVrBqW.mjs} +2 -2
- package/dist/{contract-space-aggregate-loader-BSWfMkFY.mjs.map → contract-space-aggregate-loader-CpNVrBqW.mjs.map} +1 -1
- package/dist/{db-verify-B-YOEESk.mjs → db-verify-Cq16Obsw.mjs} +4 -4
- package/dist/{db-verify-B-YOEESk.mjs.map → db-verify-Cq16Obsw.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{framework-components-D6VMhw2T.mjs → framework-components-BO9VO43s.mjs} +2 -2
- package/dist/{framework-components-D6VMhw2T.mjs.map → framework-components-BO9VO43s.mjs.map} +1 -1
- package/dist/{global-flags-DG4uY5tV.d.mts → global-flags-CV5LhrFg.d.mts} +1 -1
- package/dist/{global-flags-DG4uY5tV.d.mts.map → global-flags-CV5LhrFg.d.mts.map} +1 -1
- package/dist/{init-Ceib8PNc.mjs → init-C0rjiQ9I.mjs} +4 -4
- package/dist/{init-Ceib8PNc.mjs.map → init-C0rjiQ9I.mjs.map} +1 -1
- package/dist/{inspect-live-schema-CjMZ0RkS.mjs → inspect-live-schema-CRDKTNcf.mjs} +3 -3
- package/dist/{inspect-live-schema-CjMZ0RkS.mjs.map → inspect-live-schema-CRDKTNcf.mjs.map} +1 -1
- package/dist/{migration-check-DkNcCXZC.mjs → migration-check-CCXNXMXJ.mjs} +49 -30
- package/dist/migration-check-CCXNXMXJ.mjs.map +1 -0
- package/dist/{migration-command-scaffold-CrRysYxV.mjs → migration-command-scaffold-BDd9abqW.mjs} +3 -3
- package/dist/{migration-command-scaffold-CrRysYxV.mjs.map → migration-command-scaffold-BDd9abqW.mjs.map} +1 -1
- package/dist/{migration-graph-space-render-ByJ83gxp.mjs → migration-graph-space-render-CeNXh_Wy.mjs} +13 -13
- package/dist/migration-graph-space-render-CeNXh_Wy.mjs.map +1 -0
- package/dist/{migration-list-ip7fKesI.mjs → migration-list-vJWFuXca.mjs} +17 -17
- package/dist/migration-list-vJWFuXca.mjs.map +1 -0
- package/dist/{migration-log-BX9vu5c9.mjs → migration-log-6rcHQSI4.mjs} +15 -8
- package/dist/migration-log-6rcHQSI4.mjs.map +1 -0
- package/dist/{migration-path-target-ByduK0eI.mjs → migration-path-target-UkxkgXnv.mjs} +2 -2
- package/dist/{migration-path-target-ByduK0eI.mjs.map → migration-path-target-UkxkgXnv.mjs.map} +1 -1
- package/dist/{migration-plan-DLbbc_7z.mjs → migration-plan-CHu_erQ5.mjs} +5 -5
- package/dist/{migration-plan-DLbbc_7z.mjs.map → migration-plan-CHu_erQ5.mjs.map} +1 -1
- package/dist/{migration-status-BtdaOuQJ.mjs → migration-status-DzdlZQJ3.mjs} +39 -35
- package/dist/migration-status-DzdlZQJ3.mjs.map +1 -0
- package/dist/{output-CF_hqzI-.mjs → output-BD61elic.mjs} +1 -1
- package/dist/{output-CF_hqzI-.mjs.map → output-BD61elic.mjs.map} +1 -1
- package/dist/schemas-BL33A3i-.d.mts +193 -0
- package/dist/schemas-BL33A3i-.d.mts.map +1 -0
- package/dist/schemas-DJY2O09F.mjs +112 -0
- package/dist/schemas-DJY2O09F.mjs.map +1 -0
- package/dist/{telemetry-CxbY4NKn.mjs → telemetry-CZkgkR_O.mjs} +2 -2
- package/dist/{telemetry-CxbY4NKn.mjs.map → telemetry-CZkgkR_O.mjs.map} +1 -1
- package/dist/{terminal-ui-5Y6mrg93.d.mts → terminal-ui-BgLiAOYi.d.mts} +1 -1
- package/dist/{terminal-ui-5Y6mrg93.d.mts.map → terminal-ui-BgLiAOYi.d.mts.map} +1 -1
- package/dist/{types-Cculk5KV.d.mts → types-qV41eEXH.d.mts} +1 -1
- package/dist/{types-Cculk5KV.d.mts.map → types-qV41eEXH.d.mts.map} +1 -1
- package/dist/{verify-Df-8Kwat.mjs → verify-IilvIk_E.mjs} +2 -2
- package/dist/{verify-Df-8Kwat.mjs.map → verify-IilvIk_E.mjs.map} +1 -1
- package/package.json +18 -18
- package/src/commands/json/schemas.ts +195 -0
- package/src/commands/migration-check.ts +33 -24
- package/src/commands/migration-graph.ts +34 -36
- package/src/commands/migration-list.ts +14 -14
- package/src/commands/migration-log.ts +6 -7
- package/src/commands/migration-show.ts +21 -28
- package/src/commands/migration-status.ts +69 -67
- package/src/utils/formatters/migration-list-graph-topology.ts +4 -4
- package/src/utils/formatters/migration-list-render.ts +12 -12
- package/src/utils/formatters/migration-list-types.ts +5 -21
- package/src/utils/formatters/migration-log-table.ts +12 -7
- package/src/utils/formatters/migrations.ts +8 -10
- package/src/utils/integrity-violation-to-check-failure.ts +28 -19
- package/dist/command-helpers-C6lqKJG1.mjs.map +0 -1
- package/dist/migration-check-DkNcCXZC.mjs.map +0 -1
- package/dist/migration-graph-space-render-ByJ83gxp.mjs.map +0 -1
- package/dist/migration-list-ip7fKesI.mjs.map +0 -1
- package/dist/migration-list-types-DS63IdFd.d.mts +0 -23
- package/dist/migration-list-types-DS63IdFd.d.mts.map +0 -1
- package/dist/migration-log-BX9vu5c9.mjs.map +0 -1
- package/dist/migration-status-BtdaOuQJ.mjs.map +0 -1
|
@@ -55,9 +55,15 @@ import { formatStyledHeader } from '../utils/formatters/styled';
|
|
|
55
55
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
56
56
|
import { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
57
57
|
import { shouldShowLegend, validateLegendOptions } from '../utils/legend';
|
|
58
|
-
import type { StatusDiagnostic } from '../utils/migration-types';
|
|
59
58
|
import { handleResult } from '../utils/result-handler';
|
|
60
59
|
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
60
|
+
import type {
|
|
61
|
+
MigrationStatusEntry,
|
|
62
|
+
MigrationStatusResult,
|
|
63
|
+
MigrationStatusSpace,
|
|
64
|
+
StatusDiagnosticJson,
|
|
65
|
+
} from './json/schemas';
|
|
66
|
+
import { migrationStatusJsonResultSchema } from './json/schemas';
|
|
61
67
|
import {
|
|
62
68
|
listRefsByContractHash,
|
|
63
69
|
migrationSpaceListEntriesFromAggregate,
|
|
@@ -69,7 +75,16 @@ import {
|
|
|
69
75
|
statusForMigrationHash,
|
|
70
76
|
} from './migration-status-overlay';
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
export type { StatusRef } from '../utils/migration-types';
|
|
79
|
+
export type {
|
|
80
|
+
MigrationStatusEntry,
|
|
81
|
+
MigrationStatusResult,
|
|
82
|
+
MigrationStatusSpace,
|
|
83
|
+
StatusDiagnosticJson,
|
|
84
|
+
};
|
|
85
|
+
export { migrationStatusJsonResultSchema };
|
|
86
|
+
|
|
87
|
+
export interface MigrationStatusOptions extends CommonCommandOptions {
|
|
73
88
|
readonly db?: string;
|
|
74
89
|
readonly config?: string;
|
|
75
90
|
readonly to?: string;
|
|
@@ -79,34 +94,20 @@ interface MigrationStatusOptions extends CommonCommandOptions {
|
|
|
79
94
|
readonly ascii?: boolean;
|
|
80
95
|
}
|
|
81
96
|
|
|
82
|
-
export interface
|
|
83
|
-
readonly
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
export interface MigrationStatusSpaceResult {
|
|
87
|
-
readonly spaceId: string;
|
|
88
|
-
readonly markerHash: string | null;
|
|
89
|
-
readonly targetHash: string;
|
|
90
|
-
readonly migrations: readonly MigrationStatusMigrationEntry[];
|
|
97
|
+
export interface MigrationStatusTreeSection {
|
|
98
|
+
readonly space: string;
|
|
99
|
+
readonly tree: string;
|
|
100
|
+
readonly showHeading: boolean;
|
|
91
101
|
}
|
|
92
102
|
|
|
93
|
-
|
|
103
|
+
interface MigrationStatusCommandResult {
|
|
94
104
|
readonly ok: true;
|
|
95
|
-
readonly spaces: readonly
|
|
105
|
+
readonly spaces: readonly MigrationStatusSpace[];
|
|
96
106
|
readonly summary: string;
|
|
97
|
-
readonly
|
|
98
|
-
readonly diagnostics: readonly StatusDiagnostic[];
|
|
107
|
+
readonly diagnostics: readonly StatusDiagnosticJson[];
|
|
99
108
|
readonly treeSections: readonly MigrationStatusTreeSection[];
|
|
100
109
|
}
|
|
101
110
|
|
|
102
|
-
export interface MigrationStatusTreeSection {
|
|
103
|
-
readonly spaceId: string;
|
|
104
|
-
readonly tree: string;
|
|
105
|
-
readonly showHeading: boolean;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export type { StatusDiagnostic, StatusRef } from '../utils/migration-types';
|
|
109
|
-
|
|
110
111
|
function shortDisplayHash(hash: string): string {
|
|
111
112
|
const stripped = hash.startsWith('sha256:') ? hash.slice(7) : hash;
|
|
112
113
|
return stripped.slice(0, 12);
|
|
@@ -119,10 +120,10 @@ function resolveTarget(contractHash: string, activeRefHash: string | undefined):
|
|
|
119
120
|
function buildStatusMigrations(
|
|
120
121
|
listMigrations: readonly MigrationListEntry[],
|
|
121
122
|
annotations: ReadonlyMap<string, MigrationEdgeAnnotation>,
|
|
122
|
-
): readonly
|
|
123
|
+
): readonly MigrationStatusEntry[] {
|
|
123
124
|
return listMigrations.map((migration) => ({
|
|
124
125
|
...migration,
|
|
125
|
-
status: statusForMigrationHash(migration.
|
|
126
|
+
status: statusForMigrationHash(migration.hash, annotations),
|
|
126
127
|
}));
|
|
127
128
|
}
|
|
128
129
|
|
|
@@ -160,7 +161,7 @@ function renderSpaceTree(args: {
|
|
|
160
161
|
});
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
function countPending(migrations: readonly
|
|
164
|
+
function countPending(migrations: readonly MigrationStatusEntry[]): number {
|
|
164
165
|
return migrations.filter((m) => m.status === 'pending').length;
|
|
165
166
|
}
|
|
166
167
|
|
|
@@ -200,7 +201,10 @@ export function buildStatusHeadline(args: {
|
|
|
200
201
|
return `${args.pendingCount} pending — run \`prisma-next migrate --to ${shortDisplayHash(args.targetHash)}\``;
|
|
201
202
|
}
|
|
202
203
|
|
|
203
|
-
export function formatStatusSummary(
|
|
204
|
+
export function formatStatusSummary(
|
|
205
|
+
result: MigrationStatusCommandResult,
|
|
206
|
+
colorize: boolean,
|
|
207
|
+
): string {
|
|
204
208
|
const c = (fn: (s: string) => string, s: string) => (colorize ? fn(s) : s);
|
|
205
209
|
const lines: string[] = [];
|
|
206
210
|
const pendingTotal = result.spaces.reduce(
|
|
@@ -215,17 +219,23 @@ export function formatStatusSummary(result: MigrationStatusResult, colorize: boo
|
|
|
215
219
|
} else {
|
|
216
220
|
lines.push(result.summary);
|
|
217
221
|
}
|
|
218
|
-
|
|
219
|
-
|
|
222
|
+
const missingInvariantsDiagnostic = result.diagnostics.find(
|
|
223
|
+
(d) => d.code === 'MIGRATION.MISSING_INVARIANTS',
|
|
224
|
+
);
|
|
225
|
+
if (missingInvariantsDiagnostic !== undefined) {
|
|
226
|
+
lines.push(c(dim, missingInvariantsDiagnostic.message));
|
|
220
227
|
}
|
|
221
228
|
return lines.join('\n');
|
|
222
229
|
}
|
|
223
230
|
|
|
224
|
-
export function formatStatusHumanOutput(
|
|
231
|
+
export function formatStatusHumanOutput(
|
|
232
|
+
result: MigrationStatusCommandResult,
|
|
233
|
+
colorize: boolean,
|
|
234
|
+
): string {
|
|
225
235
|
const sections: string[] = [];
|
|
226
236
|
for (const section of result.treeSections) {
|
|
227
237
|
if (section.showHeading) {
|
|
228
|
-
sections.push(`${section.
|
|
238
|
+
sections.push(`${section.space}:`);
|
|
229
239
|
}
|
|
230
240
|
if (section.tree.length > 0) {
|
|
231
241
|
sections.push(section.tree);
|
|
@@ -257,11 +267,11 @@ async function readMarkersAndLedgers(args: {
|
|
|
257
267
|
return { markersBySpace, ledgersBySpace };
|
|
258
268
|
}
|
|
259
269
|
|
|
260
|
-
async function executeMigrationStatusCommand(
|
|
270
|
+
export async function executeMigrationStatusCommand(
|
|
261
271
|
options: MigrationStatusOptions,
|
|
262
272
|
flags: GlobalFlags,
|
|
263
273
|
ui: TerminalUI,
|
|
264
|
-
): Promise<Result<
|
|
274
|
+
): Promise<Result<MigrationStatusCommandResult, CliStructuredError>> {
|
|
265
275
|
const config = await loadConfig(options.config);
|
|
266
276
|
const { configPath, migrationsDir, migrationsRelative, refsDir } = resolveMigrationPaths(
|
|
267
277
|
options.config,
|
|
@@ -294,7 +304,7 @@ async function executeMigrationStatusCommand(
|
|
|
294
304
|
throw error;
|
|
295
305
|
}
|
|
296
306
|
|
|
297
|
-
const diagnostics:
|
|
307
|
+
const diagnostics: StatusDiagnosticJson[] = [];
|
|
298
308
|
let contractHash: string = EMPTY_CONTRACT_HASH;
|
|
299
309
|
try {
|
|
300
310
|
const envelope = await readContractEnvelope(config);
|
|
@@ -414,7 +424,7 @@ async function executeMigrationStatusCommand(
|
|
|
414
424
|
connected = true;
|
|
415
425
|
const read = await readMarkersAndLedgers({
|
|
416
426
|
client,
|
|
417
|
-
spaceIds: scopedSpaces.map((s) => s.
|
|
427
|
+
spaceIds: scopedSpaces.map((s) => s.space),
|
|
418
428
|
});
|
|
419
429
|
markersBySpace = new Map(read.markersBySpace);
|
|
420
430
|
ledgersBySpace = new Map(read.ledgersBySpace);
|
|
@@ -456,7 +466,7 @@ async function executeMigrationStatusCommand(
|
|
|
456
466
|
const glyphMode = ui.resolveGlyphMode(options.ascii === true);
|
|
457
467
|
const colorize = flags.color !== false;
|
|
458
468
|
|
|
459
|
-
const statusSpaces:
|
|
469
|
+
const statusSpaces: MigrationStatusSpace[] = [];
|
|
460
470
|
const treeSections: MigrationStatusTreeSection[] = [];
|
|
461
471
|
let markerDiverged = false;
|
|
462
472
|
let markerCannotReachTarget = false;
|
|
@@ -467,7 +477,7 @@ async function executeMigrationStatusCommand(
|
|
|
467
477
|
? scopedSpaces
|
|
468
478
|
.filter((spaceEntry) => spaceEntry.migrations.length > 0)
|
|
469
479
|
.map((spaceEntry) => ({
|
|
470
|
-
graph: aggregate.space(spaceEntry.
|
|
480
|
+
graph: aggregate.space(spaceEntry.space)!.graph(),
|
|
471
481
|
liveContractHash: contractHash,
|
|
472
482
|
}))
|
|
473
483
|
: [];
|
|
@@ -479,18 +489,18 @@ async function executeMigrationStatusCommand(
|
|
|
479
489
|
globalLayoutInputs.length > 0 ? computeGlobalMaxDirNameWidth(globalLayoutInputs) : undefined;
|
|
480
490
|
|
|
481
491
|
for (const spaceEntry of scopedSpaces) {
|
|
482
|
-
const member = aggregate.space(spaceEntry.
|
|
492
|
+
const member = aggregate.space(spaceEntry.space);
|
|
483
493
|
if (member === undefined) {
|
|
484
494
|
continue;
|
|
485
495
|
}
|
|
486
496
|
const graph = member.graph();
|
|
487
497
|
const spaceContractHash = member.contract().storage.storageHash;
|
|
488
498
|
const targetHash = resolveTarget(spaceContractHash, activeRefHash);
|
|
489
|
-
if (spaceEntry.
|
|
499
|
+
if (spaceEntry.space === aggregate.app.spaceId) {
|
|
490
500
|
headlineTargetHash = targetHash;
|
|
491
501
|
}
|
|
492
502
|
|
|
493
|
-
const markerRecord = markersBySpace.get(spaceEntry.
|
|
503
|
+
const markerRecord = markersBySpace.get(spaceEntry.space);
|
|
494
504
|
const markerHash = usingFromOverride
|
|
495
505
|
? fromOverrideHash
|
|
496
506
|
: (markerRecord?.storageHash ?? undefined);
|
|
@@ -521,7 +531,7 @@ async function executeMigrationStatusCommand(
|
|
|
521
531
|
});
|
|
522
532
|
}
|
|
523
533
|
|
|
524
|
-
const ledger = ledgersBySpace.get(spaceEntry.
|
|
534
|
+
const ledger = ledgersBySpace.get(spaceEntry.space) ?? [];
|
|
525
535
|
const appliedHashes = showAppliedOverlay ? appliedHashesFromLedger(ledger) : new Set<string>();
|
|
526
536
|
|
|
527
537
|
const annotations = deriveStatusEdgeAnnotations({
|
|
@@ -548,27 +558,31 @@ async function executeMigrationStatusCommand(
|
|
|
548
558
|
totalPending += pending;
|
|
549
559
|
|
|
550
560
|
statusSpaces.push({
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
targetHash,
|
|
554
|
-
migrations,
|
|
561
|
+
space: spaceEntry.space,
|
|
562
|
+
currentContract: markerHash ?? null,
|
|
563
|
+
targetContract: targetHash,
|
|
564
|
+
migrations: [...migrations],
|
|
555
565
|
});
|
|
556
566
|
const displayTree =
|
|
557
567
|
showSpaceHeadings && tree.length > 0 ? indentMigrationGraphTreeBlock(tree, ' ') : tree;
|
|
558
568
|
treeSections.push({
|
|
559
|
-
|
|
569
|
+
space: spaceEntry.space,
|
|
560
570
|
tree: displayTree,
|
|
561
571
|
showHeading: showSpaceHeadings,
|
|
562
572
|
});
|
|
563
573
|
}
|
|
564
574
|
|
|
565
|
-
let missingInvariantsLine: string | undefined;
|
|
566
575
|
if (connected && requiredInvariants.length > 0) {
|
|
567
576
|
const markerInvariants = markersBySpace.get(aggregate.app.spaceId)?.invariants ?? [];
|
|
568
577
|
const markerSet = new Set(markerInvariants);
|
|
569
578
|
const missing = requiredInvariants.filter((id) => !markerSet.has(id));
|
|
570
579
|
if (missing.length > 0) {
|
|
571
|
-
|
|
580
|
+
diagnostics.push({
|
|
581
|
+
code: 'MIGRATION.MISSING_INVARIANTS',
|
|
582
|
+
...ifDefined('ref', activeRefName),
|
|
583
|
+
invariants: missing,
|
|
584
|
+
message: `missing invariant(s): ${missing.join(', ')}`,
|
|
585
|
+
});
|
|
572
586
|
if (activeRefHash !== undefined) {
|
|
573
587
|
const originHash =
|
|
574
588
|
markersBySpace.get(aggregate.app.spaceId)?.storageHash ?? EMPTY_CONTRACT_HASH;
|
|
@@ -614,7 +628,6 @@ async function executeMigrationStatusCommand(
|
|
|
614
628
|
summary: 'No migrations found',
|
|
615
629
|
diagnostics,
|
|
616
630
|
treeSections,
|
|
617
|
-
...ifDefined('missingInvariantsLine', missingInvariantsLine),
|
|
618
631
|
});
|
|
619
632
|
}
|
|
620
633
|
|
|
@@ -624,7 +637,6 @@ async function executeMigrationStatusCommand(
|
|
|
624
637
|
summary,
|
|
625
638
|
diagnostics,
|
|
626
639
|
treeSections,
|
|
627
|
-
...ifDefined('missingInvariantsLine', missingInvariantsLine),
|
|
628
640
|
});
|
|
629
641
|
}
|
|
630
642
|
|
|
@@ -680,23 +692,13 @@ export function createMigrationStatusCommand(): Command {
|
|
|
680
692
|
|
|
681
693
|
const exitCode = handleResult(result, flags, ui, (statusResult) => {
|
|
682
694
|
if (flags.json) {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
? { diagnostics: statusResult.diagnostics }
|
|
691
|
-
: {}),
|
|
692
|
-
...(statusResult.missingInvariantsLine
|
|
693
|
-
? { missingInvariants: statusResult.missingInvariantsLine }
|
|
694
|
-
: {}),
|
|
695
|
-
},
|
|
696
|
-
null,
|
|
697
|
-
2,
|
|
698
|
-
),
|
|
699
|
-
);
|
|
695
|
+
const jsonResult: MigrationStatusResult = {
|
|
696
|
+
ok: true,
|
|
697
|
+
spaces: [...statusResult.spaces],
|
|
698
|
+
summary: statusResult.summary,
|
|
699
|
+
diagnostics: [...statusResult.diagnostics],
|
|
700
|
+
};
|
|
701
|
+
ui.output(JSON.stringify(jsonResult, null, 2));
|
|
700
702
|
} else if (!flags.quiet) {
|
|
701
703
|
ui.output(formatStatusHumanOutput(statusResult, flags.color !== false));
|
|
702
704
|
}
|
|
@@ -319,10 +319,10 @@ export function classifyMigrationListGraphTopology(
|
|
|
319
319
|
entries: readonly MigrationListEntry[],
|
|
320
320
|
): MigrationListGraphTopology {
|
|
321
321
|
const normalized: NormalizedEdge[] = entries.map((entry) => ({
|
|
322
|
-
hash: entry.
|
|
323
|
-
from: canonicalFrom(entry.
|
|
324
|
-
to: entry.
|
|
325
|
-
dirName: entry.
|
|
322
|
+
hash: entry.hash,
|
|
323
|
+
from: canonicalFrom(entry.fromContract),
|
|
324
|
+
to: entry.toContract,
|
|
325
|
+
dirName: entry.name,
|
|
326
326
|
}));
|
|
327
327
|
return classifyNormalizedEdges(normalized);
|
|
328
328
|
}
|
|
@@ -72,24 +72,24 @@ export function migrationGraphFromListEntries(
|
|
|
72
72
|
const migrationByHash = new Map<string, MigrationEdge>();
|
|
73
73
|
|
|
74
74
|
for (const entry of entries) {
|
|
75
|
-
const from = canonicalFrom(entry.
|
|
75
|
+
const from = canonicalFrom(entry.fromContract);
|
|
76
76
|
const edge: MigrationEdge = {
|
|
77
77
|
from,
|
|
78
|
-
to: entry.
|
|
79
|
-
migrationHash: entry.
|
|
80
|
-
dirName: entry.
|
|
78
|
+
to: entry.toContract,
|
|
79
|
+
migrationHash: entry.hash,
|
|
80
|
+
dirName: entry.name,
|
|
81
81
|
createdAt: entry.createdAt,
|
|
82
82
|
invariants: entry.providedInvariants,
|
|
83
83
|
};
|
|
84
84
|
nodes.add(from);
|
|
85
|
-
nodes.add(entry.
|
|
85
|
+
nodes.add(entry.toContract);
|
|
86
86
|
const forward = forwardChain.get(from);
|
|
87
87
|
if (forward) forward.push(edge);
|
|
88
88
|
else forwardChain.set(from, [edge]);
|
|
89
|
-
const reverse = reverseChain.get(entry.
|
|
89
|
+
const reverse = reverseChain.get(entry.toContract);
|
|
90
90
|
if (reverse) reverse.push(edge);
|
|
91
|
-
else reverseChain.set(entry.
|
|
92
|
-
migrationByHash.set(entry.
|
|
91
|
+
else reverseChain.set(entry.toContract, [edge]);
|
|
92
|
+
migrationByHash.set(entry.hash, edge);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
return { nodes, forwardChain, reverseChain, migrationByHash };
|
|
@@ -100,7 +100,7 @@ export function buildEdgeAnnotationsByHashFromListEntries(
|
|
|
100
100
|
): ReadonlyMap<string, MigrationEdgeAnnotation> {
|
|
101
101
|
const annotations = new Map<string, MigrationEdgeAnnotation>();
|
|
102
102
|
for (const entry of entries) {
|
|
103
|
-
annotations.set(entry.
|
|
103
|
+
annotations.set(entry.hash, {
|
|
104
104
|
operationCount: entry.operationCount,
|
|
105
105
|
invariants: entry.providedInvariants,
|
|
106
106
|
});
|
|
@@ -114,7 +114,7 @@ export function buildRefsByHashFromListEntries(
|
|
|
114
114
|
const refsByHash = new Map<string, readonly string[]>();
|
|
115
115
|
for (const entry of entries) {
|
|
116
116
|
if (entry.refs.length > 0) {
|
|
117
|
-
refsByHash.set(entry.
|
|
117
|
+
refsByHash.set(entry.toContract, entry.refs);
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
return refsByHash;
|
|
@@ -193,7 +193,7 @@ export function renderMigrationListWithStyle(
|
|
|
193
193
|
? result.spaces
|
|
194
194
|
.filter((space) => space.migrations.length > 0)
|
|
195
195
|
.map((space) => ({
|
|
196
|
-
graph: graphForSpace(space.
|
|
196
|
+
graph: graphForSpace(space.space) ?? migrationGraphFromListEntries(space.migrations),
|
|
197
197
|
liveContractHash,
|
|
198
198
|
}))
|
|
199
199
|
: [];
|
|
@@ -212,7 +212,7 @@ export function renderMigrationListWithStyle(
|
|
|
212
212
|
}
|
|
213
213
|
lines.push(
|
|
214
214
|
...renderSpaceTreeBlock(
|
|
215
|
-
space.
|
|
215
|
+
space.space,
|
|
216
216
|
space.migrations,
|
|
217
217
|
multiSpace,
|
|
218
218
|
glyphMode,
|
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readonly operationCount: number;
|
|
7
|
-
readonly createdAt: string;
|
|
8
|
-
readonly refs: readonly string[];
|
|
9
|
-
readonly providedInvariants: readonly string[];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface MigrationSpaceListEntry {
|
|
13
|
-
readonly spaceId: string;
|
|
14
|
-
readonly migrations: readonly MigrationListEntry[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface MigrationListResult {
|
|
18
|
-
readonly ok: true;
|
|
19
|
-
readonly spaces: readonly MigrationSpaceListEntry[];
|
|
20
|
-
readonly summary: string;
|
|
21
|
-
}
|
|
1
|
+
export type {
|
|
2
|
+
MigrationEntry as MigrationListEntry,
|
|
3
|
+
MigrationListResult,
|
|
4
|
+
MigrationSpaceListEntry,
|
|
5
|
+
} from '../../commands/json/schemas';
|
|
@@ -18,10 +18,10 @@ export interface RenderMigrationLogTableOptions {
|
|
|
18
18
|
|
|
19
19
|
export interface SerializedLedgerEntryRecord {
|
|
20
20
|
readonly space: string;
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
23
|
-
readonly
|
|
24
|
-
readonly
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly hash: string;
|
|
23
|
+
readonly fromContract: string | null;
|
|
24
|
+
readonly toContract: string;
|
|
25
25
|
readonly appliedAt: string;
|
|
26
26
|
readonly operationCount: number;
|
|
27
27
|
}
|
|
@@ -191,9 +191,14 @@ export function renderMigrationLogTable(
|
|
|
191
191
|
export function serializeLedgerEntriesForJson(
|
|
192
192
|
entries: readonly LedgerEntryRecord[],
|
|
193
193
|
): SerializedLedgerEntryRecord[] {
|
|
194
|
-
return sortLedgerEntries(entries).map((
|
|
195
|
-
|
|
196
|
-
|
|
194
|
+
return sortLedgerEntries(entries).map((entry) => ({
|
|
195
|
+
space: entry.space,
|
|
196
|
+
name: entry.migrationName,
|
|
197
|
+
hash: entry.migrationHash,
|
|
198
|
+
fromContract: entry.from,
|
|
199
|
+
toContract: entry.to,
|
|
200
|
+
appliedAt: formatLedgerAppliedAt(entry.appliedAt, 'iso'),
|
|
201
|
+
operationCount: entry.operationCount,
|
|
197
202
|
}));
|
|
198
203
|
}
|
|
199
204
|
|
|
@@ -335,11 +335,10 @@ export function formatMigrationApplyCommandOutput(
|
|
|
335
335
|
}
|
|
336
336
|
|
|
337
337
|
interface MigrationShowPresent {
|
|
338
|
-
readonly
|
|
339
|
-
readonly
|
|
340
|
-
readonly
|
|
341
|
-
readonly
|
|
342
|
-
readonly migrationHash: string;
|
|
338
|
+
readonly name: string;
|
|
339
|
+
readonly fromContract: string | null;
|
|
340
|
+
readonly toContract: string;
|
|
341
|
+
readonly hash: string;
|
|
343
342
|
readonly createdAt: string;
|
|
344
343
|
readonly operations: readonly {
|
|
345
344
|
readonly id: string;
|
|
@@ -347,7 +346,6 @@ interface MigrationShowPresent {
|
|
|
347
346
|
readonly operationClass: string;
|
|
348
347
|
}[];
|
|
349
348
|
readonly preview: OperationPreview;
|
|
350
|
-
readonly summary: string;
|
|
351
349
|
}
|
|
352
350
|
|
|
353
351
|
interface MigrationShowResult {
|
|
@@ -360,10 +358,10 @@ function formatSpaceShowBlock(space: MigrationShowPresent, useColor: boolean): r
|
|
|
360
358
|
const formatDimText = (text: string) => formatDim(useColor, text);
|
|
361
359
|
|
|
362
360
|
const lines: string[] = [];
|
|
363
|
-
lines.push(`${formatGreen('✔')} ${space.
|
|
364
|
-
lines.push(`${formatDimText(` from: ${space.
|
|
365
|
-
lines.push(`${formatDimText(` to: ${space.
|
|
366
|
-
lines.push(`${formatDimText(`
|
|
361
|
+
lines.push(`${formatGreen('✔')} ${space.name}`);
|
|
362
|
+
lines.push(`${formatDimText(` from: ${space.fromContract ?? '(baseline)'}`)}`);
|
|
363
|
+
lines.push(`${formatDimText(` to: ${space.toContract}`)}`);
|
|
364
|
+
lines.push(`${formatDimText(` hash: ${space.hash}`)}`);
|
|
367
365
|
lines.push(`${formatDimText(` created: ${space.createdAt}`)}`);
|
|
368
366
|
|
|
369
367
|
lines.push('');
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import type { IntegrityViolation } from '@prisma-next/migration-tools/aggregate';
|
|
2
2
|
import { join, relative } from 'pathe';
|
|
3
|
+
import type { CheckFailure } from '../commands/json/schemas';
|
|
3
4
|
|
|
4
|
-
export
|
|
5
|
-
readonly pnCode: string;
|
|
6
|
-
readonly where: string;
|
|
7
|
-
readonly why: string;
|
|
8
|
-
readonly fix: string;
|
|
9
|
-
}
|
|
5
|
+
export type { CheckFailure } from '../commands/json/schemas';
|
|
10
6
|
|
|
11
7
|
function migrationPathRelative(dirPath: string): string {
|
|
12
8
|
return relative(process.cwd(), dirPath);
|
|
@@ -34,7 +30,8 @@ export function integrityViolationToCheckFailure(
|
|
|
34
30
|
switch (violation.kind) {
|
|
35
31
|
case 'hashMismatch':
|
|
36
32
|
return {
|
|
37
|
-
|
|
33
|
+
space: violation.spaceId,
|
|
34
|
+
code: 'PN-MIG-CHECK-001',
|
|
38
35
|
where: migrationFileRelative(
|
|
39
36
|
join(migrationsDir, violation.spaceId, violation.dirName),
|
|
40
37
|
'migration.json',
|
|
@@ -44,84 +41,96 @@ export function integrityViolationToCheckFailure(
|
|
|
44
41
|
};
|
|
45
42
|
case 'providedInvariantsMismatch':
|
|
46
43
|
return {
|
|
47
|
-
|
|
44
|
+
space: violation.spaceId,
|
|
45
|
+
code: 'PN-MIG-CHECK-002',
|
|
48
46
|
where: packageRelative(violation.spaceId, violation.dirName),
|
|
49
47
|
why: `Migration "${violation.dirName}" providedInvariants in migration.json disagrees with ops.json.`,
|
|
50
48
|
fix: 'Re-emit the migration package so migration.json and ops.json agree.',
|
|
51
49
|
};
|
|
52
50
|
case 'packageUnloadable':
|
|
53
51
|
return {
|
|
54
|
-
|
|
52
|
+
space: violation.spaceId,
|
|
53
|
+
code: 'PN-MIG-CHECK-002',
|
|
55
54
|
where: packageRelative(violation.spaceId, violation.dirName),
|
|
56
55
|
why: `Migration "${violation.dirName}" could not be loaded: ${violation.detail}`,
|
|
57
56
|
fix: 'Re-emit the migration package or restore from version control.',
|
|
58
57
|
};
|
|
59
58
|
case 'sameSourceAndTarget':
|
|
60
59
|
return {
|
|
61
|
-
|
|
60
|
+
space: violation.spaceId,
|
|
61
|
+
code: 'PN-MIG-CHECK-007',
|
|
62
62
|
where: packageRelative(violation.spaceId, violation.dirName),
|
|
63
63
|
why: `Migration "${violation.dirName}" in space "${violation.spaceId}" has source equal to target (${violation.hash}) with no data invariant — a true no-op self-edge.`,
|
|
64
64
|
fix: 'Add a data operation if this self-edge was meant to carry a data invariant, or delete the migration if it is a true no-op.',
|
|
65
65
|
};
|
|
66
66
|
case 'orphanSpaceDir':
|
|
67
67
|
return {
|
|
68
|
-
|
|
68
|
+
space: violation.spaceId,
|
|
69
|
+
code: 'PN-MIG-CHECK-008',
|
|
69
70
|
where: spaceRelative(violation.spaceId),
|
|
70
71
|
why: `Contract-space directory "${violation.spaceId}" exists on disk but no extension declares it.`,
|
|
71
72
|
fix: 'Remove the orphan directory, or declare the extension in `extensionPacks`.',
|
|
72
73
|
};
|
|
73
74
|
case 'declaredButUnmigrated':
|
|
74
75
|
return {
|
|
75
|
-
|
|
76
|
+
space: violation.spaceId,
|
|
77
|
+
code: 'PN-MIG-CHECK-009',
|
|
76
78
|
where: spaceRelative(violation.spaceId),
|
|
77
79
|
why: `Extension "${violation.spaceId}" is declared in \`extensionPacks\` but has no on-disk migrations directory.`,
|
|
78
80
|
fix: 'Re-emit the extension contract-space artefacts with `prisma-next contract emit` and migration planning, or remove the extension from `extensionPacks` if it is unused.',
|
|
79
81
|
};
|
|
80
82
|
case 'headRefMissing':
|
|
81
83
|
return {
|
|
82
|
-
|
|
84
|
+
space: violation.spaceId,
|
|
85
|
+
code: 'PN-MIG-CHECK-010',
|
|
83
86
|
where: refRelative(violation.spaceId, 'head'),
|
|
84
87
|
why: `Head ref \`refs/head.json\` is missing for contract space "${violation.spaceId}".`,
|
|
85
88
|
fix: 'Re-emit the contract-space migrations and head ref artefacts, or restore `refs/head.json` from version control.',
|
|
86
89
|
};
|
|
87
90
|
case 'headRefNotInGraph':
|
|
88
91
|
return {
|
|
89
|
-
|
|
92
|
+
space: violation.spaceId,
|
|
93
|
+
code: 'PN-MIG-CHECK-011',
|
|
90
94
|
where: refRelative(violation.spaceId, 'head'),
|
|
91
95
|
why: `Head ref ${violation.hash} for contract space "${violation.spaceId}" is not present in its migration graph.`,
|
|
92
96
|
fix: 'Re-emit the contract space migrations, or restore the missing migration package.',
|
|
93
97
|
};
|
|
94
98
|
case 'refUnreadable':
|
|
95
99
|
return {
|
|
96
|
-
|
|
100
|
+
space: violation.spaceId,
|
|
101
|
+
code: 'PN-MIG-CHECK-012',
|
|
97
102
|
where: refRelative(violation.spaceId, violation.refName),
|
|
98
103
|
why: `Ref "${violation.refName}" for contract space "${violation.spaceId}" is unreadable: ${violation.detail}`,
|
|
99
104
|
fix: 'Repair or remove the corrupt ref file.',
|
|
100
105
|
};
|
|
101
106
|
case 'targetMismatch':
|
|
102
107
|
return {
|
|
103
|
-
|
|
108
|
+
space: violation.spaceId,
|
|
109
|
+
code: 'PN-MIG-CHECK-013',
|
|
104
110
|
where: spaceRelative(violation.spaceId),
|
|
105
111
|
why: `Contract space "${violation.spaceId}" targets "${violation.actual}" but the project targets "${violation.expected}".`,
|
|
106
112
|
fix: 'Update the extension to target the configured database, or change the project target.',
|
|
107
113
|
};
|
|
108
114
|
case 'disjointness':
|
|
109
115
|
return {
|
|
110
|
-
|
|
116
|
+
space: 'app',
|
|
117
|
+
code: 'PN-MIG-CHECK-014',
|
|
111
118
|
where: migrationPathRelative(migrationsDir),
|
|
112
119
|
why: `Storage element "${violation.element}" is claimed by multiple contract spaces: ${violation.claimedBy.join(', ')}.`,
|
|
113
120
|
fix: 'Update the contracts so each storage element is owned by exactly one contract space.',
|
|
114
121
|
};
|
|
115
122
|
case 'contractUnreadable':
|
|
116
123
|
return {
|
|
117
|
-
|
|
124
|
+
space: violation.spaceId,
|
|
125
|
+
code: 'PN-MIG-CHECK-015',
|
|
118
126
|
where: migrationFileRelative(join(migrationsDir, violation.spaceId), 'contract.json'),
|
|
119
127
|
why: `Contract for space "${violation.spaceId}" is unreadable: ${violation.detail}`,
|
|
120
128
|
fix: 'Re-emit the extension contract artefacts, or fix the descriptor producing the invalid contract.',
|
|
121
129
|
};
|
|
122
130
|
case 'duplicateMigrationHash':
|
|
123
131
|
return {
|
|
124
|
-
|
|
132
|
+
space: violation.spaceId,
|
|
133
|
+
code: 'PN-MIG-CHECK-016',
|
|
125
134
|
where: spaceRelative(violation.spaceId),
|
|
126
135
|
why: `Multiple migrations in space "${violation.spaceId}" share migrationHash "${violation.migrationHash}" (${violation.dirNames.join(', ')}).`,
|
|
127
136
|
fix: 'Re-emit one of the conflicting packages so each migrationHash is unique.',
|