prisma-next 0.11.0-dev.56 → 0.11.0-dev.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{cli-errors-DFF1LlfU.mjs → cli-errors-DQY629C7.mjs} +16 -11
- package/dist/{cli-errors-DFF1LlfU.mjs.map → cli-errors-DQY629C7.mjs.map} +1 -1
- package/dist/cli.mjs +9 -9
- package/dist/{client-5uvDppD8.mjs → client-Ls2SAhrZ.mjs} +24 -6
- package/dist/{client-5uvDppD8.mjs.map → client-Ls2SAhrZ.mjs.map} +1 -1
- package/dist/{command-helpers-4UNsRRc4.mjs → command-helpers-DTpEJCgI.mjs} +2 -2
- package/dist/{command-helpers-4UNsRRc4.mjs.map → command-helpers-DTpEJCgI.mjs.map} +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +5 -5
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +4 -4
- package/dist/commands/db-update.mjs +5 -5
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +34 -38
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.mjs +1 -1
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +3 -3
- package/dist/commands/migration-list.d.mts +2 -2
- package/dist/commands/migration-list.mjs +1 -1
- package/dist/commands/migration-log.mjs +3 -3
- package/dist/commands/migration-new.mjs +4 -4
- package/dist/commands/migration-plan.d.mts +1 -1
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +1 -1
- package/dist/commands/migration-show.mjs +4 -4
- package/dist/commands/migration-status.d.mts +1 -1
- package/dist/commands/migration-status.mjs +6 -6
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +2 -2
- package/dist/contract-at-errors-B98TC1wK.mjs +42 -0
- package/dist/contract-at-errors-B98TC1wK.mjs.map +1 -0
- package/dist/{contract-emit-C-CFGZsI.mjs → contract-emit-BWLCn2PH.mjs} +3 -3
- package/dist/{contract-emit-C-CFGZsI.mjs.map → contract-emit-BWLCn2PH.mjs.map} +1 -1
- package/dist/{contract-emit-CuUzzM46.mjs → contract-emit-CS3vF-w9.mjs} +4 -4
- package/dist/{contract-emit-CuUzzM46.mjs.map → contract-emit-CS3vF-w9.mjs.map} +1 -1
- package/dist/{contract-infer-C98ZaRhp.mjs → contract-infer-BtefFYF-.mjs} +3 -3
- package/dist/{contract-infer-C98ZaRhp.mjs.map → contract-infer-BtefFYF-.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-CVHGuA35.mjs → contract-space-aggregate-loader-DX_1n2SA.mjs} +2 -2
- package/dist/{contract-space-aggregate-loader-CVHGuA35.mjs.map → contract-space-aggregate-loader-DX_1n2SA.mjs.map} +1 -1
- package/dist/{db-verify-BWl1Yxi-.mjs → db-verify-aHw2nzH2.mjs} +5 -5
- package/dist/{db-verify-BWl1Yxi-.mjs.map → db-verify-aHw2nzH2.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{framework-components-DTcjouhS.mjs → framework-components-BwuEBcyk.mjs} +2 -2
- package/dist/{framework-components-DTcjouhS.mjs.map → framework-components-BwuEBcyk.mjs.map} +1 -1
- package/dist/{global-flags-DWsQ6SSI.d.mts → global-flags-Bo6nCRUS.d.mts} +1 -1
- package/dist/{global-flags-DWsQ6SSI.d.mts.map → global-flags-Bo6nCRUS.d.mts.map} +1 -1
- package/dist/{glyph-mode-CBB4emzO.d.mts → glyph-mode-VIjULGFF.d.mts} +1 -1
- package/dist/glyph-mode-VIjULGFF.d.mts.map +1 -0
- package/dist/{graph-render-D2FnLpuK.mjs → graph-render-eJDcLWny.mjs} +1 -1
- package/dist/{graph-render-D2FnLpuK.mjs.map → graph-render-eJDcLWny.mjs.map} +1 -1
- package/dist/{init-C7PvN163.mjs → init-DOE4Q9YK.mjs} +5 -5
- package/dist/{init-C7PvN163.mjs.map → init-DOE4Q9YK.mjs.map} +1 -1
- package/dist/{inspect-live-schema-BRCWQ-Sr.mjs → inspect-live-schema-IS8jWaJy.mjs} +4 -4
- package/dist/{inspect-live-schema-BRCWQ-Sr.mjs.map → inspect-live-schema-IS8jWaJy.mjs.map} +1 -1
- package/dist/{migration-check-DoskM1nB.mjs → migration-check-BFdael8w.mjs} +2 -2
- package/dist/{migration-check-DoskM1nB.mjs.map → migration-check-BFdael8w.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-CXLkoIJx.mjs → migration-command-scaffold-DojkenVv.mjs} +4 -4
- package/dist/{migration-command-scaffold-CXLkoIJx.mjs.map → migration-command-scaffold-DojkenVv.mjs.map} +1 -1
- package/dist/{migration-list-B2-iQ5Jd.mjs → migration-list-hj86sCtZ.mjs} +3 -3
- package/dist/{migration-list-B2-iQ5Jd.mjs.map → migration-list-hj86sCtZ.mjs.map} +1 -1
- package/dist/{migration-plan-BqmIKQpZ.mjs → migration-plan-Bt6wxUIv.mjs} +165 -178
- package/dist/migration-plan-Bt6wxUIv.mjs.map +1 -0
- package/dist/{migration-types-q64xAI_J.d.mts → migration-types-D2FW63pr.d.mts} +1 -1
- package/dist/{migration-types-q64xAI_J.d.mts.map → migration-types-D2FW63pr.d.mts.map} +1 -1
- package/dist/{migrations-BcVTutso.mjs → migrations-CVLh0Kv4.mjs} +2 -2
- package/dist/{migrations-BcVTutso.mjs.map → migrations-CVLh0Kv4.mjs.map} +1 -1
- package/dist/{output-B60Gw5fu.mjs → output-CF_hqzI-.mjs} +1 -1
- package/dist/{output-B60Gw5fu.mjs.map → output-CF_hqzI-.mjs.map} +1 -1
- package/dist/{types-CEtm6v6a.d.mts → types-BuatV9YW.d.mts} +1 -1
- package/dist/{types-CEtm6v6a.d.mts.map → types-BuatV9YW.d.mts.map} +1 -1
- package/dist/{verify-DOHbbrub.mjs → verify-BiWm4XwD.mjs} +2 -2
- package/dist/{verify-DOHbbrub.mjs.map → verify-BiWm4XwD.mjs.map} +1 -1
- package/package.json +11 -11
- package/dist/glyph-mode-CBB4emzO.d.mts.map +0 -1
- package/dist/migration-plan-BqmIKQpZ.mjs.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import { A as mapRefResolutionError, E as errorTargetMigrationNotSupported, O as errorUnexpected, a as errorContractValidationFailed, h as errorMigrationPlanningFailed, k as mapMigrationToolsError, l as errorFileNotFound, t as CliStructuredError, v as errorPlanForgotTheFlag, w as errorSnapshotMissing } from "./cli-errors-
|
|
3
|
-
import { t as assertFrameworkComponentsCompatible } from "./framework-components-
|
|
4
|
-
import { D as formatStyledHeader,
|
|
2
|
+
import { A as mapRefResolutionError, E as errorTargetMigrationNotSupported, O as errorUnexpected, a as errorContractValidationFailed, h as errorMigrationPlanningFailed, k as mapMigrationToolsError, l as errorFileNotFound, t as CliStructuredError, v as errorPlanForgotTheFlag, w as errorSnapshotMissing } from "./cli-errors-DQY629C7.mjs";
|
|
3
|
+
import { t as assertFrameworkComponentsCompatible } from "./framework-components-BwuEBcyk.mjs";
|
|
4
|
+
import { D as formatStyledHeader, c as resolveContractPath, d as setCommandDescriptions, f as setCommandExamples, i as getTargetMigrations, l as resolveMigrationPaths, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as handleResult, y as createTerminalUI } from "./command-helpers-DTpEJCgI.mjs";
|
|
5
5
|
import { n as toExtensionInputs } from "./extension-pack-inputs-BiY86HbQ.mjs";
|
|
6
|
-
import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-
|
|
6
|
+
import { n as loadContractSpaceAggregateForCli, t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-DX_1n2SA.mjs";
|
|
7
|
+
import { t as mapContractAtError } from "./contract-at-errors-B98TC1wK.mjs";
|
|
7
8
|
import { Command } from "commander";
|
|
8
9
|
import { getEmittedArtifactPaths } from "@prisma-next/emitter";
|
|
9
10
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -14,7 +15,6 @@ import { copyFilesWithRename, formatMigrationDirName, materialiseExtensionMigrat
|
|
|
14
15
|
import { assertHashIsGraphNode, findLatestMigration, isGraphNode } from "@prisma-next/migration-tools/migration-graph";
|
|
15
16
|
import { emitContractSpaceArtefacts, planAllSpaces, readContractSpaceHeadRef, spaceMigrationDirectory } from "@prisma-next/migration-tools/spaces";
|
|
16
17
|
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
17
|
-
import { readRefSnapshot, readRefs } from "@prisma-next/migration-tools/refs";
|
|
18
18
|
import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
19
19
|
import { computeMigrationHash } from "@prisma-next/migration-tools/hash";
|
|
20
20
|
import { writeMigrationTs } from "@prisma-next/migration-tools/migration-ts";
|
|
@@ -115,8 +115,8 @@ const FULL_HASH_PATTERN = /^sha256:([0-9a-f]{64}|empty)$/;
|
|
|
115
115
|
function looksLikeFullHash(input) {
|
|
116
116
|
return FULL_HASH_PATTERN.test(input);
|
|
117
117
|
}
|
|
118
|
-
function graphIsEmpty(
|
|
119
|
-
return
|
|
118
|
+
function graphIsEmpty(member) {
|
|
119
|
+
return member.packages.length === 0;
|
|
120
120
|
}
|
|
121
121
|
function getReachableRefs(refs, graph) {
|
|
122
122
|
return Object.entries(refs).flatMap(([name, entry]) => entry && isGraphNode(entry.hash, graph) ? [{
|
|
@@ -132,86 +132,70 @@ function assertFromIsGraphNode(fromHash, graph, refs, graphTipHash) {
|
|
|
132
132
|
throw error;
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
-
async function
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
} catch (error) {
|
|
139
|
-
if (CliStructuredError.is(error)) return notOk(error);
|
|
140
|
-
return notOk(errorContractValidationFailed(`Ref snapshot contract failed to deserialize: ${error instanceof Error ? error.message : String(error)}`, { where: { path: "ref-snapshot" } }));
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
async function resolveGraphNodeFromBundle(fromHash, bundles, readBundleEndContract, explicitFromLabel) {
|
|
144
|
-
const matchingBundle = bundles.find((pkg) => pkg.metadata.to === fromHash);
|
|
145
|
-
if (!matchingBundle) return notOk(errorUnexpected(explicitFromLabel ? `No migration bundle found for --from "${explicitFromLabel}" (resolved hash: ${fromHash})` : `No migration bundle found for graph node ${fromHash}`, {
|
|
146
|
-
why: `The hash ${fromHash} is a graph node but no on-disk migration package has an end-contract hash matching it.`,
|
|
147
|
-
fix: "Provide a ref or hash that corresponds to an existing migration package, or run `migration list` to see available migrations."
|
|
148
|
-
}));
|
|
135
|
+
async function resolveContractRef(parsed, member, options) {
|
|
136
|
+
const { hash, provenance } = parsed;
|
|
137
|
+
const refName = provenance.kind === "ref" ? provenance.refName : void 0;
|
|
149
138
|
try {
|
|
139
|
+
const at = await member.contractAt(hash, refName !== void 0 ? { refName } : void 0);
|
|
140
|
+
if (at.provenance === "snapshot") return ok({
|
|
141
|
+
kind: "snapshot",
|
|
142
|
+
hash: at.hash,
|
|
143
|
+
contract: at.contract,
|
|
144
|
+
contractJson: at.contractJson,
|
|
145
|
+
contractDts: at.contractDts
|
|
146
|
+
});
|
|
150
147
|
return ok({
|
|
151
148
|
kind: "graph-node",
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
hash: at.hash,
|
|
150
|
+
contract: at.contract,
|
|
151
|
+
contractJson: at.contractJson,
|
|
152
|
+
contractDts: at.contractDts,
|
|
153
|
+
sourceDir: at.sourceDir
|
|
155
154
|
});
|
|
156
155
|
} catch (error) {
|
|
157
|
-
|
|
158
|
-
throw error;
|
|
156
|
+
return mapContractAtError(error, options?.artifactRole !== void 0 ? { artifactRole: options.artifactRole } : void 0);
|
|
159
157
|
}
|
|
160
158
|
}
|
|
161
|
-
async function
|
|
162
|
-
const
|
|
163
|
-
|
|
159
|
+
async function resolveFromPolicy(parsed, input, refs, explicitFromLabel) {
|
|
160
|
+
const resolution = await resolveContractRef(parsed, input.member, {
|
|
161
|
+
...explicitFromLabel !== void 0 ? { explicitLabel: explicitFromLabel } : {},
|
|
162
|
+
artifactRole: "from"
|
|
163
|
+
});
|
|
164
|
+
if (!resolution.ok) return resolution;
|
|
165
|
+
if (resolution.value.kind === "graph-node") return ok({
|
|
166
|
+
kind: "graph-node",
|
|
167
|
+
fromHash: resolution.value.hash,
|
|
168
|
+
fromContract: resolution.value.contract,
|
|
169
|
+
sourceDir: resolution.value.sourceDir
|
|
170
|
+
});
|
|
171
|
+
const { hash, contract, contractJson, contractDts } = resolution.value;
|
|
172
|
+
if (graphIsEmpty(input.member)) return ok({
|
|
173
|
+
kind: "auto-baseline",
|
|
174
|
+
fromHash: hash,
|
|
175
|
+
fromContract: contract,
|
|
176
|
+
contractDts,
|
|
177
|
+
contractJson
|
|
178
|
+
});
|
|
179
|
+
const graph = input.member.graph();
|
|
164
180
|
const graphTip = findLatestMigration(graph)?.to ?? null;
|
|
165
|
-
let snapshot;
|
|
166
181
|
try {
|
|
167
|
-
|
|
182
|
+
assertFromIsGraphNode(hash, graph, refs, graphTip);
|
|
168
183
|
} catch (error) {
|
|
169
|
-
if (
|
|
184
|
+
if (CliStructuredError.is(error)) return notOk(error);
|
|
170
185
|
throw error;
|
|
171
186
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
fromHash,
|
|
180
|
-
fromContract,
|
|
181
|
-
contractDts,
|
|
182
|
-
contractJson
|
|
183
|
-
});
|
|
184
|
-
try {
|
|
185
|
-
assertFromIsGraphNode(fromHash, graph, refs, graphTip);
|
|
186
|
-
} catch (error) {
|
|
187
|
-
if (CliStructuredError.is(error)) return notOk(error);
|
|
188
|
-
throw error;
|
|
189
|
-
}
|
|
190
|
-
return ok({
|
|
191
|
-
kind: "snapshot",
|
|
192
|
-
fromHash,
|
|
193
|
-
fromContract,
|
|
194
|
-
contractDts,
|
|
195
|
-
contractJson
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
if (isGraphNode(fromHash, graph)) return resolveGraphNodeFromBundle(fromHash, bundles, readBundleEndContract);
|
|
199
|
-
return notOk(errorSnapshotMissing(refName));
|
|
200
|
-
}
|
|
201
|
-
async function resolveFromHashProvenance(fromHash, input, _refs, explicitFromLabel) {
|
|
202
|
-
const { bundles, graph } = input;
|
|
203
|
-
if (isGraphNode(fromHash, graph)) return resolveGraphNodeFromBundle(fromHash, bundles, input.readBundleEndContract, explicitFromLabel);
|
|
204
|
-
throw new Error(`resolveFromHashProvenance: non-graph-node hash ${fromHash} should be refused via looksLikeFullHash before this helper is called`);
|
|
187
|
+
return ok({
|
|
188
|
+
kind: "snapshot",
|
|
189
|
+
fromHash: hash,
|
|
190
|
+
fromContract: contract,
|
|
191
|
+
contractDts,
|
|
192
|
+
contractJson
|
|
193
|
+
});
|
|
205
194
|
}
|
|
206
195
|
async function resolveFromForPlan(input) {
|
|
207
|
-
const { optionsFrom,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
refs = await readRefs(refsDir);
|
|
211
|
-
} catch (error) {
|
|
212
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
213
|
-
throw error;
|
|
214
|
-
}
|
|
196
|
+
const { optionsFrom, member } = input;
|
|
197
|
+
const graph = member.graph();
|
|
198
|
+
const refs = member.refs;
|
|
215
199
|
if (optionsFrom === void 0) {
|
|
216
200
|
const dbRef = refs["db"];
|
|
217
201
|
if (!dbRef) return ok({
|
|
@@ -219,7 +203,13 @@ async function resolveFromForPlan(input) {
|
|
|
219
203
|
fromHash: null,
|
|
220
204
|
fromContract: null
|
|
221
205
|
});
|
|
222
|
-
return
|
|
206
|
+
return resolveFromPolicy({
|
|
207
|
+
hash: dbRef.hash,
|
|
208
|
+
provenance: {
|
|
209
|
+
kind: "ref",
|
|
210
|
+
refName: "db"
|
|
211
|
+
}
|
|
212
|
+
}, input, refs);
|
|
223
213
|
}
|
|
224
214
|
const refResult = parseContractRef(optionsFrom, {
|
|
225
215
|
graph,
|
|
@@ -227,57 +217,39 @@ async function resolveFromForPlan(input) {
|
|
|
227
217
|
});
|
|
228
218
|
if (!refResult.ok) {
|
|
229
219
|
if (looksLikeFullHash(optionsFrom)) {
|
|
230
|
-
const empty = graphIsEmpty(
|
|
220
|
+
const empty = graphIsEmpty(member);
|
|
231
221
|
const graphTip = findLatestMigration(graph)?.to ?? null;
|
|
232
222
|
if (empty) return notOk(errorSnapshotMissing(optionsFrom, { viaRef: false }));
|
|
233
223
|
return notOk(errorPlanForgotTheFlag(optionsFrom, getReachableRefs(refs, graph), graphTip));
|
|
234
224
|
}
|
|
235
225
|
return notOk(mapRefResolutionError(refResult.failure));
|
|
236
226
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
227
|
+
return resolveFromPolicy(refResult.value, input, refs, optionsFrom);
|
|
228
|
+
}
|
|
229
|
+
async function resolveToForPlan(optionsTo, input) {
|
|
230
|
+
const { member } = input;
|
|
231
|
+
const graph = member.graph();
|
|
232
|
+
const refs = member.refs;
|
|
233
|
+
const refResult = parseContractRef(optionsTo, {
|
|
234
|
+
graph,
|
|
235
|
+
refs
|
|
236
|
+
});
|
|
237
|
+
if (!refResult.ok) return notOk(mapRefResolutionError(refResult.failure));
|
|
238
|
+
const resolution = await resolveContractRef(refResult.value, member, {
|
|
239
|
+
explicitLabel: optionsTo,
|
|
240
|
+
artifactRole: "to"
|
|
241
|
+
});
|
|
242
|
+
if (!resolution.ok) return resolution;
|
|
243
|
+
const { hash, contract, contractJson, contractDts } = resolution.value;
|
|
244
|
+
return ok({
|
|
245
|
+
hash,
|
|
246
|
+
contract,
|
|
247
|
+
contractJson,
|
|
248
|
+
contractDts
|
|
249
|
+
});
|
|
240
250
|
}
|
|
241
251
|
//#endregion
|
|
242
252
|
//#region src/commands/migration-plan.ts
|
|
243
|
-
/**
|
|
244
|
-
* Load a predecessor migration's destination contract from its sibling
|
|
245
|
-
* `end-contract.json` on disk and route it through the family's
|
|
246
|
-
* `ContractSerializer` (via `deserializeContract`) so the in-memory shape
|
|
247
|
-
* is the hydrated `Contract` every other caller sees. Bypassing this
|
|
248
|
-
* seam was the root cause of TML-2536: a raw `JSON.parse(...) as Contract`
|
|
249
|
-
* here let polymorphic `storage.types` entries reach the planner without
|
|
250
|
-
* the `kind` discriminator the planner dispatches on.
|
|
251
|
-
*
|
|
252
|
-
* Throws `CliStructuredError` with:
|
|
253
|
-
* - `errorFileNotFound` when the sibling file is missing — the user
|
|
254
|
-
* has likely deleted or never authored the snapshot, and the
|
|
255
|
-
* message names the file and points them at re-emitting from the
|
|
256
|
-
* source.
|
|
257
|
-
* - `errorContractValidationFailed` when the JSON parses but the
|
|
258
|
-
* family deserializer rejects it (legacy untagged shape, structural
|
|
259
|
-
* mismatch, etc.) — the message names the predecessor's path so
|
|
260
|
-
* the operator can locate the bad snapshot.
|
|
261
|
-
*/
|
|
262
|
-
async function readPredecessorEndContract(migrationDir, familyInstance) {
|
|
263
|
-
const path = join(migrationDir, "end-contract.json");
|
|
264
|
-
let raw;
|
|
265
|
-
try {
|
|
266
|
-
raw = await readFile(path, "utf-8");
|
|
267
|
-
} catch (error) {
|
|
268
|
-
if (error instanceof Error && error.code === "ENOENT") throw errorFileNotFound(path, {
|
|
269
|
-
why: `Predecessor migration is missing its destination contract snapshot at ${path}`,
|
|
270
|
-
fix: "Re-emit the predecessor migration (`prisma-next migration plan` from its source) so its sibling `end-contract.json` is restored, then re-run this command."
|
|
271
|
-
});
|
|
272
|
-
throw error;
|
|
273
|
-
}
|
|
274
|
-
try {
|
|
275
|
-
return familyInstance.deserializeContract(JSON.parse(raw));
|
|
276
|
-
} catch (error) {
|
|
277
|
-
if (CliStructuredError.is(error)) throw error;
|
|
278
|
-
throw errorContractValidationFailed(`Predecessor contract at ${path} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`, { where: { path } });
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
253
|
async function writeSnapshotContractArtifacts(packageDir, contractJson, contractDts, artifactBasename) {
|
|
282
254
|
await mkdir(packageDir, { recursive: true });
|
|
283
255
|
const jsonContent = `${canonicalizeJson(contractJson)}\n`;
|
|
@@ -360,6 +332,10 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
360
332
|
label: "from",
|
|
361
333
|
value: options.from
|
|
362
334
|
});
|
|
335
|
+
if (options.to) details.push({
|
|
336
|
+
label: "to",
|
|
337
|
+
value: options.to
|
|
338
|
+
});
|
|
363
339
|
if (options.name) details.push({
|
|
364
340
|
label: "name",
|
|
365
341
|
value: options.name
|
|
@@ -393,54 +369,61 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
393
369
|
}
|
|
394
370
|
const rawStorageHash = toContract.storage?.storageHash;
|
|
395
371
|
if (typeof rawStorageHash !== "string") return notOk(errorContractValidationFailed("Contract is missing storageHash", { where: { path: contractPathAbsolute } }));
|
|
396
|
-
|
|
397
|
-
|
|
372
|
+
let toStorageHash = rawStorageHash;
|
|
373
|
+
let toArtifacts = null;
|
|
398
374
|
let fromContract = null;
|
|
399
375
|
let fromHash = null;
|
|
400
376
|
let fromContractSourceDir = null;
|
|
401
377
|
let snapshotStartContract = null;
|
|
402
378
|
let isAutoBaseline = false;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
379
|
+
const tolerantAggregateResult = await loadContractSpaceAggregateForCli({
|
|
380
|
+
targetId: config.target.targetId,
|
|
381
|
+
migrationsDir,
|
|
382
|
+
appContract: toContract,
|
|
383
|
+
extensionPacks: config.extensionPacks ?? [],
|
|
384
|
+
deserializeContract: (json) => familyInstance.deserializeContract(json)
|
|
385
|
+
});
|
|
386
|
+
if (!tolerantAggregateResult.ok) return notOk(tolerantAggregateResult.failure);
|
|
387
|
+
const resolutionMember = tolerantAggregateResult.value.app;
|
|
388
|
+
const resolutionResult = await resolveFromForPlan({
|
|
389
|
+
optionsFrom: options.from,
|
|
390
|
+
member: resolutionMember
|
|
391
|
+
});
|
|
392
|
+
if (!resolutionResult.ok) return notOk(resolutionResult.failure);
|
|
393
|
+
switch (resolutionResult.value.kind) {
|
|
394
|
+
case "greenfield": break;
|
|
395
|
+
case "graph-node":
|
|
396
|
+
fromHash = resolutionResult.value.fromHash;
|
|
397
|
+
fromContract = resolutionResult.value.fromContract;
|
|
398
|
+
fromContractSourceDir = resolutionResult.value.sourceDir;
|
|
399
|
+
break;
|
|
400
|
+
case "snapshot":
|
|
401
|
+
fromHash = resolutionResult.value.fromHash;
|
|
402
|
+
fromContract = resolutionResult.value.fromContract;
|
|
403
|
+
snapshotStartContract = {
|
|
404
|
+
contractJson: resolutionResult.value.contractJson,
|
|
405
|
+
contractDts: resolutionResult.value.contractDts
|
|
406
|
+
};
|
|
407
|
+
break;
|
|
408
|
+
case "auto-baseline":
|
|
409
|
+
fromHash = resolutionResult.value.fromHash;
|
|
410
|
+
fromContract = resolutionResult.value.fromContract;
|
|
411
|
+
snapshotStartContract = {
|
|
412
|
+
contractJson: resolutionResult.value.contractJson,
|
|
413
|
+
contractDts: resolutionResult.value.contractDts
|
|
414
|
+
};
|
|
415
|
+
isAutoBaseline = true;
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
if (options.to !== void 0) {
|
|
419
|
+
const toResolution = await resolveToForPlan(options.to, { member: resolutionMember });
|
|
420
|
+
if (!toResolution.ok) return notOk(toResolution.failure);
|
|
421
|
+
toContract = toResolution.value.contract;
|
|
422
|
+
toStorageHash = toResolution.value.hash;
|
|
423
|
+
toArtifacts = {
|
|
424
|
+
contractJson: toResolution.value.contractJson,
|
|
425
|
+
contractDts: toResolution.value.contractDts
|
|
426
|
+
};
|
|
444
427
|
}
|
|
445
428
|
const seedResult = await runContractSpaceSeedPhase({
|
|
446
429
|
migrationsDir,
|
|
@@ -482,6 +465,20 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
482
465
|
config.adapter,
|
|
483
466
|
...config.extensionPacks ?? []
|
|
484
467
|
]);
|
|
468
|
+
async function writeDestinationEndContract(packageDir) {
|
|
469
|
+
if (toArtifacts !== null) {
|
|
470
|
+
await writeSnapshotContractArtifacts(packageDir, toArtifacts.contractJson, toArtifacts.contractDts, "end-contract");
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);
|
|
474
|
+
await copyFilesWithRename(packageDir, [{
|
|
475
|
+
sourcePath: destinationArtifacts.jsonPath,
|
|
476
|
+
destName: "end-contract.json"
|
|
477
|
+
}, {
|
|
478
|
+
sourcePath: destinationArtifacts.dtsPath,
|
|
479
|
+
destName: "end-contract.d.ts"
|
|
480
|
+
}]);
|
|
481
|
+
}
|
|
485
482
|
try {
|
|
486
483
|
const planner = migrations.createPlanner(familyInstance);
|
|
487
484
|
if (isAutoBaseline && fromHash !== null && fromContract !== null && snapshotStartContract !== null) {
|
|
@@ -534,14 +531,7 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
534
531
|
const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId);
|
|
535
532
|
if (!deltaLeg.ok) return notOk(deltaLeg.failure);
|
|
536
533
|
await writePlannedMigrationPackage(deltaPackageDir, fromHash, toStorageHash, deltaTimestamp, deltaLeg.value);
|
|
537
|
-
|
|
538
|
-
await copyFilesWithRename(deltaPackageDir, [{
|
|
539
|
-
sourcePath: destinationArtifacts.jsonPath,
|
|
540
|
-
destName: "end-contract.json"
|
|
541
|
-
}, {
|
|
542
|
-
sourcePath: destinationArtifacts.dtsPath,
|
|
543
|
-
destName: "end-contract.d.ts"
|
|
544
|
-
}]);
|
|
534
|
+
await writeDestinationEndContract(deltaPackageDir);
|
|
545
535
|
await writeSnapshotStartContract(deltaPackageDir, snapshotStartContract.contractJson, snapshotStartContract.contractDts);
|
|
546
536
|
const deltaOps = deltaLeg.value.hasPlaceholders ? [] : deltaLeg.value.plannedOps;
|
|
547
537
|
if (deltaLeg.value.hasPlaceholders) return ok({
|
|
@@ -581,14 +571,7 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
581
571
|
const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId);
|
|
582
572
|
if (!deltaLeg.ok) return notOk(deltaLeg.failure);
|
|
583
573
|
await writePlannedMigrationPackage(packageDir, fromHash, toStorageHash, timestamp, deltaLeg.value);
|
|
584
|
-
|
|
585
|
-
await copyFilesWithRename(packageDir, [{
|
|
586
|
-
sourcePath: destinationArtifacts.jsonPath,
|
|
587
|
-
destName: "end-contract.json"
|
|
588
|
-
}, {
|
|
589
|
-
sourcePath: destinationArtifacts.dtsPath,
|
|
590
|
-
destName: "end-contract.d.ts"
|
|
591
|
-
}]);
|
|
574
|
+
await writeDestinationEndContract(packageDir);
|
|
592
575
|
if (fromContractSourceDir !== null) {
|
|
593
576
|
const sourceArtifacts = getEmittedArtifactPaths(join(fromContractSourceDir, "end-contract.json"));
|
|
594
577
|
await copyFilesWithRename(packageDir, [{
|
|
@@ -639,8 +622,12 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
639
622
|
function createMigrationPlanCommand() {
|
|
640
623
|
const command = new Command("plan");
|
|
641
624
|
setCommandDescriptions(command, "Plan a migration from contract changes", "Compares the emitted contract against the latest on-disk migration state and\nproduces a new migration package with the required operations. No database\nconnection is needed — this is a fully offline operation.");
|
|
642
|
-
setCommandExamples(command, [
|
|
643
|
-
|
|
625
|
+
setCommandExamples(command, [
|
|
626
|
+
"prisma-next migration plan",
|
|
627
|
+
"prisma-next migration plan --name add-users-table",
|
|
628
|
+
"prisma-next migration plan --to <migration-dir>^ --name rollback"
|
|
629
|
+
]);
|
|
630
|
+
addGlobalOptions(command).option("--config <path>", "Path to prisma-next.config.ts").option("--name <slug>", "Name slug for the migration directory", "migration").option("--from <contract>", "Starting contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)").option("--to <contract>", "Destination contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path); defaults to the emitted contract").action(async (options) => {
|
|
644
631
|
const flags = parseGlobalFlagsOrExit(options);
|
|
645
632
|
const startTime = Date.now();
|
|
646
633
|
const ui = createTerminalUI(flags);
|
|
@@ -779,4 +766,4 @@ function resolveBundleByPrefix(bundles, needle) {
|
|
|
779
766
|
//#endregion
|
|
780
767
|
export { formatMigrationPlanOutput as n, resolveBundleByPrefix as r, createMigrationPlanCommand as t };
|
|
781
768
|
|
|
782
|
-
//# sourceMappingURL=migration-plan-
|
|
769
|
+
//# sourceMappingURL=migration-plan-Bt6wxUIv.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-plan-Bt6wxUIv.mjs","names":[],"sources":["../src/utils/contract-space-seed-phase.ts","../src/utils/plan-resolution.ts","../src/commands/migration-plan.ts"],"sourcesContent":["import { materialiseExtensionMigrationPackageIfMissing } from '@prisma-next/migration-tools/io';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport type { MigrationOps } from '@prisma-next/migration-tools/package';\nimport {\n emitContractSpaceArtefacts,\n planAllSpaces,\n readContractSpaceHeadRef,\n type SpacePlanOutput,\n spaceMigrationDirectory,\n} from '@prisma-next/migration-tools/spaces';\n\n/**\n * In-memory authored migration package shipped by an extension descriptor.\n * Mirrors `MigrationPackage` from `@prisma-next/migration-tools/io` (the\n * on-disk shape minus `dirPath`); redeclared structurally here so the\n * CLI helper does not couple to any family's `ExtensionMigrationPackage`\n * type — any family that ships pre-built migration packages can pass\n * them through unchanged.\n */\nexport interface DescriptorMigrationPackage {\n readonly dirName: string;\n readonly metadata: MigrationMetadata;\n readonly ops: MigrationOps;\n}\n\n/**\n * Minimal descriptor view consumed by the seed phase. Mirrors the shape\n * the SQL family ships on each declared extension entry; only the fields\n * the seed phase needs are surfaced.\n */\nexport interface SeedPhaseExtensionInput {\n readonly id: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: { readonly hash: string; readonly invariants: readonly string[] };\n readonly migrations: readonly DescriptorMigrationPackage[];\n };\n}\n\nexport interface ContractSpaceSeedPhaseInputs {\n readonly migrationsDir: string;\n readonly extensionPacks: ReadonlyArray<SeedPhaseExtensionInput>;\n}\n\n/**\n * One per-space record describing what the seed phase did for an\n * extension contract space. Surfaced verbatim by the caller (typically\n * `migration plan`) so users see a single line per touched extension.\n *\n * - `action: 'updated'` — either the on-disk head pointer changed, or\n * one or more new descriptor-shipped migration packages were\n * materialised into `migrations/<spaceId>/<dirName>/`.\n * - `action: 'unchanged'` — the on-disk head already matched the\n * descriptor and no new migration packages needed to be written.\n *\n * Either way, the artefacts (`contract.json`, `contract.d.ts`,\n * `refs/head.json`) are re-emitted: the framework owns those files and\n * makes the re-emit observably idempotent at the byte level.\n */\nexport interface ContractSpaceSeedPhaseRecord {\n readonly spaceId: string;\n readonly action: 'updated' | 'unchanged';\n readonly priorHash: string | null;\n readonly newHash: string;\n readonly newMigrationDirs: readonly string[];\n}\n\nexport interface ContractSpaceSeedPhaseResult {\n readonly seeded: readonly ContractSpaceSeedPhaseRecord[];\n}\n\n/**\n * Phase-1 of the two-phase `migration plan` pipeline (sub-spec § 4).\n *\n * For every extension that exposes a `contractSpace`:\n *\n * 1. Read the on-disk head ref (returns `null` on first emit).\n * 2. Re-emit `contract.json` / `contract.d.ts` / `refs/head.json`\n * unconditionally via {@link emitContractSpaceArtefacts}. The\n * framework owns these files; re-emit is the contract.\n * 3. Materialise any descriptor-shipped migration packages not yet on\n * disk via {@link materialiseExtensionMigrationPackageIfMissing}.\n * Existing packages are left untouched (by-existence skip).\n *\n * The return value lets the caller render a per-space status line and\n * lets the phase-2 aggregate loader run on a now-consistent disk state\n * (every loaded extension is guaranteed to have its head ref pinned\n * to the descriptor's hash and to ship every package the descriptor\n * declares).\n *\n * Output ordering is deterministic and alphabetical by spaceId (via\n * {@link planAllSpaces}, which also detects duplicate spaceIds). This\n * matches the canonical sort order used by every other aggregate\n * surface (`migrate`, `migration status`, the runner).\n */\nexport async function runContractSpaceSeedPhase(\n inputs: ContractSpaceSeedPhaseInputs,\n): Promise<ContractSpaceSeedPhaseResult> {\n const planInputs = inputs.extensionPacks\n .filter(\n (\n pack,\n ): pack is SeedPhaseExtensionInput & {\n contractSpace: NonNullable<SeedPhaseExtensionInput['contractSpace']>;\n } => pack.contractSpace !== undefined,\n )\n .map((pack) => ({\n spaceId: pack.id,\n priorContract: null,\n newContract: pack.contractSpace.contractJson,\n __pack: pack.contractSpace,\n }));\n\n // `planAllSpaces` brings deterministic alphabetical ordering and\n // duplicate-spaceId detection. The \"planner\" callback is a no-op\n // pass-through that simply returns the descriptor's pre-built\n // migration packages.\n const planned: readonly SpacePlanOutput<DescriptorMigrationPackage>[] = planAllSpaces(\n planInputs,\n (input) =>\n (\n input as typeof input & {\n readonly __pack: NonNullable<SeedPhaseExtensionInput['contractSpace']>;\n }\n ).__pack.migrations,\n );\n\n // Reassemble a spaceId → descriptor lookup so the loop below can read\n // the contractJson / headRef without leaking the typed-cast back into\n // `planAllSpaces`'s output shape.\n const descriptorBySpace = new Map<\n string,\n NonNullable<SeedPhaseExtensionInput['contractSpace']>\n >();\n for (const pack of inputs.extensionPacks) {\n if (pack.contractSpace !== undefined) descriptorBySpace.set(pack.id, pack.contractSpace);\n }\n\n const seeded: ContractSpaceSeedPhaseRecord[] = [];\n for (const space of planned) {\n const descriptor = descriptorBySpace.get(space.spaceId);\n if (descriptor === undefined) continue;\n\n const onDiskHeadRef = await readContractSpaceHeadRef(inputs.migrationsDir, space.spaceId);\n const priorHash = onDiskHeadRef?.hash ?? null;\n\n await emitContractSpaceArtefacts(inputs.migrationsDir, space.spaceId, {\n contract: descriptor.contractJson,\n contractDts: buildPlaceholderContractDts(space.spaceId),\n headRef: { hash: descriptor.headRef.hash, invariants: descriptor.headRef.invariants },\n });\n\n const spaceDir = spaceMigrationDirectory(inputs.migrationsDir, space.spaceId);\n const newMigrationDirs: string[] = [];\n for (const pkg of space.migrationPackages) {\n const { written } = await materialiseExtensionMigrationPackageIfMissing(spaceDir, pkg);\n if (written) newMigrationDirs.push(pkg.dirName);\n }\n\n const action: ContractSpaceSeedPhaseRecord['action'] =\n priorHash !== descriptor.headRef.hash || newMigrationDirs.length > 0\n ? 'updated'\n : 'unchanged';\n\n seeded.push({\n spaceId: space.spaceId,\n action,\n priorHash,\n newHash: descriptor.headRef.hash,\n newMigrationDirs,\n });\n }\n\n return { seeded };\n}\n\n/**\n * Placeholder `.d.ts` content for an extension space's on-disk mirror.\n *\n * Rendering a fully-typed `.d.ts` for an extension contract requires\n * the SQL-family renderer with the codec / typemap registry threaded\n * through; until that integration ships, the on-disk `.d.ts` is a\n * stub `export {};` module that documents how consumers should\n * validate the sibling `contract.json`. The stub typechecks on its\n * own and does not need any TypeScript suppressions.\n */\nfunction buildPlaceholderContractDts(spaceId: string): string {\n return [\n '/**',\n ` * Placeholder \\`.d.ts\\` for extension space \"${spaceId}\".`,\n ' *',\n ' * The framework re-emits this file on every `migration plan` run',\n ' * alongside `contract.json` and `refs/head.json`. A typed `.d.ts`',\n ' * rendering pass for extension contracts is tracked separately;',\n ' * until that ships, consumers should import `contract.json`',\n ' * and pass it through the target descriptor’s `contractSerializer`.',\n ' */',\n 'export {};',\n '',\n ].join('\\n');\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { ContractSpaceMember } from '@prisma-next/migration-tools/aggregate';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport type { MigrationGraph } from '@prisma-next/migration-tools/graph';\nimport {\n assertHashIsGraphNode,\n findLatestMigration,\n isGraphNode,\n} from '@prisma-next/migration-tools/migration-graph';\nimport type { ContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { Refs } from '@prisma-next/migration-tools/refs';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport {\n CliStructuredError,\n errorPlanForgotTheFlag,\n errorSnapshotMissing,\n mapRefResolutionError,\n} from './cli-errors';\nimport { mapContractAtError } from './contract-at-errors';\n\nconst FULL_HASH_PATTERN = /^sha256:([0-9a-f]{64}|empty)$/;\n\nexport function looksLikeFullHash(input: string): boolean {\n return FULL_HASH_PATTERN.test(input);\n}\n\nexport type FromResolution =\n | { kind: 'greenfield'; fromHash: null; fromContract: null }\n | { kind: 'graph-node'; fromHash: string; fromContract: Contract; sourceDir: string }\n | {\n kind: 'snapshot';\n fromHash: string;\n fromContract: Contract;\n contractDts: string;\n contractJson: unknown;\n }\n | {\n kind: 'auto-baseline';\n fromHash: string;\n fromContract: Contract;\n contractDts: string;\n contractJson: unknown;\n };\n\nexport interface ResolveFromForPlanInput {\n readonly optionsFrom?: string | undefined;\n readonly member: ContractSpaceMember;\n}\n\nfunction graphIsEmpty(member: ContractSpaceMember): boolean {\n return member.packages.length === 0;\n}\n\nfunction getReachableRefs(\n refs: Refs,\n graph: MigrationGraph,\n): ReadonlyArray<{ name: string; hash: string }> {\n return Object.entries(refs)\n .flatMap(([name, entry]) =>\n entry && isGraphNode(entry.hash, graph) ? [{ name, hash: entry.hash }] : [],\n )\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport function assertFromIsGraphNode(\n fromHash: string,\n graph: MigrationGraph,\n refs: Refs,\n graphTipHash: string | null,\n): void {\n try {\n assertHashIsGraphNode(fromHash, graph);\n } catch (error) {\n if (MigrationToolsError.is(error) && error.code === 'MIGRATION.HASH_NOT_IN_GRAPH') {\n throw errorPlanForgotTheFlag(fromHash, getReachableRefs(refs, graph), graphTipHash);\n }\n throw error;\n }\n}\n\ntype RefContractResolution =\n | {\n kind: 'snapshot';\n hash: string;\n contract: Contract;\n contractJson: unknown;\n contractDts: string;\n }\n | {\n kind: 'graph-node';\n hash: string;\n contract: Contract;\n contractJson: unknown;\n contractDts: string;\n sourceDir: string;\n };\n\nasync function resolveContractRef(\n parsed: ContractRef,\n member: ContractSpaceMember,\n options?: { readonly explicitLabel?: string; readonly artifactRole?: 'from' | 'to' },\n): Promise<Result<RefContractResolution, CliStructuredError>> {\n const { hash, provenance } = parsed;\n const refName = provenance.kind === 'ref' ? provenance.refName : undefined;\n\n try {\n const at = await member.contractAt(hash, refName !== undefined ? { refName } : undefined);\n\n if (at.provenance === 'snapshot') {\n return ok({\n kind: 'snapshot',\n hash: at.hash,\n contract: at.contract,\n contractJson: at.contractJson,\n contractDts: at.contractDts,\n });\n }\n\n return ok({\n kind: 'graph-node',\n hash: at.hash,\n contract: at.contract,\n contractJson: at.contractJson,\n contractDts: at.contractDts,\n sourceDir: at.sourceDir,\n });\n } catch (error) {\n return mapContractAtError(\n error,\n options?.artifactRole !== undefined ? { artifactRole: options.artifactRole } : undefined,\n );\n }\n}\n\nasync function resolveFromPolicy(\n parsed: ContractRef,\n input: ResolveFromForPlanInput,\n refs: Refs,\n explicitFromLabel?: string,\n): Promise<Result<FromResolution, CliStructuredError>> {\n const resolution = await resolveContractRef(parsed, input.member, {\n ...(explicitFromLabel !== undefined ? { explicitLabel: explicitFromLabel } : {}),\n artifactRole: 'from',\n });\n if (!resolution.ok) {\n return resolution;\n }\n\n if (resolution.value.kind === 'graph-node') {\n return ok({\n kind: 'graph-node',\n fromHash: resolution.value.hash,\n fromContract: resolution.value.contract,\n sourceDir: resolution.value.sourceDir,\n });\n }\n\n const { hash, contract, contractJson, contractDts } = resolution.value;\n if (graphIsEmpty(input.member)) {\n return ok({\n kind: 'auto-baseline',\n fromHash: hash,\n fromContract: contract,\n contractDts,\n contractJson,\n });\n }\n\n const graph = input.member.graph();\n const graphTip = findLatestMigration(graph)?.to ?? null;\n try {\n assertFromIsGraphNode(hash, graph, refs, graphTip);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n throw error;\n }\n return ok({\n kind: 'snapshot',\n fromHash: hash,\n fromContract: contract,\n contractDts,\n contractJson,\n });\n}\n\nexport async function resolveFromForPlan(\n input: ResolveFromForPlanInput,\n): Promise<Result<FromResolution, CliStructuredError>> {\n const { optionsFrom, member } = input;\n const graph = member.graph();\n const refs = member.refs;\n\n if (optionsFrom === undefined) {\n const dbRef = refs['db'];\n if (!dbRef) {\n return ok({ kind: 'greenfield', fromHash: null, fromContract: null });\n }\n return resolveFromPolicy(\n { hash: dbRef.hash, provenance: { kind: 'ref', refName: 'db' } },\n input,\n refs,\n );\n }\n\n const refResult = parseContractRef(optionsFrom, { graph, refs });\n if (!refResult.ok) {\n if (looksLikeFullHash(optionsFrom)) {\n const empty = graphIsEmpty(member);\n const graphTip = findLatestMigration(graph)?.to ?? null;\n if (empty) {\n return notOk(errorSnapshotMissing(optionsFrom, { viaRef: false }));\n }\n return notOk(errorPlanForgotTheFlag(optionsFrom, getReachableRefs(refs, graph), graphTip));\n }\n return notOk(mapRefResolutionError(refResult.failure));\n }\n\n return resolveFromPolicy(refResult.value, input, refs, optionsFrom);\n}\n\nexport interface ResolveToForPlanInput {\n readonly member: ContractSpaceMember;\n}\n\nexport interface ResolvedContractRef {\n readonly hash: string;\n readonly contract: Contract;\n readonly contractJson: unknown;\n readonly contractDts: string;\n}\n\nexport async function resolveToForPlan(\n optionsTo: string,\n input: ResolveToForPlanInput,\n): Promise<Result<ResolvedContractRef, CliStructuredError>> {\n const { member } = input;\n const graph = member.graph();\n const refs = member.refs;\n\n const refResult = parseContractRef(optionsTo, { graph, refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n\n const resolution = await resolveContractRef(refResult.value, member, {\n explicitLabel: optionsTo,\n artifactRole: 'to',\n });\n if (!resolution.ok) {\n return resolution;\n }\n\n const { hash, contract, contractJson, contractDts } = resolution.value;\n return ok({ hash, contract, contractJson, contractDts });\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport {\n createControlStack,\n hasOperationPreview,\n type MigrationPlanOperation,\n type OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { canonicalizeJson } from '@prisma-next/framework-components/utils';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { computeMigrationHash } from '@prisma-next/migration-tools/hash';\nimport { deriveProvidedInvariants } from '@prisma-next/migration-tools/invariants';\nimport {\n copyFilesWithRename,\n formatMigrationDirName,\n writeMigrationPackage,\n} from '@prisma-next/migration-tools/io';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';\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 {\n type CliErrorConflict,\n CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorMigrationPlanningFailed,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n getTargetMigrations,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport {\n buildContractSpaceAggregate,\n loadContractSpaceAggregateForCli,\n} from '../utils/contract-space-aggregate-loader';\nimport { runContractSpaceSeedPhase } from '../utils/contract-space-seed-phase';\nimport { toExtensionInputs } from '../utils/extension-pack-inputs';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { resolveFromForPlan, resolveToForPlan } from '../utils/plan-resolution';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationPlanOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly name?: string;\n readonly from?: string;\n readonly to?: string;\n}\n\nasync function writeSnapshotContractArtifacts(\n packageDir: string,\n contractJson: unknown,\n contractDts: string,\n artifactBasename: 'start-contract' | 'end-contract',\n): Promise<void> {\n await mkdir(packageDir, { recursive: true });\n const jsonContent = `${canonicalizeJson(contractJson)}\\n`;\n const dtsContent = contractDts.endsWith('\\n') ? contractDts : `${contractDts}\\n`;\n await writeFile(join(packageDir, `${artifactBasename}.json`), jsonContent);\n await writeFile(join(packageDir, `${artifactBasename}.d.ts`), dtsContent);\n}\n\nasync function writeSnapshotStartContract(\n packageDir: string,\n contractJson: unknown,\n contractDts: string,\n): Promise<void> {\n await writeSnapshotContractArtifacts(packageDir, contractJson, contractDts, 'start-contract');\n}\n\ntype PlannerSuccess = {\n readonly plannedOps: readonly MigrationPlanOperation[];\n readonly migrationTsContent: string;\n readonly hasPlaceholders: boolean;\n};\n\ntype TargetMigrationsApi = NonNullable<ReturnType<typeof getTargetMigrations>>;\n\nasync function runPlannerLeg(\n planner: ReturnType<TargetMigrationsApi['createPlanner']>,\n migrations: TargetMigrationsApi,\n frameworkComponents: ReturnType<typeof assertFrameworkComponentsCompatible>,\n contract: Contract,\n fromContract: Contract | null,\n spaceId: string,\n): Promise<Result<PlannerSuccess, CliStructuredError>> {\n const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);\n const plannerResult = planner.plan({\n contract,\n schema: fromSchema,\n policy: { allowedOperationClasses: ['additive', 'widening', 'destructive', 'data'] },\n fromContract,\n frameworkComponents,\n spaceId,\n });\n if (plannerResult.kind === 'failure') {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: plannerResult.conflicts as readonly CliErrorConflict[],\n }),\n );\n }\n\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 return ok({\n plannedOps,\n migrationTsContent: plannerResult.plan.renderTypeScript(),\n hasPlaceholders,\n });\n}\n\nasync function writePlannedMigrationPackage(\n packageDir: string,\n fromHash: string | null,\n toHash: string,\n createdAt: Date,\n leg: PlannerSuccess,\n): Promise<void> {\n const opsForWrite = leg.hasPlaceholders ? [] : leg.plannedOps;\n const metadataWithInvariants: Omit<MigrationMetadata, 'migrationHash'> = {\n from: fromHash,\n to: toHash,\n providedInvariants: deriveProvidedInvariants(opsForWrite),\n createdAt: createdAt.toISOString(),\n };\n const metadata: MigrationMetadata = {\n ...metadataWithInvariants,\n migrationHash: computeMigrationHash(metadataWithInvariants, opsForWrite),\n };\n await writeMigrationPackage(packageDir, metadata, opsForWrite);\n await writeMigrationTs(packageDir, leg.migrationTsContent);\n}\n\nexport interface MigrationPlanResult {\n readonly ok: boolean;\n readonly noOp: boolean;\n readonly from: string | null;\n readonly to: string;\n readonly dir?: string;\n readonly baselineDir?: string;\n /**\n * Extension-space migration packages materialised onto disk during this\n * `plan` run. Each entry names a `migrations/<spaceId>/<dirName>/`\n * tree the framework wrote alongside the app-space migration directory.\n * Empty when the project has no extension packs declaring a contract\n * space, or when every extension-space package is already on disk.\n *\n * Surfacing these in the result (rather than only via `ui.step` log\n * lines) makes the cross-space side effect explicit to JSON consumers\n * and the success-summary renderer — the same multi-space side effect\n * that `migrate` will replay.\n */\n readonly emittedExtensionDirs: readonly { readonly spaceId: string; readonly dirName: string }[];\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the migration plan operations.\n * Replaces the previous `sql?: readonly string[]` field; consumers should\n * read `result.preview?.statements`.\n */\n readonly preview?: OperationPreview;\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\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, appMigrationsDir, appMigrationsRelative } =\n resolveMigrationPaths(options.config, config);\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: appMigrationsRelative },\n ];\n if (options.from) {\n details.push({ label: 'from', value: options.from });\n }\n if (options.to) {\n details.push({ label: 'to', value: options.to });\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 // Construct the family instance up-front so on-disk contract reads cross the\n // serializer seam at the read site, not after the planner has already\n // started dispatching on raw shapes. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let toContract: Contract;\n try {\n toContract = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const rawStorageHash = toContract.storage?.storageHash;\n if (typeof rawStorageHash !== 'string') {\n return notOk(\n errorContractValidationFailed('Contract is missing storageHash', {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n let toStorageHash: string = rawStorageHash;\n\n // When `--to <ref>` resolves a non-default destination, these carry its raw\n // artifacts so the planned package's `end-contract.*` is written from the\n // resolved target rather than copied from the emitted `contract.json`.\n let toArtifacts: { contractJson: unknown; contractDts: string } | null = null;\n\n let fromContract: Contract | null = null;\n let fromHash: string | null = null;\n let fromContractSourceDir: string | null = null;\n let snapshotStartContract: { contractJson: unknown; contractDts: string } | null = null;\n let isAutoBaseline = false;\n\n const tolerantAggregateResult = await loadContractSpaceAggregateForCli({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: toContract,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n if (!tolerantAggregateResult.ok) {\n return notOk(tolerantAggregateResult.failure);\n }\n const resolutionMember = tolerantAggregateResult.value.app;\n\n const resolutionResult = await resolveFromForPlan({\n optionsFrom: options.from,\n member: resolutionMember,\n });\n\n if (!resolutionResult.ok) {\n return notOk(resolutionResult.failure);\n }\n\n switch (resolutionResult.value.kind) {\n case 'greenfield':\n break;\n case 'graph-node':\n fromHash = resolutionResult.value.fromHash;\n fromContract = resolutionResult.value.fromContract;\n fromContractSourceDir = resolutionResult.value.sourceDir;\n break;\n case 'snapshot':\n fromHash = resolutionResult.value.fromHash;\n fromContract = resolutionResult.value.fromContract;\n snapshotStartContract = {\n contractJson: resolutionResult.value.contractJson,\n contractDts: resolutionResult.value.contractDts,\n };\n break;\n case 'auto-baseline':\n fromHash = resolutionResult.value.fromHash;\n fromContract = resolutionResult.value.fromContract;\n snapshotStartContract = {\n contractJson: resolutionResult.value.contractJson,\n contractDts: resolutionResult.value.contractDts,\n };\n isAutoBaseline = true;\n break;\n }\n\n // `--to <ref>` swaps the planner destination to an arbitrary resolved\n // contract (e.g. an ancestor / rollback target). The from-side resolution\n // above is untouched; only the destination + its emitted `end-contract.*`\n // change.\n if (options.to !== undefined) {\n const toResolution = await resolveToForPlan(options.to, {\n member: resolutionMember,\n });\n if (!toResolution.ok) {\n return notOk(toResolution.failure);\n }\n toContract = toResolution.value.contract;\n toStorageHash = toResolution.value.hash;\n toArtifacts = {\n contractJson: toResolution.value.contractJson,\n contractDts: toResolution.value.contractDts,\n };\n }\n\n // Phase 1 — seed: unconditionally re-emit per-space pinned artefacts\n // (contract.json / contract.d.ts / refs/head.json) and materialise any\n // descriptor-shipped migration packages not yet on disk. Runs before\n // the no-op check so that an extension bump alone (with no structural\n // app-space change) still re-pins extension artefacts on disk.\n const canonicalExtensionInputs = toExtensionInputs(config.extensionPacks ?? []);\n const seedResult = await runContractSpaceSeedPhase({\n migrationsDir,\n extensionPacks: canonicalExtensionInputs,\n });\n if (!flags.json && !flags.quiet) {\n for (const record of seedResult.seeded) {\n if (record.action === 'updated') {\n const pkgSuffix =\n record.newMigrationDirs.length > 0\n ? `; ${record.newMigrationDirs.length} new migration package(s) materialised`\n : '';\n ui.step(`Updated ${record.spaceId} to ${record.newHash}${pkgSuffix}`);\n }\n }\n }\n const emittedExtensionDirs = seedResult.seeded.flatMap((r) =>\n r.newMigrationDirs.map((dirName) => ({ spaceId: r.spaceId, dirName })),\n );\n\n // Check for no-op (same hash means no changes). Auto-baseline is exempt:\n // an empty graph with db ref at the current contract still needs a\n // null → fromHash baseline bundle so migrate can anchor the marker.\n if (fromHash === toStorageHash && !isAutoBaseline) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: true,\n from: fromHash,\n to: toStorageHash,\n operations: [],\n emittedExtensionDirs,\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\n // Phase 2 — load: build the aggregate against the now-consistent disk\n // state that phase 1 just seeded. The seed phase guarantees every\n // declared extension has its head ref pinned, so the loader's\n // declaredButUnmigrated precheck always passes here. The app contract\n // was already routed through `familyInstance.deserializeContract` at the\n // read site above (see TML-2536), so it's the hydrated `Contract`\n // here — no second validation pass needed.\n const aggregateResult = await buildContractSpaceAggregate({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: toContract,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n if (!aggregateResult.ok) {\n return notOk(aggregateResult.failure);\n }\n const aggregate = aggregateResult.value;\n\n const frameworkComponents = assertFrameworkComponentsCompatible(\n config.family.familyId,\n config.target.targetId,\n [config.target, config.adapter, ...(config.extensionPacks ?? [])],\n );\n\n // Write the planned package's destination `end-contract.*`. With `--to`, the\n // resolved target's raw artifacts are written; otherwise the emitted\n // `contract.json` / `contract.d.ts` are copied verbatim (today's behaviour).\n async function writeDestinationEndContract(packageDir: string): Promise<void> {\n if (toArtifacts !== null) {\n await writeSnapshotContractArtifacts(\n packageDir,\n toArtifacts.contractJson,\n toArtifacts.contractDts,\n 'end-contract',\n );\n return;\n }\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 }\n\n try {\n const planner = migrations.createPlanner(familyInstance);\n\n if (\n isAutoBaseline &&\n fromHash !== null &&\n fromContract !== null &&\n snapshotStartContract !== null\n ) {\n const baselineTimestamp = new Date();\n const deltaTimestamp = new Date(baselineTimestamp.getTime() + 60_000);\n const baselineDirName = formatMigrationDirName(baselineTimestamp, 'baseline');\n const deltaDirName = formatMigrationDirName(deltaTimestamp, options.name ?? 'migration');\n const baselinePackageDir = join(appMigrationsDir, baselineDirName);\n const deltaPackageDir = join(appMigrationsDir, deltaDirName);\n\n const baselineLeg = await runPlannerLeg(\n planner,\n migrations,\n frameworkComponents,\n fromContract,\n null,\n aggregate.app.spaceId,\n );\n if (!baselineLeg.ok) {\n return notOk(baselineLeg.failure);\n }\n\n await writePlannedMigrationPackage(\n baselinePackageDir,\n null,\n fromHash,\n baselineTimestamp,\n baselineLeg.value,\n );\n await writeSnapshotContractArtifacts(\n baselinePackageDir,\n snapshotStartContract.contractJson,\n snapshotStartContract.contractDts,\n 'end-contract',\n );\n\n if (fromHash === toStorageHash) {\n const baselineOps = baselineLeg.value.hasPlaceholders ? [] : baselineLeg.value.plannedOps;\n if (baselineLeg.value.hasPlaceholders) {\n const baselineDir = relative(process.cwd(), baselinePackageDir);\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: baselineDir,\n baselineDir,\n operations: [],\n emittedExtensionDirs,\n pendingPlaceholders: true,\n summary:\n 'Planned baseline 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 preview = hasOperationPreview(familyInstance)\n ? familyInstance.toOperationPreview(baselineOps)\n : undefined;\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n baselineDir: relative(process.cwd(), baselinePackageDir),\n operations: baselineOps.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n emittedExtensionDirs,\n ...(preview !== undefined ? { preview } : {}),\n summary: buildAutoBaselinePlanSummary(0, emittedExtensionDirs.length),\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const deltaLeg = await runPlannerLeg(\n planner,\n migrations,\n frameworkComponents,\n aggregate.app.contract(),\n fromContract,\n aggregate.app.spaceId,\n );\n if (!deltaLeg.ok) {\n return notOk(deltaLeg.failure);\n }\n\n await writePlannedMigrationPackage(\n deltaPackageDir,\n fromHash,\n toStorageHash,\n deltaTimestamp,\n deltaLeg.value,\n );\n await writeDestinationEndContract(deltaPackageDir);\n await writeSnapshotStartContract(\n deltaPackageDir,\n snapshotStartContract.contractJson,\n snapshotStartContract.contractDts,\n );\n\n const deltaOps = deltaLeg.value.hasPlaceholders ? [] : deltaLeg.value.plannedOps;\n if (deltaLeg.value.hasPlaceholders) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), deltaPackageDir),\n baselineDir: relative(process.cwd(), baselinePackageDir),\n operations: [],\n emittedExtensionDirs,\n pendingPlaceholders: true,\n summary:\n 'Planned baseline + 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 preview = hasOperationPreview(familyInstance)\n ? familyInstance.toOperationPreview(deltaOps)\n : undefined;\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), deltaPackageDir),\n baselineDir: relative(process.cwd(), baselinePackageDir),\n operations: deltaOps.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n emittedExtensionDirs,\n ...(preview !== undefined ? { preview } : {}),\n summary: buildAutoBaselinePlanSummary(deltaOps.length, emittedExtensionDirs.length),\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const timestamp = new Date();\n const slug = options.name ?? 'migration';\n const dirName = formatMigrationDirName(timestamp, slug);\n const packageDir = join(appMigrationsDir, dirName);\n\n const deltaLeg = await runPlannerLeg(\n planner,\n migrations,\n frameworkComponents,\n aggregate.app.contract(),\n fromContract,\n aggregate.app.spaceId,\n );\n if (!deltaLeg.ok) {\n return notOk(deltaLeg.failure);\n }\n\n await writePlannedMigrationPackage(\n packageDir,\n fromHash,\n toStorageHash,\n timestamp,\n deltaLeg.value,\n );\n await writeDestinationEndContract(packageDir);\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 } else if (snapshotStartContract !== null) {\n await writeSnapshotStartContract(\n packageDir,\n snapshotStartContract.contractJson,\n snapshotStartContract.contractDts,\n );\n }\n\n if (deltaLeg.value.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 emittedExtensionDirs,\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 plannedOps = deltaLeg.value.plannedOps;\n const preview = hasOperationPreview(familyInstance)\n ? familyInstance.toOperationPreview(plannedOps)\n : undefined;\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 emittedExtensionDirs,\n ...(preview !== undefined ? { preview } : {}),\n summary: buildPlanSummary(plannedOps.length, emittedExtensionDirs.length),\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n const message = error instanceof Error ? error.message : String(error);\n return notOk(\n errorUnexpected(message, {\n why: `Unexpected error during migration plan: ${message}`,\n }),\n );\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 'prisma-next migration plan --to <migration-dir>^ --name rollback',\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(\n '--from <contract>',\n 'Starting contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .option(\n '--to <contract>',\n 'Destination contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path); defaults to the emitted contract',\n )\n .action(async (options: MigrationPlanOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\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\n/**\n * Compose the success-line summary so the cross-space side effect\n * (extension-space migration packages materialised on disk during\n * this `plan` run) is visible in the top line — not just in the\n * step log above it.\n *\n * Example outputs:\n * - `Planned 3 operation(s)` (app-space-only project)\n * - `Planned 3 operation(s); materialised 1 extension-space migration` (one extension)\n * - `Planned 3 operation(s); materialised 2 extension-space migrations` (two extensions)\n *\n * Locks AC3 at the summary-line level: a reader of the success line\n * can tell that something happened beyond the app space.\n */\nfunction buildPlanSummary(plannedOpsCount: number, emittedExtensionDirsCount: number): string {\n const base = `Planned ${plannedOpsCount} operation(s)`;\n if (emittedExtensionDirsCount === 0) return base;\n const noun =\n emittedExtensionDirsCount === 1 ? 'extension-space migration' : 'extension-space migrations';\n return `${base}; materialised ${emittedExtensionDirsCount} ${noun}`;\n}\n\nfunction buildAutoBaselinePlanSummary(\n deltaOpsCount: number,\n emittedExtensionDirsCount: number,\n): string {\n const base = `Planned baseline + ${deltaOpsCount} operation(s)`;\n if (emittedExtensionDirsCount === 0) return base;\n const noun =\n emittedExtensionDirsCount === 1 ? 'extension-space migration' : 'extension-space migrations';\n return `${base}; materialised ${emittedExtensionDirsCount} ${noun}`;\n}\n\nexport function 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 // Renders the extension-space materialisation block + canonical apply-step\n // hint shared by the no-op, placeholder, and full-plan branches. The app\n // space short-circuits do not skip it: an extension-only bump emits new\n // `migrations/<spaceId>/<dirName>/` directories on disk that the user\n // still has to apply, so the success line must surface them.\n function appendEmittedExtensions(): void {\n if (result.emittedExtensionDirs.length === 0) return;\n lines.push('');\n lines.push(dim_('Emitted extension migrations:'));\n for (const entry of result.emittedExtensionDirs) {\n lines.push(dim_(` ${entry.spaceId} → migrations/${entry.spaceId}/${entry.dirName}`));\n }\n lines.push('');\n lines.push(\n `Next: review the extension migrations above, then run ${green_('prisma-next migrate')}.`,\n );\n }\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 appendEmittedExtensions();\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 appendEmittedExtensions();\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 // operationClass tag is intentionally NOT inlined per spec:\n // a destructive footer warning still surfaces below this list.\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${yellow_('(destructive)')}` : '';\n lines.push(`${dim_(treeChar)}─ ${op.label}${destructiveMarker}`);\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.baselineDir) {\n lines.push(dim_(`Baseline → ${result.baselineDir}`));\n }\n if (result.dir) {\n lines.push(dim_(`App space → ${result.dir}`));\n }\n // Per-space block: surface the extension-space directories materialised\n // alongside the app-space migration. Without this block the cross-space\n // side effect is invisible in the success summary (e2e finding F1).\n for (const entry of result.emittedExtensionDirs) {\n lines.push(\n dim_(`Extension space ${entry.spaceId} → migrations/${entry.spaceId}/${entry.dirName}`),\n );\n }\n\n lines.push('');\n // The \"Next:\" hint always points at the canonical apply path\n // (`prisma-next migrate`) regardless of how many spaces were\n // materialised — `db update` is a dev-time convenience, not the\n // canonical replay step.\n const reviewTarget =\n result.baselineDir !== undefined && result.dir !== undefined\n ? `${result.baselineDir} and ${result.dir}`\n : (result.baselineDir ?? result.dir ?? '<dir>');\n lines.push(\n `Next: review ${green_(reviewTarget)} if needed, then run ${green_('prisma-next migrate')}.`,\n );\n\n if (result.preview && result.preview.statements.length > 0) {\n // The non-empty length is already guaranteed by the surrounding check, so\n // a plain `every` here is equivalent to the helper in formatters/migrations.ts.\n const allSql = result.preview.statements.every((s) => s.language === 'sql');\n lines.push('');\n lines.push(dim_(allSql ? 'DDL preview' : 'Operation preview'));\n lines.push('');\n for (const statement of result.preview.statements) {\n const trimmed = statement.text.trim();\n if (!trimmed) continue;\n const line = statement.language === 'sql' && !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 package by **target contract hash** (`metadata.to`)\n * using exact match or prefix match.\n *\n * Note: matches `metadata.to` (the contract hash this migration produces),\n * not `metadata.migrationHash` (the package's content-addressed identity).\n * Tries exact match first, then prefix match (auto-prepending `sha256:` when\n * the needle omits the scheme). Returns the matched package 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 { metadata: { to: string } }>(\n bundles: readonly T[],\n needle: string,\n): Result<T, PrefixResolutionFailure> {\n const exact = bundles.find((p) => p.metadata.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.metadata.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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-types-
|
|
1
|
+
{"version":3,"file":"migration-types-D2FW63pr.d.mts","names":[],"sources":["../src/utils/migration-types.ts"],"mappings":";UAAiB,SAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,IAAA;EAAA,SACA,QAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA;AAAA"}
|