prisma-next 0.11.0-dev.5 → 0.11.0-dev.51
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 +215 -0
- package/dist/cli-errors-DFF1LlfU.mjs.map +1 -0
- package/dist/cli.mjs +9 -10
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-oXO2WCPD.mjs → client-5uvDppD8.mjs} +23 -21
- package/dist/client-5uvDppD8.mjs.map +1 -0
- package/dist/{command-helpers-DtavI0wJ.mjs → command-helpers-4UNsRRc4.mjs} +427 -9
- package/dist/command-helpers-4UNsRRc4.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 +33 -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 +6 -7
- 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 +36 -8
- 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 +5 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +79 -39
- 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 +1 -1
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +3 -4
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.d.mts +63 -12
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +2 -103
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +3 -4
- 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 +33 -38
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +2 -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 +4 -55
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +62 -153
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +5 -40
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +93 -67
- 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 +34 -9
- 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-emit-o-8VmdQX.mjs → contract-emit-C-CFGZsI.mjs} +9 -6
- package/dist/{contract-emit-o-8VmdQX.mjs.map → contract-emit-C-CFGZsI.mjs.map} +1 -1
- package/dist/{contract-emit-CmsklifJ.mjs → contract-emit-CuUzzM46.mjs} +5 -6
- package/dist/{contract-emit-CmsklifJ.mjs.map → contract-emit-CuUzzM46.mjs.map} +1 -1
- package/dist/{contract-enrichment-Dani0mMW.mjs → contract-enrichment-XmUPhmsS.mjs} +4 -25
- package/dist/contract-enrichment-XmUPhmsS.mjs.map +1 -0
- package/dist/{contract-infer-pKkiCt7C.mjs → contract-infer-C98ZaRhp.mjs} +3 -4
- package/dist/{contract-infer-pKkiCt7C.mjs.map → contract-infer-C98ZaRhp.mjs.map} +1 -1
- package/dist/contract-space-aggregate-loader-CVHGuA35.mjs +170 -0
- package/dist/contract-space-aggregate-loader-CVHGuA35.mjs.map +1 -0
- package/dist/{db-verify-AoIUriL4.mjs → db-verify-BWl1Yxi-.mjs} +6 -7
- package/dist/{db-verify-AoIUriL4.mjs.map → db-verify-BWl1Yxi-.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- 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-BiY86HbQ.mjs +62 -0
- package/dist/extension-pack-inputs-BiY86HbQ.mjs.map +1 -0
- package/dist/{framework-components-65gOHkHB.mjs → framework-components-DTcjouhS.mjs} +2 -2
- package/dist/{framework-components-65gOHkHB.mjs.map → framework-components-DTcjouhS.mjs.map} +1 -1
- package/dist/{global-flags-CdE7M0d9.d.mts → global-flags-DWsQ6SSI.d.mts} +1 -1
- package/dist/global-flags-DWsQ6SSI.d.mts.map +1 -0
- package/dist/glyph-mode-CBB4emzO.d.mts +5 -0
- package/dist/glyph-mode-CBB4emzO.d.mts.map +1 -0
- package/dist/{graph-render-DJVv0_uf.mjs → graph-render-D2FnLpuK.mjs} +1 -1
- package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-D2FnLpuK.mjs.map} +1 -1
- package/dist/{init-Db5Itt5r.mjs → init-C7PvN163.mjs} +5 -5
- package/dist/{init-Db5Itt5r.mjs.map → init-C7PvN163.mjs.map} +1 -1
- package/dist/{inspect-live-schema-LeWvkZVz.mjs → inspect-live-schema-BRCWQ-Sr.mjs} +5 -5
- package/dist/{inspect-live-schema-LeWvkZVz.mjs.map → inspect-live-schema-BRCWQ-Sr.mjs.map} +1 -1
- package/dist/migration-check-DoskM1nB.mjs +341 -0
- package/dist/migration-check-DoskM1nB.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-BtkunvFQ.mjs → migration-command-scaffold-CXLkoIJx.mjs} +5 -5
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs.map → migration-command-scaffold-CXLkoIJx.mjs.map} +1 -1
- package/dist/migration-list-B2-iQ5Jd.mjs +646 -0
- package/dist/migration-list-B2-iQ5Jd.mjs.map +1 -0
- package/dist/{migration-plan-C2jeH1J5.mjs → migration-plan-BqmIKQpZ.mjs} +341 -88
- package/dist/migration-plan-BqmIKQpZ.mjs.map +1 -0
- package/dist/{migration-types-BXWvz12q.d.mts → migration-types-q64xAI_J.d.mts} +1 -1
- package/dist/{migration-types-BXWvz12q.d.mts.map → migration-types-q64xAI_J.d.mts.map} +1 -1
- package/dist/{migrations-CwZMa1Ck.mjs → migrations-BcVTutso.mjs} +12 -13
- package/dist/migrations-BcVTutso.mjs.map +1 -0
- package/dist/{output-BlsrGMEF.mjs → output-B60Gw5fu.mjs} +1 -1
- package/dist/{output-BlsrGMEF.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs → progress-adapter-xASh41wr.mjs} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs.map → progress-adapter-xASh41wr.mjs.map} +1 -1
- package/dist/ref-advancement-DRh5Nquq.mjs +50 -0
- package/dist/ref-advancement-DRh5Nquq.mjs.map +1 -0
- package/dist/{types-C9FfXb1l.d.mts → types-CEtm6v6a.d.mts} +5 -11
- package/dist/types-CEtm6v6a.d.mts.map +1 -0
- package/dist/{verify-Bom75OYI.mjs → verify-DOHbbrub.mjs} +2 -2
- package/dist/{verify-Bom75OYI.mjs.map → verify-DOHbbrub.mjs.map} +1 -1
- package/package.json +12 -12
- package/dist/cli-errors-Czmx92Zy.d.mts +0 -3
- package/dist/cli-errors-Djtz98Vm.mjs +0 -71
- package/dist/cli-errors-Djtz98Vm.mjs.map +0 -1
- package/dist/client-oXO2WCPD.mjs.map +0 -1
- package/dist/command-helpers-DtavI0wJ.mjs.map +0 -1
- package/dist/commands/migration-check.mjs.map +0 -1
- package/dist/commands/migration-list.mjs.map +0 -1
- package/dist/contract-enrichment-Dani0mMW.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs +0 -160
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs.map +0 -1
- package/dist/global-flags-CdE7M0d9.d.mts.map +0 -1
- package/dist/migration-plan-C2jeH1J5.mjs.map +0 -1
- package/dist/migrations-CwZMa1Ck.mjs.map +0 -1
- package/dist/terminal-ui-BiB_8KNo.mjs +0 -379
- package/dist/terminal-ui-BiB_8KNo.mjs.map +0 -1
- package/dist/types-C9FfXb1l.d.mts.map +0 -1
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as assertFrameworkComponentsCompatible } from "./framework-components-
|
|
4
|
-
import { t as createTerminalUI } from "./
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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-DFF1LlfU.mjs";
|
|
3
|
+
import { t as assertFrameworkComponentsCompatible } from "./framework-components-DTcjouhS.mjs";
|
|
4
|
+
import { D as formatStyledHeader, a as loadMigrationPackages, 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-4UNsRRc4.mjs";
|
|
5
|
+
import { n as toExtensionInputs } from "./extension-pack-inputs-BiY86HbQ.mjs";
|
|
6
|
+
import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-CVHGuA35.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
|
-
import { readFile } from "node:fs/promises";
|
|
11
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
12
12
|
import { createControlStack, hasOperationPreview } from "@prisma-next/framework-components/control";
|
|
13
13
|
import { copyFilesWithRename, formatMigrationDirName, materialiseExtensionMigrationPackageIfMissing, writeMigrationPackage } from "@prisma-next/migration-tools/io";
|
|
14
|
-
import { findLatestMigration } from "@prisma-next/migration-tools/migration-graph";
|
|
14
|
+
import { assertHashIsGraphNode, findLatestMigration, isGraphNode } from "@prisma-next/migration-tools/migration-graph";
|
|
15
15
|
import { emitContractSpaceArtefacts, planAllSpaces, readContractSpaceHeadRef, spaceMigrationDirectory } from "@prisma-next/migration-tools/spaces";
|
|
16
16
|
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
17
|
+
import { readRefSnapshot, readRefs } from "@prisma-next/migration-tools/refs";
|
|
17
18
|
import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
18
|
-
import { readRefs } from "@prisma-next/migration-tools/refs";
|
|
19
19
|
import { computeMigrationHash } from "@prisma-next/migration-tools/hash";
|
|
20
20
|
import { writeMigrationTs } from "@prisma-next/migration-tools/migration-ts";
|
|
21
|
+
import { canonicalizeJson } from "@prisma-next/framework-components/utils";
|
|
21
22
|
import { deriveProvidedInvariants } from "@prisma-next/migration-tools/invariants";
|
|
22
23
|
//#region src/utils/contract-space-seed-phase.ts
|
|
23
24
|
/**
|
|
@@ -109,6 +110,135 @@ function buildPlaceholderContractDts(spaceId) {
|
|
|
109
110
|
].join("\n");
|
|
110
111
|
}
|
|
111
112
|
//#endregion
|
|
113
|
+
//#region src/utils/plan-resolution.ts
|
|
114
|
+
const FULL_HASH_PATTERN = /^sha256:([0-9a-f]{64}|empty)$/;
|
|
115
|
+
function looksLikeFullHash(input) {
|
|
116
|
+
return FULL_HASH_PATTERN.test(input);
|
|
117
|
+
}
|
|
118
|
+
function graphIsEmpty(bundles) {
|
|
119
|
+
return bundles.length === 0;
|
|
120
|
+
}
|
|
121
|
+
function getReachableRefs(refs, graph) {
|
|
122
|
+
return Object.entries(refs).flatMap(([name, entry]) => entry && isGraphNode(entry.hash, graph) ? [{
|
|
123
|
+
name,
|
|
124
|
+
hash: entry.hash
|
|
125
|
+
}] : []).sort((a, b) => a.name.localeCompare(b.name));
|
|
126
|
+
}
|
|
127
|
+
function assertFromIsGraphNode(fromHash, graph, refs, graphTipHash) {
|
|
128
|
+
try {
|
|
129
|
+
assertHashIsGraphNode(fromHash, graph);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (MigrationToolsError.is(error) && error.code === "MIGRATION.HASH_NOT_IN_GRAPH") throw errorPlanForgotTheFlag(fromHash, getReachableRefs(refs, graph), graphTipHash);
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function deserializeSnapshotContract(familyInstance, contract) {
|
|
136
|
+
try {
|
|
137
|
+
return ok(familyInstance.deserializeContract(contract));
|
|
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
|
+
}));
|
|
149
|
+
try {
|
|
150
|
+
return ok({
|
|
151
|
+
kind: "graph-node",
|
|
152
|
+
fromHash,
|
|
153
|
+
fromContract: await readBundleEndContract(matchingBundle.dirPath),
|
|
154
|
+
sourceDir: matchingBundle.dirPath
|
|
155
|
+
});
|
|
156
|
+
} catch (error) {
|
|
157
|
+
if (CliStructuredError.is(error)) return notOk(error);
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function resolveFromRefName(refName, fromHash, input, refs) {
|
|
162
|
+
const { refsDir, bundles, graph, familyInstance, readBundleEndContract } = input;
|
|
163
|
+
const empty = graphIsEmpty(bundles);
|
|
164
|
+
const graphTip = findLatestMigration(graph)?.to ?? null;
|
|
165
|
+
let snapshot;
|
|
166
|
+
try {
|
|
167
|
+
snapshot = await readRefSnapshot(refsDir, refName);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
if (snapshot) {
|
|
173
|
+
const contractResult = await deserializeSnapshotContract(familyInstance, snapshot.contract);
|
|
174
|
+
if (!contractResult.ok) return contractResult;
|
|
175
|
+
const fromContract = contractResult.value;
|
|
176
|
+
const { contractDts, contract: contractJson } = snapshot;
|
|
177
|
+
if (empty) return ok({
|
|
178
|
+
kind: "auto-baseline",
|
|
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`);
|
|
205
|
+
}
|
|
206
|
+
async function resolveFromForPlan(input) {
|
|
207
|
+
const { optionsFrom, refsDir, graph } = input;
|
|
208
|
+
let refs;
|
|
209
|
+
try {
|
|
210
|
+
refs = await readRefs(refsDir);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
if (optionsFrom === void 0) {
|
|
216
|
+
const dbRef = refs["db"];
|
|
217
|
+
if (!dbRef) return ok({
|
|
218
|
+
kind: "greenfield",
|
|
219
|
+
fromHash: null,
|
|
220
|
+
fromContract: null
|
|
221
|
+
});
|
|
222
|
+
return resolveFromRefName("db", dbRef.hash, input, refs);
|
|
223
|
+
}
|
|
224
|
+
const refResult = parseContractRef(optionsFrom, {
|
|
225
|
+
graph,
|
|
226
|
+
refs
|
|
227
|
+
});
|
|
228
|
+
if (!refResult.ok) {
|
|
229
|
+
if (looksLikeFullHash(optionsFrom)) {
|
|
230
|
+
const empty = graphIsEmpty(input.bundles);
|
|
231
|
+
const graphTip = findLatestMigration(graph)?.to ?? null;
|
|
232
|
+
if (empty) return notOk(errorSnapshotMissing(optionsFrom, { viaRef: false }));
|
|
233
|
+
return notOk(errorPlanForgotTheFlag(optionsFrom, getReachableRefs(refs, graph), graphTip));
|
|
234
|
+
}
|
|
235
|
+
return notOk(mapRefResolutionError(refResult.failure));
|
|
236
|
+
}
|
|
237
|
+
const { hash: fromHash, provenance } = refResult.value;
|
|
238
|
+
if (provenance.kind === "ref") return resolveFromRefName(provenance.refName, fromHash, input, refs);
|
|
239
|
+
return resolveFromHashProvenance(fromHash, input, refs, optionsFrom);
|
|
240
|
+
}
|
|
241
|
+
//#endregion
|
|
112
242
|
//#region src/commands/migration-plan.ts
|
|
113
243
|
/**
|
|
114
244
|
* Load a predecessor migration's destination contract from its sibling
|
|
@@ -148,6 +278,64 @@ async function readPredecessorEndContract(migrationDir, familyInstance) {
|
|
|
148
278
|
throw errorContractValidationFailed(`Predecessor contract at ${path} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`, { where: { path } });
|
|
149
279
|
}
|
|
150
280
|
}
|
|
281
|
+
async function writeSnapshotContractArtifacts(packageDir, contractJson, contractDts, artifactBasename) {
|
|
282
|
+
await mkdir(packageDir, { recursive: true });
|
|
283
|
+
const jsonContent = `${canonicalizeJson(contractJson)}\n`;
|
|
284
|
+
const dtsContent = contractDts.endsWith("\n") ? contractDts : `${contractDts}\n`;
|
|
285
|
+
await writeFile(join(packageDir, `${artifactBasename}.json`), jsonContent);
|
|
286
|
+
await writeFile(join(packageDir, `${artifactBasename}.d.ts`), dtsContent);
|
|
287
|
+
}
|
|
288
|
+
async function writeSnapshotStartContract(packageDir, contractJson, contractDts) {
|
|
289
|
+
await writeSnapshotContractArtifacts(packageDir, contractJson, contractDts, "start-contract");
|
|
290
|
+
}
|
|
291
|
+
async function runPlannerLeg(planner, migrations, frameworkComponents, contract, fromContract, spaceId) {
|
|
292
|
+
const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);
|
|
293
|
+
const plannerResult = planner.plan({
|
|
294
|
+
contract,
|
|
295
|
+
schema: fromSchema,
|
|
296
|
+
policy: { allowedOperationClasses: [
|
|
297
|
+
"additive",
|
|
298
|
+
"widening",
|
|
299
|
+
"destructive",
|
|
300
|
+
"data"
|
|
301
|
+
] },
|
|
302
|
+
fromContract,
|
|
303
|
+
frameworkComponents,
|
|
304
|
+
spaceId
|
|
305
|
+
});
|
|
306
|
+
if (plannerResult.kind === "failure") return notOk(errorMigrationPlanningFailed({ conflicts: plannerResult.conflicts }));
|
|
307
|
+
let plannedOps = [];
|
|
308
|
+
let hasPlaceholders = false;
|
|
309
|
+
try {
|
|
310
|
+
plannedOps = plannerResult.plan.operations;
|
|
311
|
+
if (plannedOps.length === 0) return notOk(errorMigrationPlanningFailed({ conflicts: [{
|
|
312
|
+
kind: "unsupportedChange",
|
|
313
|
+
summary: "Contract changed but planner produced no operations. This indicates unsupported or ignored changes."
|
|
314
|
+
}] }));
|
|
315
|
+
} catch (e) {
|
|
316
|
+
if (CliStructuredError.is(e) && e.domain === "MIG" && e.code === "2001") hasPlaceholders = true;
|
|
317
|
+
else throw e;
|
|
318
|
+
}
|
|
319
|
+
return ok({
|
|
320
|
+
plannedOps,
|
|
321
|
+
migrationTsContent: plannerResult.plan.renderTypeScript(),
|
|
322
|
+
hasPlaceholders
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
async function writePlannedMigrationPackage(packageDir, fromHash, toHash, createdAt, leg) {
|
|
326
|
+
const opsForWrite = leg.hasPlaceholders ? [] : leg.plannedOps;
|
|
327
|
+
const metadataWithInvariants = {
|
|
328
|
+
from: fromHash,
|
|
329
|
+
to: toHash,
|
|
330
|
+
providedInvariants: deriveProvidedInvariants(opsForWrite),
|
|
331
|
+
createdAt: createdAt.toISOString()
|
|
332
|
+
};
|
|
333
|
+
await writeMigrationPackage(packageDir, {
|
|
334
|
+
...metadataWithInvariants,
|
|
335
|
+
migrationHash: computeMigrationHash(metadataWithInvariants, opsForWrite)
|
|
336
|
+
}, opsForWrite);
|
|
337
|
+
await writeMigrationTs(packageDir, leg.migrationTsContent);
|
|
338
|
+
}
|
|
151
339
|
async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
152
340
|
const config = await loadConfig(options.config);
|
|
153
341
|
const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative } = resolveMigrationPaths(options.config, config);
|
|
@@ -206,36 +394,47 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
206
394
|
const rawStorageHash = toContract.storage?.storageHash;
|
|
207
395
|
if (typeof rawStorageHash !== "string") return notOk(errorContractValidationFailed("Contract is missing storageHash", { where: { path: contractPathAbsolute } }));
|
|
208
396
|
const toStorageHash = rawStorageHash;
|
|
397
|
+
const { refsDir } = resolveMigrationPaths(options.config, config);
|
|
209
398
|
let fromContract = null;
|
|
210
399
|
let fromHash = null;
|
|
211
400
|
let fromContractSourceDir = null;
|
|
401
|
+
let snapshotStartContract = null;
|
|
402
|
+
let isAutoBaseline = false;
|
|
212
403
|
try {
|
|
213
404
|
const { bundles, graph } = await loadMigrationPackages(appMigrationsDir);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
405
|
+
const resolutionResult = await resolveFromForPlan({
|
|
406
|
+
optionsFrom: options.from,
|
|
407
|
+
refsDir,
|
|
408
|
+
bundles,
|
|
409
|
+
graph,
|
|
410
|
+
familyInstance,
|
|
411
|
+
readBundleEndContract: (migrationDir) => readPredecessorEndContract(migrationDir, familyInstance)
|
|
412
|
+
});
|
|
413
|
+
if (!resolutionResult.ok) return notOk(resolutionResult.failure);
|
|
414
|
+
switch (resolutionResult.value.kind) {
|
|
415
|
+
case "greenfield": break;
|
|
416
|
+
case "graph-node":
|
|
417
|
+
fromHash = resolutionResult.value.fromHash;
|
|
418
|
+
fromContract = resolutionResult.value.fromContract;
|
|
419
|
+
fromContractSourceDir = resolutionResult.value.sourceDir;
|
|
420
|
+
break;
|
|
421
|
+
case "snapshot":
|
|
422
|
+
fromHash = resolutionResult.value.fromHash;
|
|
423
|
+
fromContract = resolutionResult.value.fromContract;
|
|
424
|
+
snapshotStartContract = {
|
|
425
|
+
contractJson: resolutionResult.value.contractJson,
|
|
426
|
+
contractDts: resolutionResult.value.contractDts
|
|
427
|
+
};
|
|
428
|
+
break;
|
|
429
|
+
case "auto-baseline":
|
|
430
|
+
fromHash = resolutionResult.value.fromHash;
|
|
431
|
+
fromContract = resolutionResult.value.fromContract;
|
|
432
|
+
snapshotStartContract = {
|
|
433
|
+
contractJson: resolutionResult.value.contractJson,
|
|
434
|
+
contractDts: resolutionResult.value.contractDts
|
|
435
|
+
};
|
|
436
|
+
isAutoBaseline = true;
|
|
437
|
+
break;
|
|
239
438
|
}
|
|
240
439
|
} catch (error) {
|
|
241
440
|
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
@@ -257,7 +456,7 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
257
456
|
spaceId: r.spaceId,
|
|
258
457
|
dirName
|
|
259
458
|
})));
|
|
260
|
-
if (fromHash === toStorageHash) return ok({
|
|
459
|
+
if (fromHash === toStorageHash && !isAutoBaseline) return ok({
|
|
261
460
|
ok: true,
|
|
262
461
|
noOp: true,
|
|
263
462
|
from: fromHash,
|
|
@@ -283,58 +482,105 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
283
482
|
config.adapter,
|
|
284
483
|
...config.extensionPacks ?? []
|
|
285
484
|
]);
|
|
286
|
-
const timestamp = /* @__PURE__ */ new Date();
|
|
287
|
-
const packageDir = join(appMigrationsDir, formatMigrationDirName(timestamp, options.name ?? "migration"));
|
|
288
|
-
const baseMetadata = {
|
|
289
|
-
from: fromHash,
|
|
290
|
-
to: toStorageHash,
|
|
291
|
-
hints: {
|
|
292
|
-
used: [],
|
|
293
|
-
applied: [],
|
|
294
|
-
plannerVersion: "2.0.0"
|
|
295
|
-
},
|
|
296
|
-
labels: [],
|
|
297
|
-
createdAt: timestamp.toISOString()
|
|
298
|
-
};
|
|
299
485
|
try {
|
|
300
486
|
const planner = migrations.createPlanner(familyInstance);
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
487
|
+
if (isAutoBaseline && fromHash !== null && fromContract !== null && snapshotStartContract !== null) {
|
|
488
|
+
const baselineTimestamp = /* @__PURE__ */ new Date();
|
|
489
|
+
const deltaTimestamp = new Date(baselineTimestamp.getTime() + 6e4);
|
|
490
|
+
const baselineDirName = formatMigrationDirName(baselineTimestamp, "baseline");
|
|
491
|
+
const deltaDirName = formatMigrationDirName(deltaTimestamp, options.name ?? "migration");
|
|
492
|
+
const baselinePackageDir = join(appMigrationsDir, baselineDirName);
|
|
493
|
+
const deltaPackageDir = join(appMigrationsDir, deltaDirName);
|
|
494
|
+
const baselineLeg = await runPlannerLeg(planner, migrations, frameworkComponents, fromContract, null, aggregate.app.spaceId);
|
|
495
|
+
if (!baselineLeg.ok) return notOk(baselineLeg.failure);
|
|
496
|
+
await writePlannedMigrationPackage(baselinePackageDir, null, fromHash, baselineTimestamp, baselineLeg.value);
|
|
497
|
+
await writeSnapshotContractArtifacts(baselinePackageDir, snapshotStartContract.contractJson, snapshotStartContract.contractDts, "end-contract");
|
|
498
|
+
if (fromHash === toStorageHash) {
|
|
499
|
+
const baselineOps = baselineLeg.value.hasPlaceholders ? [] : baselineLeg.value.plannedOps;
|
|
500
|
+
if (baselineLeg.value.hasPlaceholders) {
|
|
501
|
+
const baselineDir = relative(process.cwd(), baselinePackageDir);
|
|
502
|
+
return ok({
|
|
503
|
+
ok: true,
|
|
504
|
+
noOp: false,
|
|
505
|
+
from: fromHash,
|
|
506
|
+
to: toStorageHash,
|
|
507
|
+
dir: baselineDir,
|
|
508
|
+
baselineDir,
|
|
509
|
+
operations: [],
|
|
510
|
+
emittedExtensionDirs,
|
|
511
|
+
pendingPlaceholders: true,
|
|
512
|
+
summary: "Planned baseline with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit",
|
|
513
|
+
timings: { total: Date.now() - startTime }
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
const preview = hasOperationPreview(familyInstance) ? familyInstance.toOperationPreview(baselineOps) : void 0;
|
|
517
|
+
return ok({
|
|
518
|
+
ok: true,
|
|
519
|
+
noOp: false,
|
|
520
|
+
from: fromHash,
|
|
521
|
+
to: toStorageHash,
|
|
522
|
+
baselineDir: relative(process.cwd(), baselinePackageDir),
|
|
523
|
+
operations: baselineOps.map((op) => ({
|
|
524
|
+
id: op.id,
|
|
525
|
+
label: op.label,
|
|
526
|
+
operationClass: op.operationClass
|
|
527
|
+
})),
|
|
528
|
+
emittedExtensionDirs,
|
|
529
|
+
...preview !== void 0 ? { preview } : {},
|
|
530
|
+
summary: buildAutoBaselinePlanSummary(0, emittedExtensionDirs.length),
|
|
531
|
+
timings: { total: Date.now() - startTime }
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId);
|
|
535
|
+
if (!deltaLeg.ok) return notOk(deltaLeg.failure);
|
|
536
|
+
await writePlannedMigrationPackage(deltaPackageDir, fromHash, toStorageHash, deltaTimestamp, deltaLeg.value);
|
|
537
|
+
const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);
|
|
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
|
+
}]);
|
|
545
|
+
await writeSnapshotStartContract(deltaPackageDir, snapshotStartContract.contractJson, snapshotStartContract.contractDts);
|
|
546
|
+
const deltaOps = deltaLeg.value.hasPlaceholders ? [] : deltaLeg.value.plannedOps;
|
|
547
|
+
if (deltaLeg.value.hasPlaceholders) return ok({
|
|
548
|
+
ok: true,
|
|
549
|
+
noOp: false,
|
|
550
|
+
from: fromHash,
|
|
551
|
+
to: toStorageHash,
|
|
552
|
+
dir: relative(process.cwd(), deltaPackageDir),
|
|
553
|
+
baselineDir: relative(process.cwd(), baselinePackageDir),
|
|
554
|
+
operations: [],
|
|
555
|
+
emittedExtensionDirs,
|
|
556
|
+
pendingPlaceholders: true,
|
|
557
|
+
summary: "Planned baseline + migration with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit",
|
|
558
|
+
timings: { total: Date.now() - startTime }
|
|
559
|
+
});
|
|
560
|
+
const preview = hasOperationPreview(familyInstance) ? familyInstance.toOperationPreview(deltaOps) : void 0;
|
|
561
|
+
return ok({
|
|
562
|
+
ok: true,
|
|
563
|
+
noOp: false,
|
|
564
|
+
from: fromHash,
|
|
565
|
+
to: toStorageHash,
|
|
566
|
+
dir: relative(process.cwd(), deltaPackageDir),
|
|
567
|
+
baselineDir: relative(process.cwd(), baselinePackageDir),
|
|
568
|
+
operations: deltaOps.map((op) => ({
|
|
569
|
+
id: op.id,
|
|
570
|
+
label: op.label,
|
|
571
|
+
operationClass: op.operationClass
|
|
572
|
+
})),
|
|
573
|
+
emittedExtensionDirs,
|
|
574
|
+
...preview !== void 0 ? { preview } : {},
|
|
575
|
+
summary: buildAutoBaselinePlanSummary(deltaOps.length, emittedExtensionDirs.length),
|
|
576
|
+
timings: { total: Date.now() - startTime }
|
|
577
|
+
});
|
|
327
578
|
}
|
|
328
|
-
const
|
|
329
|
-
const
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
};
|
|
334
|
-
await writeMigrationPackage(packageDir, {
|
|
335
|
-
...metadataWithInvariants,
|
|
336
|
-
migrationHash: computeMigrationHash(metadataWithInvariants, opsForWrite)
|
|
337
|
-
}, opsForWrite);
|
|
579
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
580
|
+
const packageDir = join(appMigrationsDir, formatMigrationDirName(timestamp, options.name ?? "migration"));
|
|
581
|
+
const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId);
|
|
582
|
+
if (!deltaLeg.ok) return notOk(deltaLeg.failure);
|
|
583
|
+
await writePlannedMigrationPackage(packageDir, fromHash, toStorageHash, timestamp, deltaLeg.value);
|
|
338
584
|
const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);
|
|
339
585
|
await copyFilesWithRename(packageDir, [{
|
|
340
586
|
sourcePath: destinationArtifacts.jsonPath,
|
|
@@ -352,9 +598,8 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
352
598
|
sourcePath: sourceArtifacts.dtsPath,
|
|
353
599
|
destName: "start-contract.d.ts"
|
|
354
600
|
}]);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
if (hasPlaceholders) return ok({
|
|
601
|
+
} else if (snapshotStartContract !== null) await writeSnapshotStartContract(packageDir, snapshotStartContract.contractJson, snapshotStartContract.contractDts);
|
|
602
|
+
if (deltaLeg.value.hasPlaceholders) return ok({
|
|
358
603
|
ok: true,
|
|
359
604
|
noOp: false,
|
|
360
605
|
from: fromHash,
|
|
@@ -366,6 +611,7 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
|
366
611
|
summary: "Planned migration with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit",
|
|
367
612
|
timings: { total: Date.now() - startTime }
|
|
368
613
|
});
|
|
614
|
+
const plannedOps = deltaLeg.value.plannedOps;
|
|
369
615
|
const preview = hasOperationPreview(familyInstance) ? familyInstance.toOperationPreview(plannedOps) : void 0;
|
|
370
616
|
return ok({
|
|
371
617
|
ok: true,
|
|
@@ -425,6 +671,11 @@ function buildPlanSummary(plannedOpsCount, emittedExtensionDirsCount) {
|
|
|
425
671
|
if (emittedExtensionDirsCount === 0) return base;
|
|
426
672
|
return `${base}; materialised ${emittedExtensionDirsCount} ${emittedExtensionDirsCount === 1 ? "extension-space migration" : "extension-space migrations"}`;
|
|
427
673
|
}
|
|
674
|
+
function buildAutoBaselinePlanSummary(deltaOpsCount, emittedExtensionDirsCount) {
|
|
675
|
+
const base = `Planned baseline + ${deltaOpsCount} operation(s)`;
|
|
676
|
+
if (emittedExtensionDirsCount === 0) return base;
|
|
677
|
+
return `${base}; materialised ${emittedExtensionDirsCount} ${emittedExtensionDirsCount === 1 ? "extension-space migration" : "extension-space migrations"}`;
|
|
678
|
+
}
|
|
428
679
|
function formatMigrationPlanOutput(result, flags) {
|
|
429
680
|
const lines = [];
|
|
430
681
|
const useColor = flags.color !== false;
|
|
@@ -476,10 +727,12 @@ function formatMigrationPlanOutput(result, flags) {
|
|
|
476
727
|
}
|
|
477
728
|
lines.push(dim_(`from: ${result.from}`));
|
|
478
729
|
lines.push(dim_(`to: ${result.to}`));
|
|
730
|
+
if (result.baselineDir) lines.push(dim_(`Baseline → ${result.baselineDir}`));
|
|
479
731
|
if (result.dir) lines.push(dim_(`App space → ${result.dir}`));
|
|
480
732
|
for (const entry of result.emittedExtensionDirs) lines.push(dim_(`Extension space ${entry.spaceId} → migrations/${entry.spaceId}/${entry.dirName}`));
|
|
481
733
|
lines.push("");
|
|
482
|
-
|
|
734
|
+
const reviewTarget = result.baselineDir !== void 0 && result.dir !== void 0 ? `${result.baselineDir} and ${result.dir}` : result.baselineDir ?? result.dir ?? "<dir>";
|
|
735
|
+
lines.push(`Next: review ${green_(reviewTarget)} if needed, then run ${green_("prisma-next migrate")}.`);
|
|
483
736
|
if (result.preview && result.preview.statements.length > 0) {
|
|
484
737
|
const allSql = result.preview.statements.every((s) => s.language === "sql");
|
|
485
738
|
lines.push("");
|
|
@@ -526,4 +779,4 @@ function resolveBundleByPrefix(bundles, needle) {
|
|
|
526
779
|
//#endregion
|
|
527
780
|
export { formatMigrationPlanOutput as n, resolveBundleByPrefix as r, createMigrationPlanCommand as t };
|
|
528
781
|
|
|
529
|
-
//# sourceMappingURL=migration-plan-
|
|
782
|
+
//# sourceMappingURL=migration-plan-BqmIKQpZ.mjs.map
|