prisma-next 0.11.0-dev.9 → 0.12.0-dev.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.
- package/dist/cli.mjs +9 -10
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-UnIveZxZ.mjs → client-KgJorIvG.mjs} +72 -60
- package/dist/client-KgJorIvG.mjs.map +1 -0
- package/dist/{command-helpers-CRfjbZRz.mjs → command-helpers-Bbw1GbwL.mjs} +642 -45
- package/dist/command-helpers-Bbw1GbwL.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts.map +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.d.mts.map +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.d.mts.map +1 -1
- package/dist/commands/db-init.mjs +5 -7
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.d.mts.map +1 -1
- package/dist/commands/db-schema.mjs +3 -4
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.d.mts.map +1 -1
- package/dist/commands/db-sign.mjs +12 -10
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +12 -11
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +2 -2
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +68 -69
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +4 -3
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +1 -280
- package/dist/commands/migration-graph.d.mts +13 -2
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +2 -137
- package/dist/commands/migration-list.d.mts +64 -4
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +143 -56
- package/dist/commands/migration-list.mjs.map +1 -1
- package/dist/commands/migration-log.d.mts +10 -1
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +10 -15
- package/dist/commands/migration-log.mjs.map +1 -1
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +32 -38
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +2 -2
- 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 +4 -55
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +61 -153
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +12 -49
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +84 -80
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +10 -8
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/config-loader-B6sJjXTv.mjs.map +1 -1
- package/dist/config-loader.d.mts.map +1 -1
- package/dist/contract-at-errors-BxP-TOMl.mjs +42 -0
- package/dist/contract-at-errors-BxP-TOMl.mjs.map +1 -0
- package/dist/{contract-emit-C6rlsljO.mjs → contract-emit-D-4jrNve.mjs} +21 -7
- package/dist/{contract-emit-C6rlsljO.mjs.map → contract-emit-D-4jrNve.mjs.map} +1 -1
- package/dist/{contract-emit-mqXmapxB.mjs → contract-emit-DxcGl4Uq.mjs} +4 -6
- package/dist/{contract-emit-mqXmapxB.mjs.map → contract-emit-DxcGl4Uq.mjs.map} +1 -1
- package/dist/{contract-enrichment-Dani0mMW.mjs → contract-enrichment-a0V5Y_mL.mjs} +4 -25
- package/dist/contract-enrichment-a0V5Y_mL.mjs.map +1 -0
- package/dist/{contract-infer-C4jxc1aZ.mjs → contract-infer-D8uEbJuu.mjs} +3 -4
- package/dist/{contract-infer-C4jxc1aZ.mjs.map → contract-infer-D8uEbJuu.mjs.map} +1 -1
- package/dist/contract-space-aggregate-loader-DvZwdkrr.mjs +247 -0
- package/dist/contract-space-aggregate-loader-DvZwdkrr.mjs.map +1 -0
- package/dist/{db-verify-1d8tDoFN.mjs → db-verify-v_vUKXTU.mjs} +5 -7
- package/dist/{db-verify-1d8tDoFN.mjs.map → db-verify-v_vUKXTU.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +3 -3
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +3 -3
- package/dist/exports/index.d.mts.map +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/index.mjs.map +1 -1
- package/dist/exports/init-output.d.mts.map +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/extension-pack-inputs-IDvjRCi3.mjs +62 -0
- package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +1 -0
- package/dist/{framework-components-Bexd0f4E.mjs → framework-components-fYXjz_in.mjs} +2 -2
- package/dist/{framework-components-Bexd0f4E.mjs.map → framework-components-fYXjz_in.mjs.map} +1 -1
- package/dist/global-flags-DEHjV8_s.d.mts +34 -0
- package/dist/global-flags-DEHjV8_s.d.mts.map +1 -0
- package/dist/{graph-render-BE8vmJ_7.mjs → graph-render-rFAqZujX.mjs} +2 -2
- package/dist/{graph-render-BE8vmJ_7.mjs.map → graph-render-rFAqZujX.mjs.map} +1 -1
- package/dist/{init-ByoeQphC.mjs → init-Cv9UzWL5.mjs} +17 -19
- package/dist/init-Cv9UzWL5.mjs.map +1 -0
- package/dist/{inspect-live-schema-B1Q49RF0.mjs → inspect-live-schema-C6ohV_oQ.mjs} +4 -5
- package/dist/{inspect-live-schema-B1Q49RF0.mjs.map → inspect-live-schema-C6ohV_oQ.mjs.map} +1 -1
- package/dist/migration-check-BiBJoYYW.mjs +341 -0
- package/dist/migration-check-BiBJoYYW.mjs.map +1 -0
- package/dist/migration-cli.d.mts.map +1 -1
- package/dist/migration-cli.mjs +4 -4
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-oY4P1Qto.mjs → migration-command-scaffold-CjvwO6at.mjs} +4 -5
- package/dist/{migration-command-scaffold-oY4P1Qto.mjs.map → migration-command-scaffold-CjvwO6at.mjs.map} +1 -1
- package/dist/migration-graph-D7DVUElV.mjs +1232 -0
- package/dist/migration-graph-D7DVUElV.mjs.map +1 -0
- package/dist/migration-list-styler-BRwF4-gy.mjs +399 -0
- package/dist/migration-list-styler-BRwF4-gy.mjs.map +1 -0
- package/dist/{migration-plan-jdAHg_gK.mjs → migration-plan-9DJ7q7_z.mjs} +169 -189
- package/dist/migration-plan-9DJ7q7_z.mjs.map +1 -0
- package/dist/{migration-types-BXWvz12q.d.mts → migration-types-D2FW63pr.d.mts} +1 -1
- package/dist/{migration-types-BXWvz12q.d.mts.map → migration-types-D2FW63pr.d.mts.map} +1 -1
- package/dist/{migrations-B7n518mT.mjs → migrations-Cv2jxNNK.mjs} +3 -13
- package/dist/migrations-Cv2jxNNK.mjs.map +1 -0
- package/dist/{output-CUIdfYo5.mjs → output-B60Gw5fu.mjs} +1 -1
- package/dist/{output-CUIdfYo5.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs → progress-adapter-C644QK8l.mjs} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs.map → progress-adapter-C644QK8l.mjs.map} +1 -1
- package/dist/{ref-advancement-DRh5Nquq.mjs → ref-advancement-DUZqsue6.mjs} +1 -1
- package/dist/{ref-advancement-DRh5Nquq.mjs.map → ref-advancement-DUZqsue6.mjs.map} +1 -1
- package/dist/terminal-ui-5Y6mrg93.d.mts +133 -0
- package/dist/terminal-ui-5Y6mrg93.d.mts.map +1 -0
- package/dist/{types-UWB2-rrw.d.mts → types-Dt_SfqFm.d.mts} +18 -26
- package/dist/types-Dt_SfqFm.d.mts.map +1 -0
- package/dist/{verify-C5UvbrF1.mjs → verify-DCA9Sldu.mjs} +2 -2
- package/dist/{verify-C5UvbrF1.mjs.map → verify-DCA9Sldu.mjs.map} +1 -1
- package/package.json +27 -16
- package/dist/cli-errors-Bw2GlweY.mjs +0 -175
- package/dist/cli-errors-Bw2GlweY.mjs.map +0 -1
- package/dist/client-UnIveZxZ.mjs.map +0 -1
- package/dist/command-helpers-CRfjbZRz.mjs.map +0 -1
- package/dist/commands/migration-check.mjs.map +0 -1
- package/dist/commands/migration-graph.mjs.map +0 -1
- package/dist/contract-enrichment-Dani0mMW.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-CGakRlKM.mjs +0 -160
- package/dist/contract-space-aggregate-loader-CGakRlKM.mjs.map +0 -1
- package/dist/global-flags-CdE7M0d9.d.mts +0 -15
- package/dist/global-flags-CdE7M0d9.d.mts.map +0 -1
- package/dist/init-ByoeQphC.mjs.map +0 -1
- package/dist/migration-plan-jdAHg_gK.mjs.map +0 -1
- package/dist/migrations-B7n518mT.mjs.map +0 -1
- package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
- package/dist/terminal-ui-BiB_8KNo.mjs +0 -379
- package/dist/terminal-ui-BiB_8KNo.mjs.map +0 -1
- package/dist/types-UWB2-rrw.d.mts.map +0 -1
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as assertFrameworkComponentsCompatible } from "./framework-components-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { $ as errorTargetMigrationNotSupported, A as CliStructuredError, G as errorPlanForgotTheFlag, P as errorContractValidationFailed, R as errorFileNotFound, T as formatStyledHeader, U as errorMigrationPlanningFailed, Z as errorSnapshotMissing, _ as createTerminalUI, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, nt as mapMigrationToolsError, o as resolveContractPath, r as getTargetMigrations, rt as mapRefResolutionError, s as resolveMigrationPaths, t as addGlobalOptions, tt as errorUnexpected, u as setCommandExamples, y as handleResult } from "./command-helpers-Bbw1GbwL.mjs";
|
|
3
|
+
import { t as assertFrameworkComponentsCompatible } from "./framework-components-fYXjz_in.mjs";
|
|
4
|
+
import { n as toExtensionInputs } from "./extension-pack-inputs-IDvjRCi3.mjs";
|
|
5
|
+
import { a as loadContractSpaceAggregateForCli, n as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-DvZwdkrr.mjs";
|
|
6
|
+
import { t as mapContractAtError } from "./contract-at-errors-BxP-TOMl.mjs";
|
|
7
7
|
import { Command } from "commander";
|
|
8
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 { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
12
12
|
import { createControlStack, hasOperationPreview } from "@prisma-next/framework-components/control";
|
|
13
|
-
import { copyFilesWithRename, formatMigrationDirName, materialiseExtensionMigrationPackageIfMissing, writeMigrationPackage } from "@prisma-next/migration-tools/io";
|
|
14
|
-
import { assertHashIsGraphNode, findLatestMigration, isGraphNode } from "@prisma-next/migration-tools/migration-graph";
|
|
15
13
|
import { emitContractSpaceArtefacts, planAllSpaces, readContractSpaceHeadRef, spaceMigrationDirectory } from "@prisma-next/migration-tools/spaces";
|
|
16
14
|
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
17
|
-
import {
|
|
15
|
+
import { assertHashIsGraphNode, findLatestMigration, isGraphNode } from "@prisma-next/migration-tools/migration-graph";
|
|
18
16
|
import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
19
17
|
import { computeMigrationHash } from "@prisma-next/migration-tools/hash";
|
|
18
|
+
import { copyFilesWithRename, formatMigrationDirName, materialiseExtensionMigrationPackageIfMissing, writeMigrationPackage } from "@prisma-next/migration-tools/io";
|
|
20
19
|
import { writeMigrationTs } from "@prisma-next/migration-tools/migration-ts";
|
|
21
20
|
import { canonicalizeJson } from "@prisma-next/framework-components/utils";
|
|
22
21
|
import { deriveProvidedInvariants } from "@prisma-next/migration-tools/invariants";
|
|
@@ -115,8 +114,8 @@ const FULL_HASH_PATTERN = /^sha256:([0-9a-f]{64}|empty)$/;
|
|
|
115
114
|
function looksLikeFullHash(input) {
|
|
116
115
|
return FULL_HASH_PATTERN.test(input);
|
|
117
116
|
}
|
|
118
|
-
function graphIsEmpty(
|
|
119
|
-
return
|
|
117
|
+
function graphIsEmpty(member) {
|
|
118
|
+
return member.packages.length === 0;
|
|
120
119
|
}
|
|
121
120
|
function getReachableRefs(refs, graph) {
|
|
122
121
|
return Object.entries(refs).flatMap(([name, entry]) => entry && isGraphNode(entry.hash, graph) ? [{
|
|
@@ -132,86 +131,70 @@ function assertFromIsGraphNode(fromHash, graph, refs, graphTipHash) {
|
|
|
132
131
|
throw error;
|
|
133
132
|
}
|
|
134
133
|
}
|
|
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
|
-
}));
|
|
134
|
+
async function resolveContractRef(parsed, member, options) {
|
|
135
|
+
const { hash, provenance } = parsed;
|
|
136
|
+
const refName = provenance.kind === "ref" ? provenance.refName : void 0;
|
|
149
137
|
try {
|
|
138
|
+
const at = await member.contractAt(hash, refName !== void 0 ? { refName } : void 0);
|
|
139
|
+
if (at.provenance === "snapshot") return ok({
|
|
140
|
+
kind: "snapshot",
|
|
141
|
+
hash: at.hash,
|
|
142
|
+
contract: at.contract,
|
|
143
|
+
contractJson: at.contractJson,
|
|
144
|
+
contractDts: at.contractDts
|
|
145
|
+
});
|
|
150
146
|
return ok({
|
|
151
147
|
kind: "graph-node",
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
hash: at.hash,
|
|
149
|
+
contract: at.contract,
|
|
150
|
+
contractJson: at.contractJson,
|
|
151
|
+
contractDts: at.contractDts,
|
|
152
|
+
sourceDir: at.sourceDir
|
|
155
153
|
});
|
|
156
154
|
} catch (error) {
|
|
157
|
-
|
|
158
|
-
throw error;
|
|
155
|
+
return mapContractAtError(error, options?.artifactRole !== void 0 ? { artifactRole: options.artifactRole } : void 0);
|
|
159
156
|
}
|
|
160
157
|
}
|
|
161
|
-
async function
|
|
162
|
-
const
|
|
163
|
-
|
|
158
|
+
async function resolveFromPolicy(parsed, input, refs, explicitFromLabel) {
|
|
159
|
+
const resolution = await resolveContractRef(parsed, input.member, {
|
|
160
|
+
...explicitFromLabel !== void 0 ? { explicitLabel: explicitFromLabel } : {},
|
|
161
|
+
artifactRole: "from"
|
|
162
|
+
});
|
|
163
|
+
if (!resolution.ok) return resolution;
|
|
164
|
+
if (resolution.value.kind === "graph-node") return ok({
|
|
165
|
+
kind: "graph-node",
|
|
166
|
+
fromHash: resolution.value.hash,
|
|
167
|
+
fromContract: resolution.value.contract,
|
|
168
|
+
sourceDir: resolution.value.sourceDir
|
|
169
|
+
});
|
|
170
|
+
const { hash, contract, contractJson, contractDts } = resolution.value;
|
|
171
|
+
if (graphIsEmpty(input.member)) return ok({
|
|
172
|
+
kind: "auto-baseline",
|
|
173
|
+
fromHash: hash,
|
|
174
|
+
fromContract: contract,
|
|
175
|
+
contractDts,
|
|
176
|
+
contractJson
|
|
177
|
+
});
|
|
178
|
+
const graph = input.member.graph();
|
|
164
179
|
const graphTip = findLatestMigration(graph)?.to ?? null;
|
|
165
|
-
let snapshot;
|
|
166
180
|
try {
|
|
167
|
-
|
|
181
|
+
assertFromIsGraphNode(hash, graph, refs, graphTip);
|
|
168
182
|
} catch (error) {
|
|
169
|
-
if (
|
|
183
|
+
if (CliStructuredError.is(error)) return notOk(error);
|
|
170
184
|
throw error;
|
|
171
185
|
}
|
|
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`);
|
|
186
|
+
return ok({
|
|
187
|
+
kind: "snapshot",
|
|
188
|
+
fromHash: hash,
|
|
189
|
+
fromContract: contract,
|
|
190
|
+
contractDts,
|
|
191
|
+
contractJson
|
|
192
|
+
});
|
|
205
193
|
}
|
|
206
194
|
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
|
-
}
|
|
195
|
+
const { optionsFrom, member } = input;
|
|
196
|
+
const graph = member.graph();
|
|
197
|
+
const refs = member.refs;
|
|
215
198
|
if (optionsFrom === void 0) {
|
|
216
199
|
const dbRef = refs["db"];
|
|
217
200
|
if (!dbRef) return ok({
|
|
@@ -219,7 +202,13 @@ async function resolveFromForPlan(input) {
|
|
|
219
202
|
fromHash: null,
|
|
220
203
|
fromContract: null
|
|
221
204
|
});
|
|
222
|
-
return
|
|
205
|
+
return resolveFromPolicy({
|
|
206
|
+
hash: dbRef.hash,
|
|
207
|
+
provenance: {
|
|
208
|
+
kind: "ref",
|
|
209
|
+
refName: "db"
|
|
210
|
+
}
|
|
211
|
+
}, input, refs);
|
|
223
212
|
}
|
|
224
213
|
const refResult = parseContractRef(optionsFrom, {
|
|
225
214
|
graph,
|
|
@@ -227,57 +216,39 @@ async function resolveFromForPlan(input) {
|
|
|
227
216
|
});
|
|
228
217
|
if (!refResult.ok) {
|
|
229
218
|
if (looksLikeFullHash(optionsFrom)) {
|
|
230
|
-
const empty = graphIsEmpty(
|
|
219
|
+
const empty = graphIsEmpty(member);
|
|
231
220
|
const graphTip = findLatestMigration(graph)?.to ?? null;
|
|
232
221
|
if (empty) return notOk(errorSnapshotMissing(optionsFrom, { viaRef: false }));
|
|
233
222
|
return notOk(errorPlanForgotTheFlag(optionsFrom, getReachableRefs(refs, graph), graphTip));
|
|
234
223
|
}
|
|
235
224
|
return notOk(mapRefResolutionError(refResult.failure));
|
|
236
225
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
226
|
+
return resolveFromPolicy(refResult.value, input, refs, optionsFrom);
|
|
227
|
+
}
|
|
228
|
+
async function resolveToForPlan(optionsTo, input) {
|
|
229
|
+
const { member } = input;
|
|
230
|
+
const graph = member.graph();
|
|
231
|
+
const refs = member.refs;
|
|
232
|
+
const refResult = parseContractRef(optionsTo, {
|
|
233
|
+
graph,
|
|
234
|
+
refs
|
|
235
|
+
});
|
|
236
|
+
if (!refResult.ok) return notOk(mapRefResolutionError(refResult.failure));
|
|
237
|
+
const resolution = await resolveContractRef(refResult.value, member, {
|
|
238
|
+
explicitLabel: optionsTo,
|
|
239
|
+
artifactRole: "to"
|
|
240
|
+
});
|
|
241
|
+
if (!resolution.ok) return resolution;
|
|
242
|
+
const { hash, contract, contractJson, contractDts } = resolution.value;
|
|
243
|
+
return ok({
|
|
244
|
+
hash,
|
|
245
|
+
contract,
|
|
246
|
+
contractJson,
|
|
247
|
+
contractDts
|
|
248
|
+
});
|
|
240
249
|
}
|
|
241
250
|
//#endregion
|
|
242
251
|
//#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
252
|
async function writeSnapshotContractArtifacts(packageDir, contractJson, contractDts, artifactBasename) {
|
|
282
253
|
await mkdir(packageDir, { recursive: true });
|
|
283
254
|
const jsonContent = `${canonicalizeJson(contractJson)}\n`;
|
|
@@ -327,12 +298,6 @@ async function writePlannedMigrationPackage(packageDir, fromHash, toHash, create
|
|
|
327
298
|
const metadataWithInvariants = {
|
|
328
299
|
from: fromHash,
|
|
329
300
|
to: toHash,
|
|
330
|
-
hints: {
|
|
331
|
-
used: [],
|
|
332
|
-
applied: [],
|
|
333
|
-
plannerVersion: "2.0.0"
|
|
334
|
-
},
|
|
335
|
-
labels: [],
|
|
336
301
|
providedInvariants: deriveProvidedInvariants(opsForWrite),
|
|
337
302
|
createdAt: createdAt.toISOString()
|
|
338
303
|
};
|
|
@@ -366,6 +331,10 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
366
331
|
label: "from",
|
|
367
332
|
value: options.from
|
|
368
333
|
});
|
|
334
|
+
if (options.to) details.push({
|
|
335
|
+
label: "to",
|
|
336
|
+
value: options.to
|
|
337
|
+
});
|
|
369
338
|
if (options.name) details.push({
|
|
370
339
|
label: "name",
|
|
371
340
|
value: options.name
|
|
@@ -399,54 +368,61 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
399
368
|
}
|
|
400
369
|
const rawStorageHash = toContract.storage?.storageHash;
|
|
401
370
|
if (typeof rawStorageHash !== "string") return notOk(errorContractValidationFailed("Contract is missing storageHash", { where: { path: contractPathAbsolute } }));
|
|
402
|
-
|
|
403
|
-
|
|
371
|
+
let toStorageHash = rawStorageHash;
|
|
372
|
+
let toArtifacts = null;
|
|
404
373
|
let fromContract = null;
|
|
405
374
|
let fromHash = null;
|
|
406
375
|
let fromContractSourceDir = null;
|
|
407
376
|
let snapshotStartContract = null;
|
|
408
377
|
let isAutoBaseline = false;
|
|
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
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
378
|
+
const tolerantAggregateResult = await loadContractSpaceAggregateForCli({
|
|
379
|
+
targetId: config.target.targetId,
|
|
380
|
+
migrationsDir,
|
|
381
|
+
appContract: toContract,
|
|
382
|
+
extensionPacks: config.extensionPacks ?? [],
|
|
383
|
+
deserializeContract: (json) => familyInstance.deserializeContract(json)
|
|
384
|
+
});
|
|
385
|
+
if (!tolerantAggregateResult.ok) return notOk(tolerantAggregateResult.failure);
|
|
386
|
+
const resolutionMember = tolerantAggregateResult.value.app;
|
|
387
|
+
const resolutionResult = await resolveFromForPlan({
|
|
388
|
+
optionsFrom: options.from,
|
|
389
|
+
member: resolutionMember
|
|
390
|
+
});
|
|
391
|
+
if (!resolutionResult.ok) return notOk(resolutionResult.failure);
|
|
392
|
+
switch (resolutionResult.value.kind) {
|
|
393
|
+
case "greenfield": break;
|
|
394
|
+
case "graph-node":
|
|
395
|
+
fromHash = resolutionResult.value.fromHash;
|
|
396
|
+
fromContract = resolutionResult.value.fromContract;
|
|
397
|
+
fromContractSourceDir = resolutionResult.value.sourceDir;
|
|
398
|
+
break;
|
|
399
|
+
case "snapshot":
|
|
400
|
+
fromHash = resolutionResult.value.fromHash;
|
|
401
|
+
fromContract = resolutionResult.value.fromContract;
|
|
402
|
+
snapshotStartContract = {
|
|
403
|
+
contractJson: resolutionResult.value.contractJson,
|
|
404
|
+
contractDts: resolutionResult.value.contractDts
|
|
405
|
+
};
|
|
406
|
+
break;
|
|
407
|
+
case "auto-baseline":
|
|
408
|
+
fromHash = resolutionResult.value.fromHash;
|
|
409
|
+
fromContract = resolutionResult.value.fromContract;
|
|
410
|
+
snapshotStartContract = {
|
|
411
|
+
contractJson: resolutionResult.value.contractJson,
|
|
412
|
+
contractDts: resolutionResult.value.contractDts
|
|
413
|
+
};
|
|
414
|
+
isAutoBaseline = true;
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
if (options.to !== void 0) {
|
|
418
|
+
const toResolution = await resolveToForPlan(options.to, { member: resolutionMember });
|
|
419
|
+
if (!toResolution.ok) return notOk(toResolution.failure);
|
|
420
|
+
toContract = toResolution.value.contract;
|
|
421
|
+
toStorageHash = toResolution.value.hash;
|
|
422
|
+
toArtifacts = {
|
|
423
|
+
contractJson: toResolution.value.contractJson,
|
|
424
|
+
contractDts: toResolution.value.contractDts
|
|
425
|
+
};
|
|
450
426
|
}
|
|
451
427
|
const seedResult = await runContractSpaceSeedPhase({
|
|
452
428
|
migrationsDir,
|
|
@@ -488,6 +464,20 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
488
464
|
config.adapter,
|
|
489
465
|
...config.extensionPacks ?? []
|
|
490
466
|
]);
|
|
467
|
+
async function writeDestinationEndContract(packageDir) {
|
|
468
|
+
if (toArtifacts !== null) {
|
|
469
|
+
await writeSnapshotContractArtifacts(packageDir, toArtifacts.contractJson, toArtifacts.contractDts, "end-contract");
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);
|
|
473
|
+
await copyFilesWithRename(packageDir, [{
|
|
474
|
+
sourcePath: destinationArtifacts.jsonPath,
|
|
475
|
+
destName: "end-contract.json"
|
|
476
|
+
}, {
|
|
477
|
+
sourcePath: destinationArtifacts.dtsPath,
|
|
478
|
+
destName: "end-contract.d.ts"
|
|
479
|
+
}]);
|
|
480
|
+
}
|
|
491
481
|
try {
|
|
492
482
|
const planner = migrations.createPlanner(familyInstance);
|
|
493
483
|
if (isAutoBaseline && fromHash !== null && fromContract !== null && snapshotStartContract !== null) {
|
|
@@ -537,17 +527,10 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
537
527
|
timings: { total: Date.now() - startTime }
|
|
538
528
|
});
|
|
539
529
|
}
|
|
540
|
-
const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract, fromContract, aggregate.app.spaceId);
|
|
530
|
+
const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId);
|
|
541
531
|
if (!deltaLeg.ok) return notOk(deltaLeg.failure);
|
|
542
532
|
await writePlannedMigrationPackage(deltaPackageDir, fromHash, toStorageHash, deltaTimestamp, deltaLeg.value);
|
|
543
|
-
|
|
544
|
-
await copyFilesWithRename(deltaPackageDir, [{
|
|
545
|
-
sourcePath: destinationArtifacts.jsonPath,
|
|
546
|
-
destName: "end-contract.json"
|
|
547
|
-
}, {
|
|
548
|
-
sourcePath: destinationArtifacts.dtsPath,
|
|
549
|
-
destName: "end-contract.d.ts"
|
|
550
|
-
}]);
|
|
533
|
+
await writeDestinationEndContract(deltaPackageDir);
|
|
551
534
|
await writeSnapshotStartContract(deltaPackageDir, snapshotStartContract.contractJson, snapshotStartContract.contractDts);
|
|
552
535
|
const deltaOps = deltaLeg.value.hasPlaceholders ? [] : deltaLeg.value.plannedOps;
|
|
553
536
|
if (deltaLeg.value.hasPlaceholders) return ok({
|
|
@@ -584,17 +567,10 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
584
567
|
}
|
|
585
568
|
const timestamp = /* @__PURE__ */ new Date();
|
|
586
569
|
const packageDir = join(appMigrationsDir, formatMigrationDirName(timestamp, options.name ?? "migration"));
|
|
587
|
-
const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract, fromContract, aggregate.app.spaceId);
|
|
570
|
+
const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId);
|
|
588
571
|
if (!deltaLeg.ok) return notOk(deltaLeg.failure);
|
|
589
572
|
await writePlannedMigrationPackage(packageDir, fromHash, toStorageHash, timestamp, deltaLeg.value);
|
|
590
|
-
|
|
591
|
-
await copyFilesWithRename(packageDir, [{
|
|
592
|
-
sourcePath: destinationArtifacts.jsonPath,
|
|
593
|
-
destName: "end-contract.json"
|
|
594
|
-
}, {
|
|
595
|
-
sourcePath: destinationArtifacts.dtsPath,
|
|
596
|
-
destName: "end-contract.d.ts"
|
|
597
|
-
}]);
|
|
573
|
+
await writeDestinationEndContract(packageDir);
|
|
598
574
|
if (fromContractSourceDir !== null) {
|
|
599
575
|
const sourceArtifacts = getEmittedArtifactPaths(join(fromContractSourceDir, "end-contract.json"));
|
|
600
576
|
await copyFilesWithRename(packageDir, [{
|
|
@@ -645,8 +621,12 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
645
621
|
function createMigrationPlanCommand() {
|
|
646
622
|
const command = new Command("plan");
|
|
647
623
|
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.");
|
|
648
|
-
setCommandExamples(command, [
|
|
649
|
-
|
|
624
|
+
setCommandExamples(command, [
|
|
625
|
+
"prisma-next migration plan",
|
|
626
|
+
"prisma-next migration plan --name add-users-table",
|
|
627
|
+
"prisma-next migration plan --to <migration-dir>^ --name rollback"
|
|
628
|
+
]);
|
|
629
|
+
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) => {
|
|
650
630
|
const flags = parseGlobalFlagsOrExit(options);
|
|
651
631
|
const startTime = Date.now();
|
|
652
632
|
const ui = createTerminalUI(flags);
|
|
@@ -785,4 +765,4 @@ function resolveBundleByPrefix(bundles, needle) {
|
|
|
785
765
|
//#endregion
|
|
786
766
|
export { formatMigrationPlanOutput as n, resolveBundleByPrefix as r, createMigrationPlanCommand as t };
|
|
787
767
|
|
|
788
|
-
//# sourceMappingURL=migration-plan-
|
|
768
|
+
//# sourceMappingURL=migration-plan-9DJ7q7_z.mjs.map
|