@prisma-next/cli 0.4.0-dev.9 → 0.4.1

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 (119) hide show
  1. package/README.md +31 -18
  2. package/dist/cli-errors-CznZA5-d.mjs +5 -0
  3. package/dist/cli.mjs +8 -19
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/{client-CJxHfhze.mjs → client-DGKrciLM.mjs} +9 -8
  6. package/dist/{client-CJxHfhze.mjs.map → client-DGKrciLM.mjs.map} +1 -1
  7. package/dist/commands/contract-emit.d.mts.map +1 -1
  8. package/dist/commands/contract-emit.mjs +2 -7
  9. package/dist/commands/contract-infer.mjs +2 -8
  10. package/dist/commands/db-init.mjs +7 -8
  11. package/dist/commands/db-init.mjs.map +1 -1
  12. package/dist/commands/db-schema.mjs +5 -8
  13. package/dist/commands/db-schema.mjs.map +1 -1
  14. package/dist/commands/db-sign.mjs +7 -8
  15. package/dist/commands/db-sign.mjs.map +1 -1
  16. package/dist/commands/db-update.mjs +7 -8
  17. package/dist/commands/db-update.mjs.map +1 -1
  18. package/dist/commands/db-verify.mjs +8 -9
  19. package/dist/commands/db-verify.mjs.map +1 -1
  20. package/dist/commands/migration-apply.d.mts +1 -1
  21. package/dist/commands/migration-apply.d.mts.map +1 -1
  22. package/dist/commands/migration-apply.mjs +34 -26
  23. package/dist/commands/migration-apply.mjs.map +1 -1
  24. package/dist/commands/migration-new.d.mts.map +1 -1
  25. package/dist/commands/migration-new.mjs +48 -23
  26. package/dist/commands/migration-new.mjs.map +1 -1
  27. package/dist/commands/migration-plan.d.mts +6 -1
  28. package/dist/commands/migration-plan.d.mts.map +1 -1
  29. package/dist/commands/migration-plan.mjs +94 -71
  30. package/dist/commands/migration-plan.mjs.map +1 -1
  31. package/dist/commands/migration-ref.d.mts +1 -1
  32. package/dist/commands/migration-ref.mjs +5 -5
  33. package/dist/commands/migration-show.d.mts +2 -2
  34. package/dist/commands/migration-show.d.mts.map +1 -1
  35. package/dist/commands/migration-show.mjs +11 -16
  36. package/dist/commands/migration-show.mjs.map +1 -1
  37. package/dist/commands/migration-status.d.mts +4 -5
  38. package/dist/commands/migration-status.d.mts.map +1 -1
  39. package/dist/commands/migration-status.mjs +2 -7
  40. package/dist/config-loader-_xQZsw0i.mjs +90 -0
  41. package/dist/config-loader-_xQZsw0i.mjs.map +1 -0
  42. package/dist/config-loader.d.mts.map +1 -1
  43. package/dist/config-loader.mjs +1 -1
  44. package/dist/contract-emit-304WZtZJ.mjs +4 -0
  45. package/dist/{contract-emit-CKig_Lra.mjs → contract-emit-DgeWdonT.mjs} +25 -21
  46. package/dist/contract-emit-DgeWdonT.mjs.map +1 -0
  47. package/dist/{contract-emit-gpJNLGs7.mjs → contract-emit-mU1_B_m9.mjs} +18 -14
  48. package/dist/contract-emit-mU1_B_m9.mjs.map +1 -0
  49. package/dist/{contract-enrichment-CGW6mm-E.mjs → contract-enrichment-BV4KpbNW.mjs} +1 -1
  50. package/dist/{contract-enrichment-CGW6mm-E.mjs.map → contract-enrichment-BV4KpbNW.mjs.map} +1 -1
  51. package/dist/{contract-infer-BDJgg7Xb.mjs → contract-infer-CUbiWGX0.mjs} +4 -4
  52. package/dist/{contract-infer-BDJgg7Xb.mjs.map → contract-infer-CUbiWGX0.mjs.map} +1 -1
  53. package/dist/exports/control-api.d.mts +2 -2
  54. package/dist/exports/control-api.d.mts.map +1 -1
  55. package/dist/exports/control-api.mjs +4 -6
  56. package/dist/exports/index.mjs +2 -7
  57. package/dist/exports/index.mjs.map +1 -1
  58. package/dist/{extract-operation-statements-DZUJNmL3.mjs → extract-operation-statements-DWWFz1PK.mjs} +2 -2
  59. package/dist/{extract-operation-statements-DZUJNmL3.mjs.map → extract-operation-statements-DWWFz1PK.mjs.map} +1 -1
  60. package/dist/{extract-sql-ddl-DDMX-9mz.mjs → extract-sql-ddl-7zn_AFS8.mjs} +1 -1
  61. package/dist/{extract-sql-ddl-DDMX-9mz.mjs.map → extract-sql-ddl-7zn_AFS8.mjs.map} +1 -1
  62. package/dist/{framework-components-Bsr1GaIj.mjs → framework-components-B__p--vT.mjs} +2 -2
  63. package/dist/{framework-components-Bsr1GaIj.mjs.map → framework-components-B__p--vT.mjs.map} +1 -1
  64. package/dist/{init-DZWvhEP0.mjs → init-DRquYpPa.mjs} +3 -3
  65. package/dist/{init-DZWvhEP0.mjs.map → init-DRquYpPa.mjs.map} +1 -1
  66. package/dist/{inspect-live-schema-ChqrALmw.mjs → inspect-live-schema-wIYBTdL3.mjs} +6 -6
  67. package/dist/{inspect-live-schema-ChqrALmw.mjs.map → inspect-live-schema-wIYBTdL3.mjs.map} +1 -1
  68. package/dist/{migration-command-scaffold-B0oH_hyB.mjs → migration-command-scaffold-BC73xQSo.mjs} +7 -7
  69. package/dist/{migration-command-scaffold-B0oH_hyB.mjs.map → migration-command-scaffold-BC73xQSo.mjs.map} +1 -1
  70. package/dist/{migration-status-CPamfEPj.mjs → migration-status-CXBbScH5.mjs} +19 -35
  71. package/dist/migration-status-CXBbScH5.mjs.map +1 -0
  72. package/dist/{migrations-BIsjFjSV.mjs → migrations-DYRAjiVh.mjs} +4 -15
  73. package/dist/migrations-DYRAjiVh.mjs.map +1 -0
  74. package/dist/{progress-adapter-B-YvmcDu.mjs → progress-adapter-Bwouy73-.mjs} +1 -1
  75. package/dist/{progress-adapter-B-YvmcDu.mjs.map → progress-adapter-Bwouy73-.mjs.map} +1 -1
  76. package/dist/{result-handler-AFK4hxyX.mjs → result-handler-CGohaH1o.mjs} +22 -11
  77. package/dist/result-handler-CGohaH1o.mjs.map +1 -0
  78. package/dist/{terminal-ui-C5k88MmW.mjs → terminal-ui-BuPXVRFY.mjs} +1 -1
  79. package/dist/{terminal-ui-C5k88MmW.mjs.map → terminal-ui-BuPXVRFY.mjs.map} +1 -1
  80. package/dist/{validate-contract-deps-DBH6iTAD.mjs → validate-contract-deps-DZqv9m7H.mjs} +1 -1
  81. package/dist/{validate-contract-deps-DBH6iTAD.mjs.map → validate-contract-deps-DZqv9m7H.mjs.map} +1 -1
  82. package/dist/{verify-C56CuQc7.mjs → verify-Cm2UFuZA.mjs} +2 -2
  83. package/dist/{verify-C56CuQc7.mjs.map → verify-Cm2UFuZA.mjs.map} +1 -1
  84. package/package.json +16 -20
  85. package/src/cli.ts +1 -5
  86. package/src/commands/contract-emit.ts +9 -10
  87. package/src/commands/migration-apply.ts +34 -23
  88. package/src/commands/migration-new.ts +39 -17
  89. package/src/commands/migration-plan.ts +119 -104
  90. package/src/commands/migration-show.ts +6 -16
  91. package/src/commands/migration-status.ts +14 -34
  92. package/src/config-loader.ts +35 -29
  93. package/src/config-path-validation.ts +75 -0
  94. package/src/control-api/client.ts +2 -1
  95. package/src/control-api/operations/contract-emit.ts +24 -23
  96. package/src/control-api/types.ts +1 -1
  97. package/src/utils/command-helpers.ts +15 -19
  98. package/src/utils/formatters/graph-migration-mapper.ts +5 -14
  99. package/src/utils/formatters/help.ts +0 -1
  100. package/src/utils/formatters/migrations.ts +2 -29
  101. package/dist/cli-errors-BUuJr6py.mjs +0 -5
  102. package/dist/commands/migration-emit.d.mts +0 -38
  103. package/dist/commands/migration-emit.d.mts.map +0 -1
  104. package/dist/commands/migration-emit.mjs +0 -81
  105. package/dist/commands/migration-emit.mjs.map +0 -1
  106. package/dist/config-loader-C4VXKl8f.mjs +0 -43
  107. package/dist/config-loader-C4VXKl8f.mjs.map +0 -1
  108. package/dist/contract-emit-CKig_Lra.mjs.map +0 -1
  109. package/dist/contract-emit-CU-SYNe4.mjs +0 -6
  110. package/dist/contract-emit-gpJNLGs7.mjs.map +0 -1
  111. package/dist/migration-emit-Du4DBMqz.mjs +0 -125
  112. package/dist/migration-emit-Du4DBMqz.mjs.map +0 -1
  113. package/dist/migration-status-CPamfEPj.mjs.map +0 -1
  114. package/dist/migrations-BIsjFjSV.mjs.map +0 -1
  115. package/dist/result-handler-AFK4hxyX.mjs.map +0 -1
  116. package/src/commands/migration-emit.ts +0 -134
  117. package/src/lib/migration-emit.ts +0 -125
  118. package/src/lib/migration-strategy.ts +0 -49
  119. /package/dist/{cli-errors-Dic2eADK.d.mts → cli-errors-z37sV3eR.d.mts} +0 -0
