@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.
Files changed (115) hide show
  1. package/dist/cli.mjs +12 -12
  2. package/dist/{client-CJWPvdKj.mjs → client-DC-UlBLy.mjs} +4 -4
  3. package/dist/{client-CJWPvdKj.mjs.map → client-DC-UlBLy.mjs.map} +1 -1
  4. package/dist/{command-helpers-C6lqKJG1.mjs → command-helpers-esJGBD4W.mjs} +5 -5
  5. package/dist/command-helpers-esJGBD4W.mjs.map +1 -0
  6. package/dist/commands/contract-emit.mjs +1 -1
  7. package/dist/commands/contract-infer.mjs +1 -1
  8. package/dist/commands/db-init.mjs +3 -3
  9. package/dist/commands/db-schema.mjs +3 -3
  10. package/dist/commands/db-sign.mjs +4 -4
  11. package/dist/commands/db-update.mjs +4 -4
  12. package/dist/commands/db-verify.mjs +1 -1
  13. package/dist/commands/migrate.d.mts +1 -1
  14. package/dist/commands/migrate.mjs +4 -4
  15. package/dist/commands/migration-check.d.mts +3 -15
  16. package/dist/commands/migration-check.d.mts.map +1 -1
  17. package/dist/commands/migration-check.mjs +3 -2
  18. package/dist/commands/migration-graph.d.mts +9 -18
  19. package/dist/commands/migration-graph.d.mts.map +1 -1
  20. package/dist/commands/migration-graph.mjs +33 -20
  21. package/dist/commands/migration-graph.mjs.map +1 -1
  22. package/dist/commands/migration-list.d.mts +4 -4
  23. package/dist/commands/migration-list.mjs +1 -1
  24. package/dist/commands/migration-log.d.mts +5 -20
  25. package/dist/commands/migration-log.d.mts.map +1 -1
  26. package/dist/commands/migration-log.mjs +1 -1
  27. package/dist/commands/migration-new.mjs +3 -3
  28. package/dist/commands/migration-plan.d.mts +1 -1
  29. package/dist/commands/migration-plan.mjs +1 -1
  30. package/dist/commands/migration-show.d.mts +17 -18
  31. package/dist/commands/migration-show.d.mts.map +1 -1
  32. package/dist/commands/migration-show.mjs +13 -13
  33. package/dist/commands/migration-show.mjs.map +1 -1
  34. package/dist/commands/migration-status.d.mts +24 -26
  35. package/dist/commands/migration-status.d.mts.map +1 -1
  36. package/dist/commands/migration-status.mjs +3 -2
  37. package/dist/commands/ref.d.mts +1 -1
  38. package/dist/commands/ref.mjs +2 -2
  39. package/dist/commands/telemetry/index.mjs +1 -1
  40. package/dist/{contract-at-errors-CVQsgp3V.mjs → contract-at-errors-COZAemUl.mjs} +2 -2
  41. package/dist/{contract-at-errors-CVQsgp3V.mjs.map → contract-at-errors-COZAemUl.mjs.map} +1 -1
  42. package/dist/{contract-emit-DnUkRd-7.mjs → contract-emit-Bv46RAIO.mjs} +3 -3
  43. package/dist/{contract-emit-DnUkRd-7.mjs.map → contract-emit-Bv46RAIO.mjs.map} +1 -1
  44. package/dist/{contract-emit-Iyq5V7OU.mjs → contract-emit-DIWImLqS.mjs} +3 -3
  45. package/dist/{contract-emit-Iyq5V7OU.mjs.map → contract-emit-DIWImLqS.mjs.map} +1 -1
  46. package/dist/{contract-infer-MmQMIms7.mjs → contract-infer-DpGN9SAj.mjs} +3 -3
  47. package/dist/{contract-infer-MmQMIms7.mjs.map → contract-infer-DpGN9SAj.mjs.map} +1 -1
  48. package/dist/{contract-space-aggregate-loader-BSWfMkFY.mjs → contract-space-aggregate-loader-CpNVrBqW.mjs} +2 -2
  49. package/dist/{contract-space-aggregate-loader-BSWfMkFY.mjs.map → contract-space-aggregate-loader-CpNVrBqW.mjs.map} +1 -1
  50. package/dist/{db-verify-B-YOEESk.mjs → db-verify-Cq16Obsw.mjs} +4 -4
  51. package/dist/{db-verify-B-YOEESk.mjs.map → db-verify-Cq16Obsw.mjs.map} +1 -1
  52. package/dist/exports/control-api.d.mts +1 -1
  53. package/dist/exports/control-api.mjs +2 -2
  54. package/dist/exports/index.mjs +1 -1
  55. package/dist/exports/init-output.mjs +1 -1
  56. package/dist/{framework-components-D6VMhw2T.mjs → framework-components-BO9VO43s.mjs} +2 -2
  57. package/dist/{framework-components-D6VMhw2T.mjs.map → framework-components-BO9VO43s.mjs.map} +1 -1
  58. package/dist/{global-flags-DG4uY5tV.d.mts → global-flags-CV5LhrFg.d.mts} +1 -1
  59. package/dist/{global-flags-DG4uY5tV.d.mts.map → global-flags-CV5LhrFg.d.mts.map} +1 -1
  60. package/dist/{init-Ceib8PNc.mjs → init-C0rjiQ9I.mjs} +4 -4
  61. package/dist/{init-Ceib8PNc.mjs.map → init-C0rjiQ9I.mjs.map} +1 -1
  62. package/dist/{inspect-live-schema-CjMZ0RkS.mjs → inspect-live-schema-CRDKTNcf.mjs} +3 -3
  63. package/dist/{inspect-live-schema-CjMZ0RkS.mjs.map → inspect-live-schema-CRDKTNcf.mjs.map} +1 -1
  64. package/dist/{migration-check-DkNcCXZC.mjs → migration-check-CCXNXMXJ.mjs} +49 -30
  65. package/dist/migration-check-CCXNXMXJ.mjs.map +1 -0
  66. package/dist/{migration-command-scaffold-CrRysYxV.mjs → migration-command-scaffold-BDd9abqW.mjs} +3 -3
  67. package/dist/{migration-command-scaffold-CrRysYxV.mjs.map → migration-command-scaffold-BDd9abqW.mjs.map} +1 -1
  68. package/dist/{migration-graph-space-render-ByJ83gxp.mjs → migration-graph-space-render-CeNXh_Wy.mjs} +13 -13
  69. package/dist/migration-graph-space-render-CeNXh_Wy.mjs.map +1 -0
  70. package/dist/{migration-list-ip7fKesI.mjs → migration-list-vJWFuXca.mjs} +17 -17
  71. package/dist/migration-list-vJWFuXca.mjs.map +1 -0
  72. package/dist/{migration-log-BX9vu5c9.mjs → migration-log-6rcHQSI4.mjs} +15 -8
  73. package/dist/migration-log-6rcHQSI4.mjs.map +1 -0
  74. package/dist/{migration-path-target-ByduK0eI.mjs → migration-path-target-UkxkgXnv.mjs} +2 -2
  75. package/dist/{migration-path-target-ByduK0eI.mjs.map → migration-path-target-UkxkgXnv.mjs.map} +1 -1
  76. package/dist/{migration-plan-DLbbc_7z.mjs → migration-plan-CHu_erQ5.mjs} +5 -5
  77. package/dist/{migration-plan-DLbbc_7z.mjs.map → migration-plan-CHu_erQ5.mjs.map} +1 -1
  78. package/dist/{migration-status-BtdaOuQJ.mjs → migration-status-DzdlZQJ3.mjs} +39 -35
  79. package/dist/migration-status-DzdlZQJ3.mjs.map +1 -0
  80. package/dist/{output-CF_hqzI-.mjs → output-BD61elic.mjs} +1 -1
  81. package/dist/{output-CF_hqzI-.mjs.map → output-BD61elic.mjs.map} +1 -1
  82. package/dist/schemas-BL33A3i-.d.mts +193 -0
  83. package/dist/schemas-BL33A3i-.d.mts.map +1 -0
  84. package/dist/schemas-DJY2O09F.mjs +112 -0
  85. package/dist/schemas-DJY2O09F.mjs.map +1 -0
  86. package/dist/{telemetry-CxbY4NKn.mjs → telemetry-CZkgkR_O.mjs} +2 -2
  87. package/dist/{telemetry-CxbY4NKn.mjs.map → telemetry-CZkgkR_O.mjs.map} +1 -1
  88. package/dist/{terminal-ui-5Y6mrg93.d.mts → terminal-ui-BgLiAOYi.d.mts} +1 -1
  89. package/dist/{terminal-ui-5Y6mrg93.d.mts.map → terminal-ui-BgLiAOYi.d.mts.map} +1 -1
  90. package/dist/{types-Cculk5KV.d.mts → types-qV41eEXH.d.mts} +1 -1
  91. package/dist/{types-Cculk5KV.d.mts.map → types-qV41eEXH.d.mts.map} +1 -1
  92. package/dist/{verify-Df-8Kwat.mjs → verify-IilvIk_E.mjs} +2 -2
  93. package/dist/{verify-Df-8Kwat.mjs.map → verify-IilvIk_E.mjs.map} +1 -1
  94. package/package.json +18 -18
  95. package/src/commands/json/schemas.ts +195 -0
  96. package/src/commands/migration-check.ts +33 -24
  97. package/src/commands/migration-graph.ts +34 -36
  98. package/src/commands/migration-list.ts +14 -14
  99. package/src/commands/migration-log.ts +6 -7
  100. package/src/commands/migration-show.ts +21 -28
  101. package/src/commands/migration-status.ts +69 -67
  102. package/src/utils/formatters/migration-list-graph-topology.ts +4 -4
  103. package/src/utils/formatters/migration-list-render.ts +12 -12
  104. package/src/utils/formatters/migration-list-types.ts +5 -21
  105. package/src/utils/formatters/migration-log-table.ts +12 -7
  106. package/src/utils/formatters/migrations.ts +8 -10
  107. package/src/utils/integrity-violation-to-check-failure.ts +28 -19
  108. package/dist/command-helpers-C6lqKJG1.mjs.map +0 -1
  109. package/dist/migration-check-DkNcCXZC.mjs.map +0 -1
  110. package/dist/migration-graph-space-render-ByJ83gxp.mjs.map +0 -1
  111. package/dist/migration-list-ip7fKesI.mjs.map +0 -1
  112. package/dist/migration-list-types-DS63IdFd.d.mts +0 -23
  113. package/dist/migration-list-types-DS63IdFd.d.mts.map +0 -1
  114. package/dist/migration-log-BX9vu5c9.mjs.map +0 -1
  115. 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