@@ -1,18 +1,19 @@
1
- import { t as loadConfig } from "../config-loader-C4VXKl8f.mjs";
2
- import { a as errorContractValidationFailed, g as errorTargetMigrationNotSupported, h as errorRuntime, l as errorFileNotFound, p as errorMigrationPlanningFailed, t as CliStructuredError, v as errorUnexpected } from "../cli-errors-BUuJr6py.mjs";
3
- import { t as assertFrameworkComponentsCompatible } from "../framework-components-Bsr1GaIj.mjs";
4
- import { t as extractSqlDdl } from "../extract-sql-ddl-DDMX-9mz.mjs";
5
- import { _ as formatStyledHeader, c as resolveMigrationPaths, d as setCommandExamples, i as loadAllBundles, m as parseGlobalFlags, n as addGlobalOptions, r as getTargetMigrations, s as resolveContractPath, t as handleResult, u as setCommandDescriptions } from "../result-handler-AFK4hxyX.mjs";
6
- import { t as TerminalUI } from "../terminal-ui-C5k88MmW.mjs";
7
- import { n as migrationStrategy, t as emitMigration } from "../migration-emit-Du4DBMqz.mjs";
1
+ import { t as loadConfig } from "../config-loader-_xQZsw0i.mjs";
2
+ import { _ as errorUnexpected, a as errorContractValidationFailed, f as errorMigrationPlanningFailed, h as errorTargetMigrationNotSupported, l as errorFileNotFound, m as errorRuntime, t as CliStructuredError } from "../cli-errors-CznZA5-d.mjs";
3
+ import { t as assertFrameworkComponentsCompatible } from "../framework-components-B__p--vT.mjs";
4
+ import { t as extractSqlDdl } from "../extract-sql-ddl-7zn_AFS8.mjs";
5
+ import { _ as formatStyledHeader, c as resolveMigrationPaths, d as setCommandExamples, i as loadAllBundles, m as parseGlobalFlags, n as addGlobalOptions, r as getTargetMigrations, s as resolveContractPath, t as handleResult, u as setCommandDescriptions } from "../result-handler-CGohaH1o.mjs";
6
+ import { t as TerminalUI } from "../terminal-ui-BuPXVRFY.mjs";
8
7
  import { Command } from "commander";
8
+ import { getEmittedArtifactPaths } from "@prisma-next/emitter";
9
9
  import { notOk, ok } from "@prisma-next/utils/result";
10
10
  import { join, relative } from "pathe";
11
11
  import { createControlStack } from "@prisma-next/framework-components/control";
12
12
  import { EMPTY_CONTRACT_HASH } from "@prisma-next/migration-tools/constants";
13
13
  import { readFile } from "node:fs/promises";
14
14
  import { findLatestMigration } from "@prisma-next/migration-tools/dag";
15
- import { copyContractToMigrationDir, formatMigrationDirName, writeMigrationPackage } from "@prisma-next/migration-tools/io";
15
+ import { copyFilesWithRename, formatMigrationDirName, writeMigrationPackage } from "@prisma-next/migration-tools/io";
16
+ import { computeMigrationId } from "@prisma-next/migration-tools/attestation";
16
17
  import { MigrationToolsError } from "@prisma-next/migration-tools/types";
17
18
  import { writeMigrationTs } from "@prisma-next/migration-tools/migration-ts";
18
19
 
@@ -87,13 +88,9 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
87
88
  const toStorageHash = rawStorageHash;
88
89
  let fromContract = null;
89
90
  let fromHash = EMPTY_CONTRACT_HASH;
91
+ let fromContractSourceDir = null;
90
92
  try {
91
- const { attested: bundles, drafts, graph } = await loadAllBundles(migrationsDir);
92
- const existingDraft = drafts.find((d) => d.manifest.to === toStorageHash);
93
- if (existingDraft) return notOk(errorRuntime("A draft migration to this contract already exists", {
94
- why: `Draft migration at "${existingDraft.dirName}" already targets ${toStorageHash}`,
95
- fix: `Run 'prisma-next migration emit --dir ${migrationsRelative}/${existingDraft.dirName}' to attest it, or delete it and re-plan.`
96
- }));
93
+ const { bundles, graph } = await loadAllBundles(migrationsDir);
97
94
  if (options.from) {
98
95
  const resolved = resolveBundleByPrefix(bundles, options.from);
99
96
  if (!resolved.ok) {
@@ -108,12 +105,16 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
108
105
  }
109
106
  fromHash = resolved.value.manifest.to;
110
107
  fromContract = resolved.value.manifest.toContract;
108
+ fromContractSourceDir = resolved.value.dirPath;
111
109
  } else {
112
110
  const latestMigration = findLatestMigration(graph);
113
111
  if (latestMigration) {
114
112
  fromHash = latestMigration.to;
115
113
  const leafPkg = bundles.find((p) => p.manifest.migrationId === latestMigration.migrationId);
116
- if (leafPkg) fromContract = leafPkg.manifest.toContract;
114
+ if (leafPkg) {
115
+ fromContract = leafPkg.manifest.toContract;
116
+ fromContractSourceDir = leafPkg.dirPath;
117
+ }
117
118
  }
118
119
  }
119
120
  } catch (error) {
@@ -136,93 +137,103 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
136
137
  config.adapter,
137
138
  ...config.extensionPacks ?? []
138
139
  ]);
139
- const strategy = migrationStrategy(migrations, config.target.targetId);
140
140
  const timestamp = /* @__PURE__ */ new Date();
141
141
  const packageDir = join(migrationsDir, formatMigrationDirName(timestamp, options.name ?? "migration"));