- interface MigrationStatusOptions extends CommonCommandOptions {
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 MigrationStatusMigrationEntry extends MigrationListEntry {
83
- readonly status: 'applied' | 'pending' | null;
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
- export interface MigrationStatusResult {
103
+ interface MigrationStatusCommandResult {
94
104
  readonly ok: true;
95
- readonly spaces: readonly MigrationStatusSpaceResult[];
105
+ readonly spaces: readonly MigrationStatusSpace[];
96
106
  readonly summary: string;
97
- readonly missingInvariantsLine?: string;
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 MigrationStatusMigrationEntry[] {
123
+ ): readonly MigrationStatusEntry[] {
123
124
  return listMigrations.map((migration) => ({
124
125
  ...migration,
125
- status: statusForMigrationHash(migration.migrationHash, annotations),
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 MigrationStatusMigrationEntry[]): number {
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(result: MigrationStatusResult, colorize: boolean): string {
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
- if (result.missingInvariantsLine !== undefined) {
219
- lines.push(c(dim, result.missingInvariantsLine));
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(result: MigrationStatusResult, colorize: boolean): string {
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.spaceId}:`);
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<MigrationStatusResult, CliStructuredError>> {
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: StatusDiagnostic[] = [];
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.spaceId),
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: MigrationStatusSpaceResult[] = [];
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.spaceId)!.graph(),
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.spaceId);
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.spaceId === aggregate.app.spaceId) {
499
+ if (spaceEntry.space === aggregate.app.spaceId) {
490
500
  headlineTargetHash = targetHash;
491
501
  }
492
502
 
493
- const markerRecord = markersBySpace.get(spaceEntry.spaceId);
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.spaceId) ?? [];
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
- spaceId: spaceEntry.spaceId,
552
- markerHash: markerHash ?? null,
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
- spaceId: spaceEntry.spaceId,
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
- missingInvariantsLine = `missing invariant(s): ${missing.join(', ')}`;
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
- ui.output(
684
- JSON.stringify(
685
- {
686
- ok: true,
687
- spaces: statusResult.spaces,
688
- summary: statusResult.summary,
689
- ...(statusResult.diagnostics.length > 0
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.migrationHash,
323
- from: canonicalFrom(entry.from),
324
- to: entry.to,
325
- dirName: entry.dirName,
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.from);
75
+ const from = canonicalFrom(entry.fromContract);
76
76
  const edge: MigrationEdge = {
77
77
  from,
78
- to: entry.to,
79
- migrationHash: entry.migrationHash,
80
- dirName: entry.dirName,
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.to);
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.to);
89
+ const reverse = reverseChain.get(entry.toContract);
90
90
  if (reverse) reverse.push(edge);
91
- else reverseChain.set(entry.to, [edge]);
92
- migrationByHash.set(entry.migrationHash, edge);
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.migrationHash, {
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.to, entry.refs);
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.spaceId) ?? migrationGraphFromListEntries(space.migrations),
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.spaceId,
215
+ space.space,
216
216
  space.migrations,
217
217
  multiSpace,
218
218
  glyphMode,
@@ -1,21 +1,5 @@
1
- export interface MigrationListEntry {
2
- readonly dirName: string;
3
- readonly from: string | null;
4
- readonly to: string;
5
- readonly migrationHash: string;
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 migrationName: string;
22
- readonly migrationHash: string;
23
- readonly from: string | null;
24
- readonly to: string;
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(({ appliedAt, ...rest }) => ({
195
- ...rest,
196
- appliedAt: formatLedgerAppliedAt(appliedAt, 'iso'),
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 dirName: string;
339
- readonly dirPath: string;
340
- readonly from: string | null;
341
- readonly to: string;
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.dirName}`);
364
- lines.push(`${formatDimText(` from: ${space.from ?? '(baseline)'}`)}`);
365
- lines.push(`${formatDimText(` to: ${space.to}`)}`);
366
- lines.push(`${formatDimText(` migrationHash: ${space.migrationHash}`)}`);
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 interface CheckFailure {
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
- pnCode: 'PN-MIG-CHECK-001',
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
- pnCode: 'PN-MIG-CHECK-002',
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
- pnCode: 'PN-MIG-CHECK-002',
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
- pnCode: 'PN-MIG-CHECK-007',
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
- pnCode: 'PN-MIG-CHECK-008',
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
- pnCode: 'PN-MIG-CHECK-009',
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
- pnCode: 'PN-MIG-CHECK-010',
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
- pnCode: 'PN-MIG-CHECK-011',
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
- pnCode: 'PN-MIG-CHECK-012',
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
- pnCode: 'PN-MIG-CHECK-013',
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
- pnCode: 'PN-MIG-CHECK-014',
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
- pnCode: 'PN-MIG-CHECK-015',
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
- pnCode: 'PN-MIG-CHECK-016',
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.',