142
- const manifest = {
142
+ const baseManifest = {
143
143
  from: fromHash,
144
144
  to: toStorageHash,
145
- migrationId: null,
146
145
  kind: "regular",
147
146
  fromContract,
148
147
  toContract: toContractJson,
149
148
  hints: {
150
149
  used: [],
151
150
  applied: [],
152
- plannerVersion: "2.0.0",
153
- planningStrategy: strategy === "descriptor" ? "descriptors" : "class-based"
151
+ plannerVersion: "2.0.0"
154
152
  },
155
153
  labels: [],
156
154
  createdAt: timestamp.toISOString()
157
155
  };
158
- const scaffoldContext = {
159
- packageDir,
160
- contractJsonPath: contractPathAbsolute,
161
- fromHash,
162
- toHash: toStorageHash
163
- };
164
156
  try {
165
- let migrationTsContent;
166
- if (strategy === "descriptor") {
167
- if (!migrations.planWithDescriptors || !migrations.renderDescriptorTypeScript) throw errorTargetMigrationNotSupported({ why: `Target "${config.target.targetId}" advertises descriptor flow but is missing required hooks` });
168
- const descriptorResult = migrations.planWithDescriptors({
169
- fromContract,
170
- toContract: toContractJson,
171
- frameworkComponents
172
- });
173
- if (!descriptorResult.ok) return notOk(errorMigrationPlanningFailed({ conflicts: descriptorResult.conflicts }));
174
- if (descriptorResult.descriptors.length === 0) return notOk(errorMigrationPlanningFailed({ conflicts: [{
175
- kind: "unsupportedChange",
176
- summary: "Contract changed but planner produced no operations. This indicates unsupported or ignored changes."
177
- }] }));
178
- migrationTsContent = migrations.renderDescriptorTypeScript(descriptorResult.descriptors, scaffoldContext);
179
- } else {
180
- const stack = createControlStack(config);
181
- const familyInstance = config.family.create(stack);
182
- const planner = migrations.createPlanner(familyInstance);
183
- const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);
184
- const plannerResult = planner.plan({
185
- contract: toContractJson,
186
- schema: fromSchema,
187
- policy: { allowedOperationClasses: [
188
- "additive",
189
- "widening",
190
- "destructive",
191
- "data"
192
- ] },
193
- fromHash,
194
- frameworkComponents
195
- });
196
- if (plannerResult.kind === "failure") return notOk(errorMigrationPlanningFailed({ conflicts: plannerResult.conflicts }));
197
- if (plannerResult.plan.operations.length === 0) return notOk(errorMigrationPlanningFailed({ conflicts: [{
157
+ const stack = createControlStack(config);
158
+ const familyInstance = config.family.create(stack);
159
+ const planner = migrations.createPlanner(familyInstance);
160
+ const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);
161
+ const plannerResult = planner.plan({
162
+ contract: toContractJson,
163
+ schema: fromSchema,
164
+ policy: { allowedOperationClasses: [
165
+ "additive",
166
+ "widening",
167
+ "destructive",
168
+ "data"
169
+ ] },
170
+ fromHash,
171
+ fromContract,
172
+ frameworkComponents
173
+ });
174
+ if (plannerResult.kind === "failure") return notOk(errorMigrationPlanningFailed({ conflicts: plannerResult.conflicts }));
175
+ let plannedOps = [];
176
+ let hasPlaceholders = false;
177
+ try {
178
+ plannedOps = plannerResult.plan.operations;
179
+ if (plannedOps.length === 0) return notOk(errorMigrationPlanningFailed({ conflicts: [{
198
180
  kind: "unsupportedChange",
199
181
  summary: "Contract changed but planner produced no operations. This indicates unsupported or ignored changes."
200
182
  }] }));
201
- migrationTsContent = plannerResult.plan.renderTypeScript();
183
+ } catch (e) {
184
+ if (CliStructuredError.is(e) && e.domain === "MIG" && e.code === "2001") hasPlaceholders = true;
185
+ else throw e;
186
+ }
187
+ const migrationTsContent = plannerResult.plan.renderTypeScript();
188
+ const opsForWrite = hasPlaceholders ? [] : plannedOps;
189
+ await writeMigrationPackage(packageDir, {
190
+ ...baseManifest,
191
+ migrationId: computeMigrationId(baseManifest, opsForWrite)
192
+ }, opsForWrite);
193
+ const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);
194
+ await copyFilesWithRename(packageDir, [{
195
+ sourcePath: destinationArtifacts.jsonPath,
196
+ destName: "end-contract.json"
197
+ }, {
198
+ sourcePath: destinationArtifacts.dtsPath,
199
+ destName: "end-contract.d.ts"
200
+ }]);
201
+ if (fromContractSourceDir !== null) {
202
+ const sourceArtifacts = getEmittedArtifactPaths(join(fromContractSourceDir, "end-contract.json"));
203
+ await copyFilesWithRename(packageDir, [{
204
+ sourcePath: sourceArtifacts.jsonPath,
205
+ destName: "start-contract.json"
206
+ }, {
207
+ sourcePath: sourceArtifacts.dtsPath,
208
+ destName: "start-contract.d.ts"
209
+ }]);
202
210
  }
203
- await writeMigrationPackage(packageDir, manifest, []);
204
- await copyContractToMigrationDir(packageDir, contractPathAbsolute);
205
211
  await writeMigrationTs(packageDir, migrationTsContent);
206
- const { operations, migrationId } = await emitMigration(packageDir, {
207
- targetId: config.target.targetId,
208
- migrations,
209
- frameworkComponents
212
+ if (hasPlaceholders) return ok({
213
+ ok: true,
214
+ noOp: false,
215
+ from: fromHash,
216
+ to: toStorageHash,
217
+ dir: relative(process.cwd(), packageDir),
218
+ operations: [],
219
+ pendingPlaceholders: true,
220
+ summary: "Planned migration with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit",
221
+ timings: { total: Date.now() - startTime }
210
222
  });
211
- const sql = extractSqlDdl(operations);
223
+ const sql = extractSqlDdl(plannedOps);
212
224
  return ok({
213
225
  ok: true,
214
226
  noOp: false,
215
227
  from: fromHash,
216
228
  to: toStorageHash,
217
- migrationId,
218
229
  dir: relative(process.cwd(), packageDir),
219
- operations: operations.map((op) => ({
230
+ operations: plannedOps.map((op) => ({
220
231
  id: op.id,
221
232
  label: op.label,
222
233
  operationClass: op.operationClass
223
234
  })),
224
235
  sql,
225
- summary: `Planned ${operations.length} operation(s)`,
236
+ summary: `Planned ${plannedOps.length} operation(s)`,
226
237
  timings: { total: Date.now() - startTime }
227
238
  });
228
239
  } catch (error) {
@@ -260,6 +271,17 @@ function formatMigrationPlanOutput(result, flags) {
260
271
  lines.push(dim_(` to: ${result.to}`));
261
272
  return lines.join("\n");
262
273
  }
274
+ if (result.pendingPlaceholders) {
275
+ lines.push(`${yellow_("⚠")} ${result.summary}`);
276
+ lines.push("");
277
+ lines.push(dim_(`from: ${result.from}`));
278
+ lines.push(dim_(`to: ${result.to}`));
279
+ if (result.dir) lines.push(dim_(`dir: ${result.dir}`));
280
+ lines.push("");
281
+ lines.push("Open migration.ts and replace each `placeholder(...)` call with your actual query.");
282
+ lines.push(`Then run: ${green_(`node ${result.dir ?? "<dir>"}/migration.ts`)}`);
283
+ return lines.join("\n");
284
+ }
263
285
  lines.push(`${green_("✔")} ${result.summary}`);
264
286
  lines.push("");
265
287
  if (result.operations.length > 0) {
@@ -278,8 +300,9 @@ function formatMigrationPlanOutput(result, flags) {
278
300
  }
279
301
  lines.push(dim_(`from: ${result.from}`));
280
302
  lines.push(dim_(`to: ${result.to}`));
281
- if (result.migrationId) lines.push(dim_(`migrationId: ${result.migrationId}`));
282
303
  if (result.dir) lines.push(dim_(`dir: ${result.dir}`));
304
+ lines.push("");
305
+ lines.push(`Next: ${green_(`node ${result.dir ?? "<dir>"}/migration.ts`)} to emit ops.json and attest migrationId before running ${green_("prisma-next migration apply")}.`);
283
306
  if (result.sql && result.sql.length > 0) {
284
307
  lines.push("");
285
308
  lines.push(dim_("DDL preview"));
@@ -1 +1 @@
1
- {"version":3,"file":"migration-plan.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","toContractJson: Contract","fromContract: Contract | null","fromHash: string","manifest: MigrationManifest","migrationTsContent: string","lines: string[]"],"sources":["../../src/commands/migration-plan.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';\nimport { findLatestMigration } from '@prisma-next/migration-tools/dag';\nimport {\n copyContractToMigrationDir,\n formatMigrationDirName,\n writeMigrationPackage,\n} from '@prisma-next/migration-tools/io';\nimport { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';\nimport { type MigrationManifest, MigrationToolsError } from '@prisma-next/migration-tools/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join, relative } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { extractSqlDdl } from '../control-api/operations/extract-sql-ddl';\nimport { emitMigration } from '../lib/migration-emit';\nimport { migrationStrategy } from '../lib/migration-strategy';\nimport {\n type CliErrorConflict,\n CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorMigrationPlanningFailed,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n getTargetMigrations,\n loadAllBundles,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationPlanOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly name?: string;\n readonly from?: string;\n}\n\nexport interface MigrationPlanResult {\n readonly ok: boolean;\n readonly noOp: boolean;\n readonly from: string;\n readonly to: string;\n readonly migrationId?: string;\n readonly dir?: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly sql?: readonly string[];\n readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\n}\n\nfunction mapMigrationToolsError(error: unknown): CliStructuredError {\n if (CliStructuredError.is(error)) {\n return error;\n }\n if (MigrationToolsError.is(error)) {\n return errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n });\n }\n return errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migration plan: ${error instanceof Error ? error.message : String(error)}`,\n });\n}\n\nasync function executeMigrationPlanCommand(\n options: MigrationPlanOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrationPlanResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, migrationsRelative } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (options.from) {\n details.push({ label: 'from', value: options.from });\n }\n if (options.name) {\n details.push({ label: 'name', value: options.name });\n }\n const header = formatStyledHeader({\n command: 'migration plan',\n description: 'Plan a migration from contract changes',\n url: 'https://pris.ly/migration-plan',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n // Load contract file (the \"to\" contract)\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let toContractJson: Contract;\n try {\n toContractJson = JSON.parse(contractJsonContent) as Contract;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const rawStorageHash = toContractJson.storage?.storageHash;\n if (typeof rawStorageHash !== 'string') {\n return notOk(\n errorContractValidationFailed('Contract is missing storageHash', {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n const toStorageHash = rawStorageHash;\n\n // Read existing migrations and determine \"from\" contract\n let fromContract: Contract | null = null;\n let fromHash: string = EMPTY_CONTRACT_HASH;\n\n try {\n const { attested: bundles, drafts, graph } = await loadAllBundles(migrationsDir);\n\n // Check if a draft migration already targets this contract\n const existingDraft = drafts.find((d) => d.manifest.to === toStorageHash);\n if (existingDraft) {\n return notOk(\n errorRuntime('A draft migration to this contract already exists', {\n why: `Draft migration at \"${existingDraft.dirName}\" already targets ${toStorageHash}`,\n fix: `Run 'prisma-next migration emit --dir ${migrationsRelative}/${existingDraft.dirName}' to attest it, or delete it and re-plan.`,\n }),\n );\n }\n\n if (options.from) {\n const resolved = resolveBundleByPrefix(bundles, options.from);\n if (!resolved.ok) {\n const f = resolved.failure;\n return notOk(\n f.reason === 'ambiguous'\n ? errorRuntime('Multiple matching migrations found', {\n why: `Prefix \"${options.from}\" matches ${f.count} migrations in ${migrationsRelative}`,\n fix: 'Provide a longer prefix to disambiguate, or omit --from to use the latest migration target.',\n })\n : errorRuntime('Starting contract not found', {\n why: `No migration with to hash matching \"${options.from}\" exists in ${migrationsRelative}`,\n fix: 'Check that the --from hash matches a known migration target hash, or omit --from to use the latest migration target.',\n }),\n );\n }\n fromHash = resolved.value.manifest.to;\n fromContract = resolved.value.manifest.toContract;\n } else {\n const latestMigration = findLatestMigration(graph);\n if (latestMigration) {\n fromHash = latestMigration.to;\n const leafPkg = bundles.find((p) => p.manifest.migrationId === latestMigration.migrationId);\n if (leafPkg) {\n fromContract = leafPkg.manifest.toContract;\n }\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n // Check for no-op (same hash means no changes)\n if (fromHash === toStorageHash) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: true,\n from: fromHash,\n to: toStorageHash,\n operations: [],\n summary: 'No changes detected between contracts',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n // Check target supports migrations\n const migrations = getTargetMigrations(config.target);\n if (!migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n const frameworkComponents = assertFrameworkComponentsCompatible(\n config.family.familyId,\n config.target.targetId,\n [config.target, config.adapter, ...(config.extensionPacks ?? [])],\n );\n\n const strategy = migrationStrategy(migrations, config.target.targetId);\n\n // Build manifest and write migration package\n const timestamp = new Date();\n const slug = options.name ?? 'migration';\n const dirName = formatMigrationDirName(timestamp, slug);\n const packageDir = join(migrationsDir, dirName);\n\n const manifest: MigrationManifest = {\n from: fromHash,\n to: toStorageHash,\n migrationId: null,\n kind: 'regular',\n fromContract,\n toContract: toContractJson,\n hints: {\n used: [],\n applied: [],\n plannerVersion: '2.0.0',\n planningStrategy: strategy === 'descriptor' ? 'descriptors' : 'class-based',\n },\n labels: [],\n createdAt: timestamp.toISOString(),\n };\n\n const scaffoldContext = {\n packageDir,\n contractJsonPath: contractPathAbsolute,\n fromHash,\n toHash: toStorageHash,\n };\n\n try {\n let migrationTsContent: string;\n\n if (strategy === 'descriptor') {\n if (!migrations.planWithDescriptors || !migrations.renderDescriptorTypeScript) {\n throw errorTargetMigrationNotSupported({\n why: `Target \"${config.target.targetId}\" advertises descriptor flow but is missing required hooks`,\n });\n }\n const descriptorResult = migrations.planWithDescriptors({\n fromContract,\n toContract: toContractJson,\n frameworkComponents,\n });\n if (!descriptorResult.ok) {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: descriptorResult.conflicts as readonly CliErrorConflict[],\n }),\n );\n }\n if (descriptorResult.descriptors.length === 0) {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: [\n {\n kind: 'unsupportedChange',\n summary:\n 'Contract changed but planner produced no operations. ' +\n 'This indicates unsupported or ignored changes.',\n },\n ],\n }),\n );\n }\n migrationTsContent = migrations.renderDescriptorTypeScript(\n descriptorResult.descriptors,\n scaffoldContext,\n );\n } else {\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n const planner = migrations.createPlanner(familyInstance);\n const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);\n const plannerResult = planner.plan({\n contract: toContractJson,\n schema: fromSchema,\n policy: { allowedOperationClasses: ['additive', 'widening', 'destructive', 'data'] },\n fromHash,\n frameworkComponents,\n });\n if (plannerResult.kind === 'failure') {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: plannerResult.conflicts as readonly CliErrorConflict[],\n }),\n );\n }\n if (plannerResult.plan.operations.length === 0) {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: [\n {\n kind: 'unsupportedChange',\n summary:\n 'Contract changed but planner produced no operations. ' +\n 'This indicates unsupported or ignored changes.',\n },\n ],\n }),\n );\n }\n migrationTsContent = plannerResult.plan.renderTypeScript();\n }\n\n await writeMigrationPackage(packageDir, manifest, []);\n await copyContractToMigrationDir(packageDir, contractPathAbsolute);\n await writeMigrationTs(packageDir, migrationTsContent);\n\n // Always run emit inline. If migration.ts contains unfilled\n // placeholders (e.g. user must hand-author a dataTransform body),\n // emitMigration throws errorUnfilledPlaceholder (PN-MIG-2001) and\n // we propagate that structured error to the user.\n const { operations, migrationId } = await emitMigration(packageDir, {\n targetId: config.target.targetId,\n migrations,\n frameworkComponents,\n });\n\n const sql = extractSqlDdl(operations);\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n migrationId,\n dir: relative(process.cwd(), packageDir),\n operations: operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n sql,\n summary: `Planned ${operations.length} operation(s)`,\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n } catch (error) {\n return notOk(mapMigrationToolsError(error));\n }\n}\n\nexport function createMigrationPlanCommand(): Command {\n const command = new Command('plan');\n setCommandDescriptions(\n command,\n 'Plan a migration from contract changes',\n 'Compares the emitted contract against the latest on-disk migration state and\\n' +\n 'produces a new migration package with the required operations. No database\\n' +\n 'connection is needed — this is a fully offline operation.',\n );\n setCommandExamples(command, [\n 'prisma-next migration plan',\n 'prisma-next migration plan --name add-users-table',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--name <slug>', 'Name slug for the migration directory', 'migration')\n .option('--from <hash>', 'Explicit starting contract hash (overrides latest migration target)')\n .action(async (options: MigrationPlanOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const result = await executeMigrationPlanCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (planResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(planResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationPlanOutput(planResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n\nfunction formatMigrationPlanOutput(result: MigrationPlanResult, flags: GlobalFlags): string {\n const lines: string[] = [];\n const useColor = flags.color !== false;\n\n const green_ = useColor ? (s: string) => `\\x1b[32m${s}\\x1b[0m` : (s: string) => s;\n const yellow_ = useColor ? (s: string) => `\\x1b[33m${s}\\x1b[0m` : (s: string) => s;\n const dim_ = useColor ? (s: string) => `\\x1b[2m${s}\\x1b[0m` : (s: string) => s;\n\n if (result.noOp) {\n lines.push(`${green_('✔')} No changes detected`);\n lines.push(dim_(` from: ${result.from}`));\n lines.push(dim_(` to: ${result.to}`));\n return lines.join('\\n');\n }\n\n lines.push(`${green_('✔')} ${result.summary}`);\n lines.push('');\n\n if (result.operations.length > 0) {\n lines.push(dim_('│'));\n for (let i = 0; i < result.operations.length; i++) {\n const op = result.operations[i]!;\n const isLast = i === result.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const opClassLabel =\n op.operationClass === 'destructive'\n ? yellow_(`[${op.operationClass}]`)\n : dim_(`[${op.operationClass}]`);\n lines.push(`${dim_(treeChar)}─ ${op.label} ${opClassLabel}`);\n }\n\n const hasDestructive = result.operations.some((op) => op.operationClass === 'destructive');\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${yellow_('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n lines.push('');\n }\n\n lines.push(dim_(`from: ${result.from}`));\n lines.push(dim_(`to: ${result.to}`));\n if (result.migrationId) {\n lines.push(dim_(`migrationId: ${result.migrationId}`));\n }\n if (result.dir) {\n lines.push(dim_(`dir: ${result.dir}`));\n }\n\n if (result.sql && result.sql.length > 0) {\n lines.push('');\n lines.push(dim_('DDL preview'));\n lines.push('');\n for (const statement of result.sql) {\n const trimmed = statement.trim();\n if (!trimmed) continue;\n const line = trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n lines.push(line);\n }\n }\n\n if (flags.verbose && result.timings) {\n lines.push('');\n lines.push(dim_(`Total time: ${result.timings.total}ms`));\n }\n\n return lines.join('\\n');\n}\n\nexport type PrefixResolutionFailure =\n | { reason: 'ambiguous'; count: number }\n | { reason: 'not-found' };\n\n/**\n * Resolve a migration bundle by exact hash or prefix match.\n *\n * Tries exact match first, then prefix match (auto-prepending `sha256:` when\n * the needle omits the scheme). Returns the matched bundle on success, or a\n * discriminated failure indicating whether the prefix was ambiguous or simply\n * not found.\n *\n * @internal Exported for testing only.\n */\nexport function resolveBundleByPrefix<T extends { manifest: { to: string } }>(\n bundles: readonly T[],\n needle: string,\n): Result<T, PrefixResolutionFailure> {\n const exact = bundles.find((p) => p.manifest.to === needle);\n if (exact) return ok(exact);\n\n const prefixWithScheme = needle.startsWith('sha256:') ? needle : `sha256:${needle}`;\n const candidates = bundles.filter((p) => p.manifest.to.startsWith(prefixWithScheme));\n\n if (candidates.length === 1) return ok(candidates[0]!);\n if (candidates.length > 1) return notOk({ reason: 'ambiguous', count: candidates.length });\n return notOk({ reason: 'not-found' });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"migration-plan.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","toContractJson: Contract","fromContract: Contract | null","fromHash: string","fromContractSourceDir: string | null","baseManifest: Omit<MigrationManifest, 'migrationId'>","plannedOps: readonly MigrationPlanOperation[]","lines: string[]"],"sources":["../../src/commands/migration-plan.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport {\n createControlStack,\n type MigrationPlanOperation,\n} from '@prisma-next/framework-components/control';\nimport { computeMigrationId } from '@prisma-next/migration-tools/attestation';\nimport { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';\nimport { findLatestMigration } from '@prisma-next/migration-tools/dag';\nimport {\n copyFilesWithRename,\n formatMigrationDirName,\n writeMigrationPackage,\n} from '@prisma-next/migration-tools/io';\nimport { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';\nimport { type MigrationManifest, MigrationToolsError } from '@prisma-next/migration-tools/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join, relative } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { extractSqlDdl } from '../control-api/operations/extract-sql-ddl';\nimport {\n type CliErrorConflict,\n CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorMigrationPlanningFailed,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n getTargetMigrations,\n loadAllBundles,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationPlanOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly name?: string;\n readonly from?: string;\n}\n\nexport interface MigrationPlanResult {\n readonly ok: boolean;\n readonly noOp: boolean;\n readonly from: string;\n readonly to: string;\n readonly dir?: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly sql?: readonly string[];\n readonly summary: string;\n /**\n * When true, `migration.ts` was written but contains unfilled\n * `placeholder(...)` calls. The user must edit the file and then run\n * `node migration.ts` to self-emit `ops.json` / `migration.json`.\n */\n readonly pendingPlaceholders?: boolean;\n readonly timings: {\n readonly total: number;\n };\n}\n\nfunction mapMigrationToolsError(error: unknown): CliStructuredError {\n if (CliStructuredError.is(error)) {\n return error;\n }\n if (MigrationToolsError.is(error)) {\n return errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n });\n }\n return errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migration plan: ${error instanceof Error ? error.message : String(error)}`,\n });\n}\n\nasync function executeMigrationPlanCommand(\n options: MigrationPlanOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrationPlanResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, migrationsRelative } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (options.from) {\n details.push({ label: 'from', value: options.from });\n }\n if (options.name) {\n details.push({ label: 'name', value: options.name });\n }\n const header = formatStyledHeader({\n command: 'migration plan',\n description: 'Plan a migration from contract changes',\n url: 'https://pris.ly/migration-plan',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n // Load contract file (the \"to\" contract)\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let toContractJson: Contract;\n try {\n toContractJson = JSON.parse(contractJsonContent) as Contract;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const rawStorageHash = toContractJson.storage?.storageHash;\n if (typeof rawStorageHash !== 'string') {\n return notOk(\n errorContractValidationFailed('Contract is missing storageHash', {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n const toStorageHash = rawStorageHash;\n\n // Read existing migrations and determine \"from\" contract\n let fromContract: Contract | null = null;\n let fromHash: string = EMPTY_CONTRACT_HASH;\n let fromContractSourceDir: string | null = null;\n\n try {\n const { bundles, graph } = await loadAllBundles(migrationsDir);\n\n if (options.from) {\n const resolved = resolveBundleByPrefix(bundles, options.from);\n if (!resolved.ok) {\n const f = resolved.failure;\n return notOk(\n f.reason === 'ambiguous'\n ? errorRuntime('Multiple matching migrations found', {\n why: `Prefix \"${options.from}\" matches ${f.count} migrations in ${migrationsRelative}`,\n fix: 'Provide a longer prefix to disambiguate, or omit --from to use the latest migration target.',\n })\n : errorRuntime('Starting contract not found', {\n why: `No migration with to hash matching \"${options.from}\" exists in ${migrationsRelative}`,\n fix: 'Check that the --from hash matches a known migration target hash, or omit --from to use the latest migration target.',\n }),\n );\n }\n fromHash = resolved.value.manifest.to;\n fromContract = resolved.value.manifest.toContract;\n fromContractSourceDir = resolved.value.dirPath;\n } else {\n const latestMigration = findLatestMigration(graph);\n if (latestMigration) {\n fromHash = latestMigration.to;\n const leafPkg = bundles.find((p) => p.manifest.migrationId === latestMigration.migrationId);\n if (leafPkg) {\n fromContract = leafPkg.manifest.toContract;\n fromContractSourceDir = leafPkg.dirPath;\n }\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n // Check for no-op (same hash means no changes)\n if (fromHash === toStorageHash) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: true,\n from: fromHash,\n to: toStorageHash,\n operations: [],\n summary: 'No changes detected between contracts',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n // Check target supports migrations\n const migrations = getTargetMigrations(config.target);\n if (!migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n const frameworkComponents = assertFrameworkComponentsCompatible(\n config.family.familyId,\n config.target.targetId,\n [config.target, config.adapter, ...(config.extensionPacks ?? [])],\n );\n\n // Build manifest and write migration package\n const timestamp = new Date();\n const slug = options.name ?? 'migration';\n const dirName = formatMigrationDirName(timestamp, slug);\n const packageDir = join(migrationsDir, dirName);\n\n const baseManifest: Omit<MigrationManifest, 'migrationId'> = {\n from: fromHash,\n to: toStorageHash,\n kind: 'regular',\n fromContract,\n toContract: toContractJson,\n hints: {\n used: [],\n applied: [],\n plannerVersion: '2.0.0',\n },\n labels: [],\n createdAt: timestamp.toISOString(),\n };\n\n try {\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n const planner = migrations.createPlanner(familyInstance);\n const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);\n const plannerResult = planner.plan({\n contract: toContractJson,\n schema: fromSchema,\n policy: { allowedOperationClasses: ['additive', 'widening', 'destructive', 'data'] },\n fromHash,\n fromContract,\n frameworkComponents,\n });\n if (plannerResult.kind === 'failure') {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: plannerResult.conflicts as readonly CliErrorConflict[],\n }),\n );\n }\n\n // Accessing .operations triggers toOp() on each call. If any call\n // is a DataTransformCall with an unfilled placeholder stub, toOp()\n // throws PN-MIG-2001. We catch that here so the migration can still\n // be scaffolded with `ops: []`; the user fills the placeholder, then\n // re-runs `node migration.ts` to attest with the real ops.\n let plannedOps: readonly MigrationPlanOperation[] = [];\n let hasPlaceholders = false;\n try {\n plannedOps = plannerResult.plan.operations;\n if (plannedOps.length === 0) {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: [\n {\n kind: 'unsupportedChange',\n summary:\n 'Contract changed but planner produced no operations. ' +\n 'This indicates unsupported or ignored changes.',\n },\n ],\n }),\n );\n }\n } catch (e) {\n if (CliStructuredError.is(e) && e.domain === 'MIG' && e.code === '2001') {\n hasPlaceholders = true;\n } else {\n throw e;\n }\n }\n\n const migrationTsContent = plannerResult.plan.renderTypeScript();\n\n // Always-attest: compute migrationId over (manifest, ops). When\n // placeholders blocked lowering, ops is `[]` and the id hashes over\n // the empty list — re-emitting after the user fills the placeholder\n // produces a different id (over the real ops). This is intentional;\n // there is no on-disk \"draft\" state.\n const opsForWrite = hasPlaceholders ? [] : plannedOps;\n const manifest: MigrationManifest = {\n ...baseManifest,\n migrationId: computeMigrationId(baseManifest, opsForWrite),\n };\n\n await writeMigrationPackage(packageDir, manifest, opsForWrite);\n const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);\n await copyFilesWithRename(packageDir, [\n { sourcePath: destinationArtifacts.jsonPath, destName: 'end-contract.json' },\n { sourcePath: destinationArtifacts.dtsPath, destName: 'end-contract.d.ts' },\n ]);\n if (fromContractSourceDir !== null) {\n const sourceArtifacts = getEmittedArtifactPaths(\n join(fromContractSourceDir, 'end-contract.json'),\n );\n await copyFilesWithRename(packageDir, [\n { sourcePath: sourceArtifacts.jsonPath, destName: 'start-contract.json' },\n { sourcePath: sourceArtifacts.dtsPath, destName: 'start-contract.d.ts' },\n ]);\n }\n await writeMigrationTs(packageDir, migrationTsContent);\n\n if (hasPlaceholders) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), packageDir),\n operations: [],\n pendingPlaceholders: true,\n summary:\n 'Planned migration with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const sql = extractSqlDdl(plannedOps);\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), packageDir),\n operations: plannedOps.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n sql,\n summary: `Planned ${plannedOps.length} operation(s)`,\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n } catch (error) {\n return notOk(mapMigrationToolsError(error));\n }\n}\n\nexport function createMigrationPlanCommand(): Command {\n const command = new Command('plan');\n setCommandDescriptions(\n command,\n 'Plan a migration from contract changes',\n 'Compares the emitted contract against the latest on-disk migration state and\\n' +\n 'produces a new migration package with the required operations. No database\\n' +\n 'connection is needed — this is a fully offline operation.',\n );\n setCommandExamples(command, [\n 'prisma-next migration plan',\n 'prisma-next migration plan --name add-users-table',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--name <slug>', 'Name slug for the migration directory', 'migration')\n .option('--from <hash>', 'Explicit starting contract hash (overrides latest migration target)')\n .action(async (options: MigrationPlanOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const result = await executeMigrationPlanCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (planResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(planResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationPlanOutput(planResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n\nfunction formatMigrationPlanOutput(result: MigrationPlanResult, flags: GlobalFlags): string {\n const lines: string[] = [];\n const useColor = flags.color !== false;\n\n const green_ = useColor ? (s: string) => `\\x1b[32m${s}\\x1b[0m` : (s: string) => s;\n const yellow_ = useColor ? (s: string) => `\\x1b[33m${s}\\x1b[0m` : (s: string) => s;\n const dim_ = useColor ? (s: string) => `\\x1b[2m${s}\\x1b[0m` : (s: string) => s;\n\n if (result.noOp) {\n lines.push(`${green_('✔')} No changes detected`);\n lines.push(dim_(` from: ${result.from}`));\n lines.push(dim_(` to: ${result.to}`));\n return lines.join('\\n');\n }\n\n if (result.pendingPlaceholders) {\n lines.push(`${yellow_('⚠')} ${result.summary}`);\n lines.push('');\n lines.push(dim_(`from: ${result.from}`));\n lines.push(dim_(`to: ${result.to}`));\n if (result.dir) {\n lines.push(dim_(`dir: ${result.dir}`));\n }\n lines.push('');\n lines.push(\n 'Open migration.ts and replace each `placeholder(...)` call with your actual query.',\n );\n lines.push(`Then run: ${green_(`node ${result.dir ?? '<dir>'}/migration.ts`)}`);\n return lines.join('\\n');\n }\n\n lines.push(`${green_('✔')} ${result.summary}`);\n lines.push('');\n\n if (result.operations.length > 0) {\n lines.push(dim_('│'));\n for (let i = 0; i < result.operations.length; i++) {\n const op = result.operations[i]!;\n const isLast = i === result.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const opClassLabel =\n op.operationClass === 'destructive'\n ? yellow_(`[${op.operationClass}]`)\n : dim_(`[${op.operationClass}]`);\n lines.push(`${dim_(treeChar)}─ ${op.label} ${opClassLabel}`);\n }\n\n const hasDestructive = result.operations.some((op) => op.operationClass === 'destructive');\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${yellow_('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n lines.push('');\n }\n\n lines.push(dim_(`from: ${result.from}`));\n lines.push(dim_(`to: ${result.to}`));\n if (result.dir) {\n lines.push(dim_(`dir: ${result.dir}`));\n }\n\n lines.push('');\n lines.push(\n `Next: ${green_(`node ${result.dir ?? '<dir>'}/migration.ts`)} to emit ops.json and attest migrationId before running ${green_('prisma-next migration apply')}.`,\n );\n\n if (result.sql && result.sql.length > 0) {\n lines.push('');\n lines.push(dim_('DDL preview'));\n lines.push('');\n for (const statement of result.sql) {\n const trimmed = statement.trim();\n if (!trimmed) continue;\n const line = trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n lines.push(line);\n }\n }\n\n if (flags.verbose && result.timings) {\n lines.push('');\n lines.push(dim_(`Total time: ${result.timings.total}ms`));\n }\n\n return lines.join('\\n');\n}\n\nexport type PrefixResolutionFailure =\n | { reason: 'ambiguous'; count: number }\n | { reason: 'not-found' };\n\n/**\n * Resolve a migration bundle by exact hash or prefix match.\n *\n * Tries exact match first, then prefix match (auto-prepending `sha256:` when\n * the needle omits the scheme). Returns the matched bundle on success, or a\n * discriminated failure indicating whether the prefix was ambiguous or simply\n * not found.\n *\n * @internal Exported for testing only.\n */\nexport function resolveBundleByPrefix<T extends { manifest: { to: string } }>(\n bundles: readonly T[],\n needle: string,\n): Result<T, PrefixResolutionFailure> {\n const exact = bundles.find((p) => p.manifest.to === needle);\n if (exact) return ok(exact);\n\n const prefixWithScheme = needle.startsWith('sha256:') ? needle : `sha256:${needle}`;\n const candidates = bundles.filter((p) => p.manifest.to.startsWith(prefixWithScheme));\n\n if (candidates.length === 1) return ok(candidates[0]!);\n if (candidates.length > 1) return notOk({ reason: 'ambiguous', count: candidates.length });\n return notOk({ reason: 'not-found' });\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as CliStructuredError } from "../cli-errors-Dic2eADK.mjs";
1
+ import { t as CliStructuredError } from "../cli-errors-z37sV3eR.mjs";
2
2
  import { Command } from "commander";
3
3
  import { Result } from "@prisma-next/utils/result";
4
4
 
@@ -1,12 +1,12 @@
1
- import { t as loadConfig } from "../config-loader-C4VXKl8f.mjs";
2
- import { h as errorRuntime, t as CliStructuredError, v as errorUnexpected } from "../cli-errors-BUuJr6py.mjs";
3
- import { h as formatCommandHelp, m as parseGlobalFlags, n as addGlobalOptions, t as handleResult, u as setCommandDescriptions } from "../result-handler-AFK4hxyX.mjs";
4
- import { t as TerminalUI } from "../terminal-ui-C5k88MmW.mjs";
1
+ import { t as loadConfig } from "../config-loader-_xQZsw0i.mjs";
2
+ import { _ as errorUnexpected, m as errorRuntime, t as CliStructuredError } from "../cli-errors-CznZA5-d.mjs";
3
+ import { h as formatCommandHelp, m as parseGlobalFlags, n as addGlobalOptions, t as handleResult, u as setCommandDescriptions } from "../result-handler-CGohaH1o.mjs";
4
+ import { t as TerminalUI } from "../terminal-ui-BuPXVRFY.mjs";
5
5
  import { Command } from "commander";
6
6
  import { notOk, ok } from "@prisma-next/utils/result";
7
7
  import { resolve } from "pathe";
8
- import { MigrationToolsError } from "@prisma-next/migration-tools/types";
9
8
  import { readRefs, resolveRef, validateRefName, validateRefValue, writeRefs } from "@prisma-next/migration-tools/refs";
9
+ import { MigrationToolsError } from "@prisma-next/migration-tools/types";
10
10
 
11
11
  //#region src/commands/migration-ref.ts
12
12
  function resolveRefsPath(configPath, config) {
@@ -1,4 +1,4 @@
1
- import { t as CliStructuredError } from "../cli-errors-Dic2eADK.mjs";
1
+ import { t as CliStructuredError } from "../cli-errors-z37sV3eR.mjs";
2
2
  import { Command } from "commander";
3
3
  import { Result } from "@prisma-next/utils/result";
4
4
  import { MigrationBundle } from "@prisma-next/migration-tools/types";
@@ -10,7 +10,7 @@ interface MigrationShowResult {
10
10
  readonly dirPath: string;
11
11
  readonly from: string;
12
12
  readonly to: string;
13
- readonly migrationId: string | null;
13
+ readonly migrationId: string;
14
14
  readonly kind: string;
15
15
  readonly createdAt: string;
16
16
  readonly operations: readonly {
@@ -1 +1 @@
1
- {"version":3,"file":"migration-show.d.mts","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":[],"mappings":";;;;;;UA2BiB,mBAAA;;EAAA,SAAA,OAAA,EAAA,MAAmB;EAsBpB,SAAA,OAAA,EAAA,MAAmB;EACd,SAAA,IAAA,EAAA,MAAA;EAEX,SAAA,EAAA,EAAA,MAAA;EAAiB,SAAA,WAAA,EAAA,MAAA,GAAA,IAAA;EAAxB,SAAA,IAAA,EAAA,MAAA;EAAM,SAAA,SAAA,EAAA,MAAA;EA2JO,SAAA,UAAA,EAAA,SAA0B;;;;;;;;iBA9J1B,mBAAA,oBACK,oCAElB,OAAO,iBAAiB;iBA2JX,0BAAA,CAAA,GAA8B"}
1
+ {"version":3,"file":"migration-show.d.mts","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":[],"mappings":";;;;;;UA2BiB,mBAAA;;EAAA,SAAA,OAAA,EAAA,MAAmB;EAsBpB,SAAA,OAAA,EAAA,MAAmB;EACd,SAAA,IAAA,EAAA,MAAA;EAEX,SAAA,EAAA,EAAA,MAAA;EAAiB,SAAA,WAAA,EAAA,MAAA;EAAxB,SAAA,IAAA,EAAA,MAAA;EAAM,SAAA,SAAA,EAAA,MAAA;EAiJO,SAAA,UAAA,EAAA,SAA0B;;;;;;;;iBApJ1B,mBAAA,oBACK,oCAElB,OAAO,iBAAiB;iBAiJX,0BAAA,CAAA,GAA8B"}
@@ -1,15 +1,15 @@
1
- import { t as loadConfig } from "../config-loader-C4VXKl8f.mjs";
2
- import { h as errorRuntime, v as errorUnexpected } from "../cli-errors-BUuJr6py.mjs";
3
- import { t as extractOperationStatements } from "../extract-operation-statements-DZUJNmL3.mjs";
4
- import { _ as formatStyledHeader, d as setCommandExamples, m as parseGlobalFlags, n as addGlobalOptions, t as handleResult, u as setCommandDescriptions } from "../result-handler-AFK4hxyX.mjs";
5
- import { t as TerminalUI } from "../terminal-ui-C5k88MmW.mjs";
6
- import { o as formatMigrationShowOutput } from "../migrations-BIsjFjSV.mjs";
1
+ import { t as loadConfig } from "../config-loader-_xQZsw0i.mjs";
2
+ import { _ as errorUnexpected, m as errorRuntime } from "../cli-errors-CznZA5-d.mjs";
3
+ import { t as extractOperationStatements } from "../extract-operation-statements-DWWFz1PK.mjs";
4
+ import { _ as formatStyledHeader, d as setCommandExamples, m as parseGlobalFlags, n as addGlobalOptions, t as handleResult, u as setCommandDescriptions } from "../result-handler-CGohaH1o.mjs";
5
+ import { t as TerminalUI } from "../terminal-ui-BuPXVRFY.mjs";
6
+ import { a as formatMigrationShowOutput } from "../migrations-DYRAjiVh.mjs";
7
7
  import { Command } from "commander";
8
8
  import { notOk, ok } from "@prisma-next/utils/result";
9
9
  import { relative, resolve } from "pathe";
10
10
  import { findLatestMigration, reconstructGraph } from "@prisma-next/migration-tools/dag";
11
11
  import { readMigrationPackage, readMigrationsDir } from "@prisma-next/migration-tools/io";
12
- import { MigrationToolsError, isAttested } from "@prisma-next/migration-tools/types";
12
+ import { MigrationToolsError } from "@prisma-next/migration-tools/types";
13
13
 
14
14
  //#region src/commands/migration-show.ts
15
15
  function looksLikePath(target) {
@@ -17,10 +17,10 @@ function looksLikePath(target) {
17
17
  }
18
18
  function resolveByHashPrefix(packages, prefix) {
19
19
  const normalizedPrefix = prefix.startsWith("sha256:") ? prefix : `sha256:${prefix}`;
20
- const matches = packages.filter((p) => typeof p.manifest.migrationId === "string").filter((p) => p.manifest.migrationId.startsWith(normalizedPrefix));
20
+ const matches = packages.filter((p) => p.manifest.migrationId.startsWith(normalizedPrefix));
21
21
  if (matches.length === 1) return ok(matches[0]);
22
22
  if (matches.length === 0) return notOk(errorRuntime("No migration found matching prefix", {
23
- why: `No attested migration has a migrationId starting with "${normalizedPrefix}"`,
23
+ why: `No migration has a migrationId starting with "${normalizedPrefix}"`,
24
24
  fix: "Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages."
25
25
  }));
26
26
  return notOk(errorRuntime("Ambiguous hash prefix", {
@@ -67,17 +67,12 @@ async function executeMigrationShowCommand(target, options, flags, ui) {
67
67
  if (!resolved.ok) return resolved;
68
68
  pkg = resolved.value;
69
69
  } else {
70
- const attested = allPackages.filter(isAttested);
71
- if (attested.length === 0) return notOk(errorRuntime("No attested migrations found", {
72
- why: `All migrations in ${migrationsRelative} are drafts (migrationId: null)`,
73
- fix: "Run `prisma-next migration emit --dir <path>` to attest a draft migration."
74
- }));
75
- const latestMigration = findLatestMigration(reconstructGraph(attested));
70
+ const latestMigration = findLatestMigration(reconstructGraph(allPackages));
76
71
  if (!latestMigration) return notOk(errorRuntime("Could not resolve latest migration", {
77
72
  why: "No latest migration found in the migration history",
78
73
  fix: "The migrations directory may be corrupted. Inspect the migration.json files."
79
74
  }));
80
- const leafPkg = attested.find((p) => p.manifest.migrationId === latestMigration.migrationId);
75
+ const leafPkg = allPackages.find((p) => p.manifest.migrationId === latestMigration.migrationId);
81
76
  if (!leafPkg) return notOk(errorRuntime("Could not resolve latest migration", {
82
77
  why: `Latest migration ${latestMigration.dirName} does not match any package`,
83
78
  fix: "The migrations directory may be corrupted. Inspect the migration.json files."
@@ -1 +1 @@
1
- {"version":3,"file":"migration-show.mjs","names":["details: Array<{ label: string; value: string }>","pkg: MigrationBundle"],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';\nimport { findLatestMigration, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type { MigrationBundle } from '@prisma-next/migration-tools/types';\nimport { isAttested, MigrationToolsError } from '@prisma-next/migration-tools/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { extractOperationStatements } from '../control-api/operations/extract-operation-statements';\nimport { type CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string | null;\n readonly kind: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly sql: readonly string[];\n readonly summary: string;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveByHashPrefix(\n packages: readonly MigrationBundle[],\n prefix: string,\n): Result<MigrationBundle, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const attested = packages.filter((p) => typeof p.manifest.migrationId === 'string');\n const matches = attested.filter((p) => p.manifest.migrationId!.startsWith(normalizedPrefix));\n\n if (matches.length === 1) {\n return ok(matches[0]!);\n }\n\n if (matches.length === 0) {\n return notOk(\n errorRuntime('No migration found matching prefix', {\n why: `No attested migration has a migrationId starting with \"${normalizedPrefix}\"`,\n fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',\n }),\n );\n }\n\n const candidates = matches.map((p) => ` ${p.dirName} ${p.manifest.migrationId}`).join('\\n');\n return notOk(\n errorRuntime('Ambiguous hash prefix', {\n why: `Multiple migrations match prefix \"${normalizedPrefix}\":\\n${candidates}`,\n fix: 'Provide a longer prefix to uniquely identify the migration.',\n }),\n );\n}\n\nasync function executeMigrationShowCommand(\n target: string | undefined,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (target) {\n details.push({ label: 'target', value: target });\n }\n const header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let pkg: MigrationBundle;\n\n try {\n if (target && looksLikePath(target)) {\n pkg = await readMigrationPackage(resolve(target));\n } else {\n const allPackages = await readMigrationsDir(migrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${migrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n\n if (target) {\n const resolved = resolveByHashPrefix(allPackages, target);\n if (!resolved.ok) return resolved;\n pkg = resolved.value;\n } else {\n const attested = allPackages.filter(isAttested);\n if (attested.length === 0) {\n return notOk(\n errorRuntime('No attested migrations found', {\n why: `All migrations in ${migrationsRelative} are drafts (migrationId: null)`,\n fix: 'Run `prisma-next migration emit --dir <path>` to attest a draft migration.',\n }),\n );\n }\n const graph = reconstructGraph(attested);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: 'No latest migration found in the migration history',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = attested.find(\n (p) => p.manifest.migrationId === latestMigration.migrationId,\n );\n if (!leafPkg) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `Latest migration ${latestMigration.dirName} does not match any package`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n pkg = leafPkg;\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n const sql = extractOperationStatements(config.family.familyId, ops) ?? [];\n\n const result: MigrationShowResult = {\n ok: true,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.manifest.from,\n to: pkg.manifest.to,\n migrationId: pkg.manifest.migrationId,\n kind: pkg.manifest.kind,\n createdAt: pkg.manifest.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n sql,\n summary: `${ops.length} operation(s)`,\n };\n return ok(result);\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, DDL preview, and metadata for a migration package.\\n' +\n 'Accepts a directory path, a hash prefix (git-style), or defaults to the\\n' +\n 'latest migration.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n addGlobalOptions(command)\n .argument(\n '[target]',\n 'Migration directory path or migrationId hash prefix (defaults to latest)',\n )\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"migration-show.mjs","names":["details: Array<{ label: string; value: string }>","pkg: MigrationBundle"],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';\nimport { findLatestMigration, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type { MigrationBundle } from '@prisma-next/migration-tools/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { extractOperationStatements } from '../control-api/operations/extract-operation-statements';\nimport { type CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string;\n readonly kind: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly sql: readonly string[];\n readonly summary: string;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveByHashPrefix(\n packages: readonly MigrationBundle[],\n prefix: string,\n): Result<MigrationBundle, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const matches = packages.filter((p) => p.manifest.migrationId.startsWith(normalizedPrefix));\n\n if (matches.length === 1) {\n return ok(matches[0]!);\n }\n\n if (matches.length === 0) {\n return notOk(\n errorRuntime('No migration found matching prefix', {\n why: `No migration has a migrationId starting with \"${normalizedPrefix}\"`,\n fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',\n }),\n );\n }\n\n const candidates = matches.map((p) => ` ${p.dirName} ${p.manifest.migrationId}`).join('\\n');\n return notOk(\n errorRuntime('Ambiguous hash prefix', {\n why: `Multiple migrations match prefix \"${normalizedPrefix}\":\\n${candidates}`,\n fix: 'Provide a longer prefix to uniquely identify the migration.',\n }),\n );\n}\n\nasync function executeMigrationShowCommand(\n target: string | undefined,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (target) {\n details.push({ label: 'target', value: target });\n }\n const header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let pkg: MigrationBundle;\n\n try {\n if (target && looksLikePath(target)) {\n pkg = await readMigrationPackage(resolve(target));\n } else {\n const allPackages = await readMigrationsDir(migrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${migrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n\n if (target) {\n const resolved = resolveByHashPrefix(allPackages, target);\n if (!resolved.ok) return resolved;\n pkg = resolved.value;\n } else {\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: 'No latest migration found in the migration history',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.manifest.migrationId === latestMigration.migrationId,\n );\n if (!leafPkg) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `Latest migration ${latestMigration.dirName} does not match any package`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n pkg = leafPkg;\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n const sql = extractOperationStatements(config.family.familyId, ops) ?? [];\n\n const result: MigrationShowResult = {\n ok: true,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.manifest.from,\n to: pkg.manifest.to,\n migrationId: pkg.manifest.migrationId,\n kind: pkg.manifest.kind,\n createdAt: pkg.manifest.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n sql,\n summary: `${ops.length} operation(s)`,\n };\n return ok(result);\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, DDL preview, and metadata for a migration package.\\n' +\n 'Accepts a directory path, a hash prefix (git-style), or defaults to the\\n' +\n 'latest migration.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n addGlobalOptions(command)\n .argument(\n '[target]',\n 'Migration directory path or migrationId hash prefix (defaults to latest)',\n )\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { AttestedMigrationBundle, DraftMigrationBundle, MigrationGraph } from "@prisma-next/migration-tools/types";
2
+ import { MigrationBundle, MigrationGraph } from "@prisma-next/migration-tools/types";
3
3
 
4
4
  //#region src/utils/migration-types.d.ts
5
5
  interface StatusRef {
@@ -27,7 +27,7 @@ interface MigrationStatusEntry {
27
27
  readonly dirName: string;
28
28
  readonly from: string;
29
29
  readonly to: string;
30
- readonly migrationId: string | null;
30
+ readonly migrationId: string;
31
31
  readonly operationCount: number;
32
32
  readonly operationSummary: string;
33
33
  readonly hasDestructive: boolean;
@@ -49,7 +49,7 @@ interface MigrationStatusResult {
49
49
  readonly refName?: string;
50
50
  readonly selectedPath: readonly {
51
51
  readonly dirName: string;
52
- readonly migrationId: string | null;
52
+ readonly migrationId: string;
53
53
  readonly from: string;
54
54
  readonly to: string;
55
55
  }[];
@@ -57,8 +57,7 @@ interface MigrationStatusResult {
57
57
  readonly summary: string;
58
58
  readonly diagnostics: readonly StatusDiagnostic[];
59
59
  readonly graph?: MigrationGraph;
60
- readonly bundles?: readonly AttestedMigrationBundle[];
61
- readonly drafts?: readonly DraftMigrationBundle[];
60
+ readonly bundles?: readonly MigrationBundle[];
62
61
  readonly edgeStatuses?: readonly EdgeStatus[];
63
62
  readonly activeRefHash?: string;
64
63
  readonly activeRefName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/migration-types.ts","../../src/utils/formatters/graph-migration-mapper.ts","../../src/commands/migration-status.ts"],"sourcesContent":[],"mappings":";;;;UAAiB,SAAA;;;;AAAjB;AAMiB,UAAA,gBAAA,CAAgB;;;;ECWrB,SAAA,KAAA,EAAA,SAAc,MAAA,EAAA;AAmB1B;;;KAnBY,cAAA;ADjBZ;AAMiB,UC8BA,UAAA,CD9BgB;;mBCgCd;;;;ADtCF,UE4DA,oBAAA,CF5DS;EAMT,SAAA,OAAA,EAAA,MAAgB;;;;ECWrB,SAAA,cAAc,EAAA,MAAA;EAmBT,SAAA,gBAEE,EAAA,MAAA;;mBC8BA;;AAKF,UAAA,qBAAA,CAAqB;EAGN,SAAA,EAAA,EAAA,IAAA;EAIL,SAAA,IAAA,EAAA,QAAA,GAAA,SAAA;EAeM,SAAA,UAAA,EAAA,SAnBD,oBAmBC,EAAA;EACd,SAAA,UAAA,CAAA,EAAA,MAAA;EACW,SAAA,UAAA,EAAA,MAAA;EACD,SAAA,YAAA,EAAA,MAAA;EACM,SAAA,IAAA,CAAA,EAAA,SAnBR,SAmBQ,EAAA;EAAU,SAAA,YAAA,CAAA,EAAA;IAkD7B,SAAA,QAAkB,EAAA,MAAA;IAwjBlB,SAAA,MAAA,EAAA,MAAA;;;;;;;;;;;;iCA9mBiB;mBACd;8BACW;6BACD;mCACM;;;;;;;;;;;;;;;;;;;;iBAkDnB,kBAAA,QACP,uHAKN;iBAkjBa,4BAAA,CAAA,GAAgC"}
1
+ {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/migration-types.ts","../../src/utils/formatters/graph-migration-mapper.ts","../../src/commands/migration-status.ts"],"sourcesContent":[],"mappings":";;;;UAAiB,SAAA;;;;AAAjB;AAMiB,UAAA,gBAAA,CAAgB;;;;ECWrB,SAAA,KAAA,EAAA,SAAc,MAAA,EAAA;AAmB1B;;;KAnBY,cAAA;ADjBZ;AAMiB,UC8BA,UAAA,CD9BgB;;mBCgCd;;;;ADtCF,UE2DA,oBAAA,CF3DS;EAMT,SAAA,OAAA,EAAA,MAAgB;;;;ECWrB,SAAA,cAAc,EAAA,MAAA;EAmBT,SAAA,gBAEE,EAAA,MAAA;;mBC6BA;;AAKF,UAAA,qBAAA,CAAqB;EAGN,SAAA,EAAA,EAAA,IAAA;EAIL,SAAA,IAAA,EAAA,QAAA,GAAA,SAAA;EAeM,SAAA,UAAA,EAAA,SAnBD,oBAmBC,EAAA;EACd,SAAA,UAAA,CAAA,EAAA,MAAA;EACW,SAAA,UAAA,EAAA,MAAA;EACK,SAAA,YAAA,EAAA,MAAA;EAAU,SAAA,IAAA,CAAA,EAAA,SAlBlB,SAkBkB,EAAA;EAkD7B,SAAA,YAAkB,CAAA,EAAA;IA2iBlB,SAAA,QAAA,EAAA,MAAA;;;;;;;;;;;;;iCAhmBiB;mBACd;8BACW;mCACK;;;;;;;;;;;;;;;;;;;;iBAkDnB,kBAAA,QACP,uHAKN;iBAqiBa,4BAAA,CAAA,GAAgC"}
@@ -1,9 +1,4 @@
1
- import "../config-loader-C4VXKl8f.mjs";
2
- import "../cli-errors-BUuJr6py.mjs";
3
- import "../framework-components-Bsr1GaIj.mjs";
4
- import "../client-CJxHfhze.mjs";
5
- import "../result-handler-AFK4hxyX.mjs";
6
- import "../terminal-ui-C5k88MmW.mjs";
7
- import { n as deriveEdgeStatuses, t as createMigrationStatusCommand } from "../migration-status-CPamfEPj.mjs";
1
+ import "../config-loader-_xQZsw0i.mjs";
2
+ import { n as deriveEdgeStatuses, t as createMigrationStatusCommand } from "../migration-status-CXBbScH5.mjs";
8
3
 
9
4
  export { createMigrationStatusCommand, deriveEdgeStatuses };