prisma-next 0.12.0-dev.5 → 0.12.0-dev.50
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 +180 -163
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-KgJorIvG.mjs → client-DC-UlBLy.mjs} +83 -58
- package/dist/client-DC-UlBLy.mjs.map +1 -0
- package/dist/{command-helpers-Bbw1GbwL.mjs → command-helpers-esJGBD4W.mjs} +317 -23
- package/dist/command-helpers-esJGBD4W.mjs.map +1 -0
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +4 -5
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +4 -4
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +10 -7
- package/dist/commands/db-update.mjs.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 +6 -8
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +55 -13
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +3 -2
- package/dist/commands/migration-graph.d.mts +17 -8
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +183 -2
- package/dist/commands/migration-graph.mjs.map +1 -0
- package/dist/commands/migration-list.d.mts +25 -27
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +2 -190
- package/dist/commands/migration-log.d.mts +9 -19
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +1 -137
- package/dist/commands/migration-new.mjs +3 -3
- package/dist/commands/migration-plan.d.mts +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +17 -21
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +23 -35
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +42 -144
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +3 -759
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +3 -3
- package/dist/commands/telemetry/index.d.mts +7 -0
- package/dist/commands/telemetry/index.d.mts.map +1 -0
- package/dist/commands/telemetry/index.mjs +2 -0
- package/dist/{contract-at-errors-BxP-TOMl.mjs → contract-at-errors-COZAemUl.mjs} +2 -2
- package/dist/{contract-at-errors-BxP-TOMl.mjs.map → contract-at-errors-COZAemUl.mjs.map} +1 -1
- package/dist/{contract-emit-DxcGl4Uq.mjs → contract-emit-Bv46RAIO.mjs} +3 -3
- package/dist/{contract-emit-DxcGl4Uq.mjs.map → contract-emit-Bv46RAIO.mjs.map} +1 -1
- package/dist/{contract-emit-D-4jrNve.mjs → contract-emit-DIWImLqS.mjs} +5 -5
- package/dist/{contract-emit-D-4jrNve.mjs.map → contract-emit-DIWImLqS.mjs.map} +1 -1
- package/dist/{contract-infer-D8uEbJuu.mjs → contract-infer-DpGN9SAj.mjs} +3 -3
- package/dist/{contract-infer-D8uEbJuu.mjs.map → contract-infer-DpGN9SAj.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs → contract-space-aggregate-loader-CpNVrBqW.mjs} +63 -5
- package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs.map → contract-space-aggregate-loader-CpNVrBqW.mjs.map} +1 -1
- package/dist/{db-verify-v_vUKXTU.mjs → db-verify-Cq16Obsw.mjs} +4 -4
- package/dist/{db-verify-v_vUKXTU.mjs.map → db-verify-Cq16Obsw.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +2 -2
- package/dist/exports/control-api.d.mts.map +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-fYXjz_in.mjs → framework-components-BO9VO43s.mjs} +2 -2
- package/dist/{framework-components-fYXjz_in.mjs.map → framework-components-BO9VO43s.mjs.map} +1 -1
- package/dist/{global-flags-DEHjV8_s.d.mts → global-flags-CV5LhrFg.d.mts} +1 -1
- package/dist/{global-flags-DEHjV8_s.d.mts.map → global-flags-CV5LhrFg.d.mts.map} +1 -1
- package/dist/{init-Cv9UzWL5.mjs → init-C0rjiQ9I.mjs} +5 -58
- package/dist/init-C0rjiQ9I.mjs.map +1 -0
- package/dist/{inspect-live-schema-C6ohV_oQ.mjs → inspect-live-schema-CRDKTNcf.mjs} +3 -3
- package/dist/{inspect-live-schema-C6ohV_oQ.mjs.map → inspect-live-schema-CRDKTNcf.mjs.map} +1 -1
- package/dist/migration-check-BxWlQBOs.mjs +573 -0
- package/dist/migration-check-BxWlQBOs.mjs.map +1 -0
- package/dist/{migration-command-scaffold-CjvwO6at.mjs → migration-command-scaffold-BDd9abqW.mjs} +3 -3
- package/dist/{migration-command-scaffold-CjvwO6at.mjs.map → migration-command-scaffold-BDd9abqW.mjs.map} +1 -1
- package/dist/migration-graph-space-render-CeNXh_Wy.mjs +1966 -0
- package/dist/migration-graph-space-render-CeNXh_Wy.mjs.map +1 -0
- package/dist/migration-list-vJWFuXca.mjs +228 -0
- package/dist/migration-list-vJWFuXca.mjs.map +1 -0
- package/dist/migration-log-6rcHQSI4.mjs +222 -0
- package/dist/migration-log-6rcHQSI4.mjs.map +1 -0
- package/dist/migration-path-target-UkxkgXnv.mjs +38 -0
- package/dist/migration-path-target-UkxkgXnv.mjs.map +1 -0
- package/dist/{migration-plan-9DJ7q7_z.mjs → migration-plan-CHu_erQ5.mjs} +5 -6
- package/dist/{migration-plan-9DJ7q7_z.mjs.map → migration-plan-CHu_erQ5.mjs.map} +1 -1
- package/dist/migration-status-Bjv91dE7.mjs +444 -0
- package/dist/migration-status-Bjv91dE7.mjs.map +1 -0
- package/dist/{output-B60Gw5fu.mjs → output-BD61elic.mjs} +1 -1
- package/dist/{output-B60Gw5fu.mjs.map → output-BD61elic.mjs.map} +1 -1
- package/dist/{ref-advancement-DUZqsue6.mjs → ref-advancement-CJY9zOv7.mjs} +1 -1
- package/dist/{ref-advancement-DUZqsue6.mjs.map → ref-advancement-CJY9zOv7.mjs.map} +1 -1
- package/dist/schemas-BL33A3i-.d.mts +193 -0
- package/dist/schemas-BL33A3i-.d.mts.map +1 -0
- package/dist/schemas-DJY2O09F.mjs +112 -0
- package/dist/schemas-DJY2O09F.mjs.map +1 -0
- package/dist/telemetry-CZkgkR_O.mjs +122 -0
- package/dist/telemetry-CZkgkR_O.mjs.map +1 -0
- package/dist/{terminal-ui-5Y6mrg93.d.mts → terminal-ui-BgLiAOYi.d.mts} +1 -1
- package/dist/{terminal-ui-5Y6mrg93.d.mts.map → terminal-ui-BgLiAOYi.d.mts.map} +1 -1
- package/dist/{types-Dt_SfqFm.d.mts → types-qV41eEXH.d.mts} +44 -31
- package/dist/types-qV41eEXH.d.mts.map +1 -0
- package/dist/{verify-DCA9Sldu.mjs → verify-IilvIk_E.mjs} +2 -2
- package/dist/{verify-DCA9Sldu.mjs.map → verify-IilvIk_E.mjs.map} +1 -1
- package/package.json +11 -12
- package/dist/client-KgJorIvG.mjs.map +0 -1
- package/dist/command-helpers-Bbw1GbwL.mjs.map +0 -1
- package/dist/commands/migration-list.mjs.map +0 -1
- package/dist/commands/migration-log.mjs.map +0 -1
- package/dist/commands/migration-status.mjs.map +0 -1
- package/dist/extension-pack-inputs-IDvjRCi3.mjs +0 -62
- package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +0 -1
- package/dist/graph-render-rFAqZujX.mjs +0 -1081
- package/dist/graph-render-rFAqZujX.mjs.map +0 -1
- package/dist/init-Cv9UzWL5.mjs.map +0 -1
- package/dist/migration-check-BiBJoYYW.mjs +0 -341
- package/dist/migration-check-BiBJoYYW.mjs.map +0 -1
- package/dist/migration-graph-D7DVUElV.mjs +0 -1232
- package/dist/migration-graph-D7DVUElV.mjs.map +0 -1
- package/dist/migration-list-styler-BRwF4-gy.mjs +0 -399
- package/dist/migration-list-styler-BRwF4-gy.mjs.map +0 -1
- package/dist/migration-types-D2FW63pr.d.mts +0 -15
- package/dist/migration-types-D2FW63pr.d.mts.map +0 -1
- package/dist/migrations-Cv2jxNNK.mjs +0 -228
- package/dist/migrations-Cv2jxNNK.mjs.map +0 -1
- package/dist/types-Dt_SfqFm.d.mts.map +0 -1
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import { T as formatStyledHeader, _ as createTerminalUI, d as setCommandSeeAlso, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, o as resolveContractPath, s as resolveMigrationPaths, t as addGlobalOptions, u as setCommandExamples } from "./command-helpers-Bbw1GbwL.mjs";
|
|
3
|
-
import { t as toDeclaredExtensionsFromRaw } from "./extension-pack-inputs-IDvjRCi3.mjs";
|
|
4
|
-
import { Command } from "commander";
|
|
5
|
-
import { join, relative } from "pathe";
|
|
6
|
-
import { readFile } from "node:fs/promises";
|
|
7
|
-
import { createControlStack } from "@prisma-next/framework-components/control";
|
|
8
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
9
|
-
import { loadContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
|
|
10
|
-
import { reconstructGraph } from "@prisma-next/migration-tools/migration-graph";
|
|
11
|
-
import { readRefs } from "@prisma-next/migration-tools/refs";
|
|
12
|
-
import { parseMigrationRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
13
|
-
import { verifyMigrationHash } from "@prisma-next/migration-tools/hash";
|
|
14
|
-
import { readMigrationsDir } from "@prisma-next/migration-tools/io";
|
|
15
|
-
//#region src/utils/integrity-violation-to-check-failure.ts
|
|
16
|
-
function migrationPathRelative$1(dirPath) {
|
|
17
|
-
return relative(process.cwd(), dirPath);
|
|
18
|
-
}
|
|
19
|
-
function migrationFileRelative$1(dirPath, fileName) {
|
|
20
|
-
return join(migrationPathRelative$1(dirPath), fileName);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Map one {@link IntegrityViolation} onto a `migration check` failure row.
|
|
24
|
-
* Sole catalogue mapping from integrity violations to `PN-MIG-CHECK-*`.
|
|
25
|
-
*/
|
|
26
|
-
function integrityViolationToCheckFailure(violation, migrationsDir) {
|
|
27
|
-
const spaceRelative = (spaceId) => migrationPathRelative$1(join(migrationsDir, spaceId));
|
|
28
|
-
const packageRelative = (spaceId, dirName) => migrationPathRelative$1(join(migrationsDir, spaceId, dirName));
|
|
29
|
-
const refRelative = (spaceId, refName) => migrationPathRelative$1(join(migrationsDir, spaceId, "refs", `${refName}.json`));
|
|
30
|
-
switch (violation.kind) {
|
|
31
|
-
case "hashMismatch": return {
|
|
32
|
-
pnCode: "PN-MIG-CHECK-001",
|
|
33
|
-
where: migrationFileRelative$1(join(migrationsDir, violation.spaceId, violation.dirName), "migration.json"),
|
|
34
|
-
why: `Stored hash ${violation.stored} does not match recomputed hash ${violation.computed}`,
|
|
35
|
-
fix: "Re-emit the migration package or restore from version control."
|
|
36
|
-
};
|
|
37
|
-
case "providedInvariantsMismatch": return {
|
|
38
|
-
pnCode: "PN-MIG-CHECK-002",
|
|
39
|
-
where: packageRelative(violation.spaceId, violation.dirName),
|
|
40
|
-
why: `Migration "${violation.dirName}" providedInvariants in migration.json disagrees with ops.json.`,
|
|
41
|
-
fix: "Re-emit the migration package so migration.json and ops.json agree."
|
|
42
|
-
};
|
|
43
|
-
case "packageUnloadable": return {
|
|
44
|
-
pnCode: "PN-MIG-CHECK-002",
|
|
45
|
-
where: packageRelative(violation.spaceId, violation.dirName),
|
|
46
|
-
why: `Migration "${violation.dirName}" could not be loaded: ${violation.detail}`,
|
|
47
|
-
fix: "Re-emit the migration package or restore from version control."
|
|
48
|
-
};
|
|
49
|
-
case "sameSourceAndTarget": return {
|
|
50
|
-
pnCode: "PN-MIG-CHECK-007",
|
|
51
|
-
where: packageRelative(violation.spaceId, violation.dirName),
|
|
52
|
-
why: `Migration "${violation.dirName}" in space "${violation.spaceId}" has source equal to target (${violation.hash}) with no data invariant — a true no-op self-edge.`,
|
|
53
|
-
fix: "Add a data operation if this self-edge was meant to carry a data invariant, or delete the migration if it is a true no-op."
|
|
54
|
-
};
|
|
55
|
-
case "orphanSpaceDir": return {
|
|
56
|
-
pnCode: "PN-MIG-CHECK-008",
|
|
57
|
-
where: spaceRelative(violation.spaceId),
|
|
58
|
-
why: `Contract-space directory "${violation.spaceId}" exists on disk but no extension declares it.`,
|
|
59
|
-
fix: "Remove the orphan directory, or declare the extension in `extensionPacks`."
|
|
60
|
-
};
|
|
61
|
-
case "declaredButUnmigrated": return {
|
|
62
|
-
pnCode: "PN-MIG-CHECK-009",
|
|
63
|
-
where: spaceRelative(violation.spaceId),
|
|
64
|
-
why: `Extension "${violation.spaceId}" is declared in \`extensionPacks\` but has no on-disk migrations directory.`,
|
|
65
|
-
fix: "Re-emit the extension contract-space artefacts with `prisma-next contract emit` and migration planning, or remove the extension from `extensionPacks` if it is unused."
|
|
66
|
-
};
|
|
67
|
-
case "headRefMissing": return {
|
|
68
|
-
pnCode: "PN-MIG-CHECK-010",
|
|
69
|
-
where: refRelative(violation.spaceId, "head"),
|
|
70
|
-
why: `Head ref \`refs/head.json\` is missing for contract space "${violation.spaceId}".`,
|
|
71
|
-
fix: "Re-emit the contract-space migrations and head ref artefacts, or restore `refs/head.json` from version control."
|
|
72
|
-
};
|
|
73
|
-
case "headRefNotInGraph": return {
|
|
74
|
-
pnCode: "PN-MIG-CHECK-011",
|
|
75
|
-
where: refRelative(violation.spaceId, "head"),
|
|
76
|
-
why: `Head ref ${violation.hash} for contract space "${violation.spaceId}" is not present in its migration graph.`,
|
|
77
|
-
fix: "Re-emit the contract space migrations, or restore the missing migration package."
|
|
78
|
-
};
|
|
79
|
-
case "refUnreadable": return {
|
|
80
|
-
pnCode: "PN-MIG-CHECK-012",
|
|
81
|
-
where: refRelative(violation.spaceId, violation.refName),
|
|
82
|
-
why: `Ref "${violation.refName}" for contract space "${violation.spaceId}" is unreadable: ${violation.detail}`,
|
|
83
|
-
fix: "Repair or remove the corrupt ref file."
|
|
84
|
-
};
|
|
85
|
-
case "targetMismatch": return {
|
|
86
|
-
pnCode: "PN-MIG-CHECK-013",
|
|
87
|
-
where: spaceRelative(violation.spaceId),
|
|
88
|
-
why: `Contract space "${violation.spaceId}" targets "${violation.actual}" but the project targets "${violation.expected}".`,
|
|
89
|
-
fix: "Update the extension to target the configured database, or change the project target."
|
|
90
|
-
};
|
|
91
|
-
case "disjointness": return {
|
|
92
|
-
pnCode: "PN-MIG-CHECK-014",
|
|
93
|
-
where: migrationPathRelative$1(migrationsDir),
|
|
94
|
-
why: `Storage element "${violation.element}" is claimed by multiple contract spaces: ${violation.claimedBy.join(", ")}.`,
|
|
95
|
-
fix: "Update the contracts so each storage element is owned by exactly one contract space."
|
|
96
|
-
};
|
|
97
|
-
case "contractUnreadable": return {
|
|
98
|
-
pnCode: "PN-MIG-CHECK-015",
|
|
99
|
-
where: migrationFileRelative$1(join(migrationsDir, violation.spaceId), "contract.json"),
|
|
100
|
-
why: `Contract for space "${violation.spaceId}" is unreadable: ${violation.detail}`,
|
|
101
|
-
fix: "Re-emit the extension contract artefacts, or fix the descriptor producing the invalid contract."
|
|
102
|
-
};
|
|
103
|
-
case "duplicateMigrationHash": return {
|
|
104
|
-
pnCode: "PN-MIG-CHECK-016",
|
|
105
|
-
where: spaceRelative(violation.spaceId),
|
|
106
|
-
why: `Multiple migrations in space "${violation.spaceId}" share migrationHash "${violation.migrationHash}" (${violation.dirNames.join(", ")}).`,
|
|
107
|
-
fix: "Re-emit one of the conflicting packages so each migrationHash is unique."
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
//#endregion
|
|
112
|
-
//#region src/commands/migration-check.ts
|
|
113
|
-
function migrationPathRelative(dirPath) {
|
|
114
|
-
return relative(process.cwd(), dirPath);
|
|
115
|
-
}
|
|
116
|
-
function migrationFileRelative(dirPath, fileName) {
|
|
117
|
-
return join(migrationPathRelative(dirPath), fileName);
|
|
118
|
-
}
|
|
119
|
-
function checkFileExists(dirPath, dirName, fileName) {
|
|
120
|
-
if (!existsSync(join(dirPath, fileName))) return {
|
|
121
|
-
pnCode: "PN-MIG-CHECK-002",
|
|
122
|
-
where: migrationFileRelative(dirPath, fileName),
|
|
123
|
-
why: `${fileName} is missing from ${dirName}`,
|
|
124
|
-
fix: "Re-emit the migration package or restore from version control."
|
|
125
|
-
};
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
function checkSnapshotConsistency(pkg) {
|
|
129
|
-
const endContractPath = join(pkg.dirPath, "end-contract.json");
|
|
130
|
-
if (!existsSync(endContractPath)) return null;
|
|
131
|
-
try {
|
|
132
|
-
const snapshotHash = JSON.parse(readFileSync(endContractPath, "utf-8"))["storage"]?.["storageHash"];
|
|
133
|
-
if (typeof snapshotHash === "string" && snapshotHash !== pkg.metadata.to) return {
|
|
134
|
-
pnCode: "PN-MIG-CHECK-005",
|
|
135
|
-
where: migrationPathRelative(pkg.dirPath),
|
|
136
|
-
why: `Migration "${pkg.dirName}" declares to=${pkg.metadata.to} but end-contract.json has storageHash=${snapshotHash}`,
|
|
137
|
-
fix: "Re-emit the migration package so migration.json and end-contract.json agree."
|
|
138
|
-
};
|
|
139
|
-
} catch {
|
|
140
|
-
return {
|
|
141
|
-
pnCode: "PN-MIG-CHECK-006",
|
|
142
|
-
where: migrationPathRelative(pkg.dirPath),
|
|
143
|
-
why: `Migration "${pkg.dirName}" has an unparseable end-contract.json.`,
|
|
144
|
-
fix: "Re-emit the migration package to repair the snapshot file."
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
async function loadAggregateIntegrityViolations(config, migrationsDir) {
|
|
150
|
-
try {
|
|
151
|
-
const contractJsonContent = await readFile(resolveContractPath(config), "utf-8");
|
|
152
|
-
const familyInstance = config.family.create(createControlStack(config));
|
|
153
|
-
const declaredExtensions = toDeclaredExtensionsFromRaw(config.extensionPacks ?? []);
|
|
154
|
-
const parsedAppContract = JSON.parse(contractJsonContent);
|
|
155
|
-
return (await loadContractSpaceAggregate({
|
|
156
|
-
migrationsDir,
|
|
157
|
-
deserializeContract: (json) => familyInstance.deserializeContract(json),
|
|
158
|
-
appContract: familyInstance.deserializeContract(parsedAppContract)
|
|
159
|
-
})).checkIntegrity({
|
|
160
|
-
declaredExtensions,
|
|
161
|
-
checkContracts: true
|
|
162
|
-
});
|
|
163
|
-
} catch {
|
|
164
|
-
return [];
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
async function executeMigrationCheckCommand(target, options, flags, ui) {
|
|
168
|
-
const config = await loadConfig(options.config);
|
|
169
|
-
const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative, refsDir } = resolveMigrationPaths(options.config, config);
|
|
170
|
-
if (!flags.json && !flags.quiet) {
|
|
171
|
-
const details = [{
|
|
172
|
-
label: "config",
|
|
173
|
-
value: configPath
|
|
174
|
-
}, {
|
|
175
|
-
label: "migrations",
|
|
176
|
-
value: appMigrationsRelative
|
|
177
|
-
}];
|
|
178
|
-
if (target) details.push({
|
|
179
|
-
label: "target",
|
|
180
|
-
value: target
|
|
181
|
-
});
|
|
182
|
-
const header = formatStyledHeader({
|
|
183
|
-
command: "migration check",
|
|
184
|
-
description: "Verify artifact and graph integrity",
|
|
185
|
-
details,
|
|
186
|
-
flags
|
|
187
|
-
});
|
|
188
|
-
ui.stderr(header);
|
|
189
|
-
}
|
|
190
|
-
const failures = [];
|
|
191
|
-
const bundles = (await readMigrationsDir(appMigrationsDir)).packages;
|
|
192
|
-
const graph = reconstructGraph(bundles);
|
|
193
|
-
if (existsSync(appMigrationsDir)) {
|
|
194
|
-
const loadedDirNames = new Set(bundles.map((p) => p.dirName));
|
|
195
|
-
try {
|
|
196
|
-
const entries = readdirSync(appMigrationsDir);
|
|
197
|
-
for (const entry of entries) {
|
|
198
|
-
if (entry.startsWith(".") || entry.startsWith("_") || entry === "refs") continue;
|
|
199
|
-
const entryPath = join(appMigrationsDir, entry);
|
|
200
|
-
try {
|
|
201
|
-
if (!statSync(entryPath).isDirectory()) continue;
|
|
202
|
-
} catch {
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
if (!loadedDirNames.has(entry)) for (const f of ["migration.json", "ops.json"]) {
|
|
206
|
-
const fail = checkFileExists(entryPath, entry, f);
|
|
207
|
-
if (fail) failures.push(fail);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
} catch {}
|
|
211
|
-
}
|
|
212
|
-
if (target) {
|
|
213
|
-
const migResult = parseMigrationRef(target, {
|
|
214
|
-
graph,
|
|
215
|
-
refs: await readRefs(refsDir)
|
|
216
|
-
});
|
|
217
|
-
if (!migResult.ok) return {
|
|
218
|
-
result: {
|
|
219
|
-
ok: false,
|
|
220
|
-
failures: [],
|
|
221
|
-
summary: migResult.failure.kind === "not-found" ? `Migration "${target}" does not exist` : migResult.failure.kind === "wrong-grammar" ? migResult.failure.message : `Invalid migration reference: "${target}"`
|
|
222
|
-
},
|
|
223
|
-
exitCode: 2
|
|
224
|
-
};
|
|
225
|
-
const matchedPkg = bundles.find((p) => p.metadata.migrationHash === migResult.value.migrationHash);
|
|
226
|
-
if (!matchedPkg) return {
|
|
227
|
-
result: {
|
|
228
|
-
ok: false,
|
|
229
|
-
failures: [],
|
|
230
|
-
summary: `Migration package for "${target}" not found on disk`
|
|
231
|
-
},
|
|
232
|
-
exitCode: 2
|
|
233
|
-
};
|
|
234
|
-
for (const f of ["migration.json", "ops.json"]) {
|
|
235
|
-
const fail = checkFileExists(matchedPkg.dirPath, matchedPkg.dirName, f);
|
|
236
|
-
if (fail) failures.push(fail);
|
|
237
|
-
}
|
|
238
|
-
const verification = verifyMigrationHash(matchedPkg);
|
|
239
|
-
if (!verification.ok) failures.push({
|
|
240
|
-
pnCode: "PN-MIG-CHECK-001",
|
|
241
|
-
where: migrationFileRelative(matchedPkg.dirPath, "migration.json"),
|
|
242
|
-
why: `Stored hash ${verification.storedHash} does not match recomputed hash ${verification.computedHash}`,
|
|
243
|
-
fix: "Re-emit the migration package or restore from version control."
|
|
244
|
-
});
|
|
245
|
-
const snapshotFailure = checkSnapshotConsistency(matchedPkg);
|
|
246
|
-
if (snapshotFailure) failures.push(snapshotFailure);
|
|
247
|
-
} else {
|
|
248
|
-
for (const pkg of bundles) {
|
|
249
|
-
const snapshotFailure = checkSnapshotConsistency(pkg);
|
|
250
|
-
if (snapshotFailure) failures.push(snapshotFailure);
|
|
251
|
-
}
|
|
252
|
-
const allToHashes = new Set(bundles.map((p) => p.metadata.to));
|
|
253
|
-
for (const pkg of bundles) if (!(pkg.metadata.from === null || allToHashes.has(pkg.metadata.from) || pkg.metadata.from === "sha256:empty")) failures.push({
|
|
254
|
-
pnCode: "PN-MIG-CHECK-003",
|
|
255
|
-
where: migrationPathRelative(pkg.dirPath),
|
|
256
|
-
why: `Migration "${pkg.dirName}" starts from ${pkg.metadata.from} which no other migration produces`,
|
|
257
|
-
fix: "This migration is unreachable in the graph. Delete it or re-emit a connecting migration."
|
|
258
|
-
});
|
|
259
|
-
try {
|
|
260
|
-
const refs = await readRefs(refsDir);
|
|
261
|
-
for (const [name, entry] of Object.entries(refs)) if (!graph.nodes.has(entry.hash)) failures.push({
|
|
262
|
-
pnCode: "PN-MIG-CHECK-004",
|
|
263
|
-
where: relative(process.cwd(), join(refsDir, `${name}.json`)),
|
|
264
|
-
why: `Ref "${name}" points at ${entry.hash} which does not exist in the migration graph`,
|
|
265
|
-
fix: `Update the ref with \`prisma-next ref set ${name} <valid-hash>\` or delete it.`
|
|
266
|
-
});
|
|
267
|
-
} catch {}
|
|
268
|
-
for (const violation of await loadAggregateIntegrityViolations(config, migrationsDir)) failures.push(integrityViolationToCheckFailure(violation, migrationsDir));
|
|
269
|
-
}
|
|
270
|
-
if (failures.length === 0) return {
|
|
271
|
-
result: {
|
|
272
|
-
ok: true,
|
|
273
|
-
failures: [],
|
|
274
|
-
summary: "All checks passed"
|
|
275
|
-
},
|
|
276
|
-
exitCode: 0
|
|
277
|
-
};
|
|
278
|
-
return {
|
|
279
|
-
result: {
|
|
280
|
-
ok: false,
|
|
281
|
-
failures,
|
|
282
|
-
summary: `${failures.length} integrity failure(s)`
|
|
283
|
-
},
|
|
284
|
-
exitCode: 4
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
function createMigrationCheckCommand() {
|
|
288
|
-
const command = new Command("check");
|
|
289
|
-
setCommandDescriptions(command, "Verify artifact and graph integrity", "Validates that on-disk migration packages are internally consistent\n(hashes match, manifests are complete) and that the graph is well-formed\n(edges connect, refs point at valid nodes). Offline — does not consult\nthe database.");
|
|
290
|
-
setCommandExamples(command, [
|
|
291
|
-
"prisma-next migration check",
|
|
292
|
-
"prisma-next migration check 20260101-add-users",
|
|
293
|
-
"prisma-next migration check --json"
|
|
294
|
-
]);
|
|
295
|
-
setCommandSeeAlso(command, [
|
|
296
|
-
{
|
|
297
|
-
verb: "migration status",
|
|
298
|
-
oneLiner: "Show migration path and pending status"
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
verb: "migration list",
|
|
302
|
-
oneLiner: "List on-disk migrations"
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
verb: "migration graph",
|
|
306
|
-
oneLiner: "Show the migration graph topology"
|
|
307
|
-
}
|
|
308
|
-
]);
|
|
309
|
-
command.exitOverride();
|
|
310
|
-
addGlobalOptions(command).argument("[migration]", "Migration reference (directory name or hash) to check").option("--config <path>", "Path to prisma-next.config.ts").action(async (target, options) => {
|
|
311
|
-
const flags = parseGlobalFlagsOrExit(options);
|
|
312
|
-
const ui = createTerminalUI(flags);
|
|
313
|
-
let result;
|
|
314
|
-
let exitCode;
|
|
315
|
-
try {
|
|
316
|
-
({result, exitCode} = await executeMigrationCheckCommand(target, options, flags, ui));
|
|
317
|
-
} catch (error) {
|
|
318
|
-
result = {
|
|
319
|
-
ok: false,
|
|
320
|
-
failures: [],
|
|
321
|
-
summary: error instanceof Error ? error.message : String(error)
|
|
322
|
-
};
|
|
323
|
-
exitCode = 2;
|
|
324
|
-
}
|
|
325
|
-
if (flags.json) ui.output(JSON.stringify(result, null, 2));
|
|
326
|
-
else if (!flags.quiet) if (result.ok) ui.log(`✔ ${result.summary}`);
|
|
327
|
-
else {
|
|
328
|
-
for (const f of result.failures) {
|
|
329
|
-
ui.log(`✗ [${f.pnCode}] ${f.where}: ${f.why}`);
|
|
330
|
-
ui.log(` fix: ${f.fix}`);
|
|
331
|
-
}
|
|
332
|
-
ui.log(`\n${result.summary}`);
|
|
333
|
-
}
|
|
334
|
-
process.exit(exitCode);
|
|
335
|
-
});
|
|
336
|
-
return command;
|
|
337
|
-
}
|
|
338
|
-
//#endregion
|
|
339
|
-
export { createMigrationCheckCommand as t };
|
|
340
|
-
|
|
341
|
-
//# sourceMappingURL=migration-check-BiBJoYYW.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migration-check-BiBJoYYW.mjs","names":["migrationPathRelative","migrationFileRelative"],"sources":["../src/utils/integrity-violation-to-check-failure.ts","../src/commands/migration-check.ts"],"sourcesContent":["import type { IntegrityViolation } from '@prisma-next/migration-tools/aggregate';\nimport { join, relative } from 'pathe';\n\nexport interface CheckFailure {\n readonly pnCode: string;\n readonly where: string;\n readonly why: string;\n readonly fix: string;\n}\n\nfunction migrationPathRelative(dirPath: string): string {\n return relative(process.cwd(), dirPath);\n}\n\nfunction migrationFileRelative(dirPath: string, fileName: string): string {\n return join(migrationPathRelative(dirPath), fileName);\n}\n\n/**\n * Map one {@link IntegrityViolation} onto a `migration check` failure row.\n * Sole catalogue mapping from integrity violations to `PN-MIG-CHECK-*`.\n */\nexport function integrityViolationToCheckFailure(\n violation: IntegrityViolation,\n migrationsDir: string,\n): CheckFailure {\n const spaceRelative = (spaceId: string): string =>\n migrationPathRelative(join(migrationsDir, spaceId));\n const packageRelative = (spaceId: string, dirName: string): string =>\n migrationPathRelative(join(migrationsDir, spaceId, dirName));\n const refRelative = (spaceId: string, refName: string): string =>\n migrationPathRelative(join(migrationsDir, spaceId, 'refs', `${refName}.json`));\n\n switch (violation.kind) {\n case 'hashMismatch':\n return {\n pnCode: 'PN-MIG-CHECK-001',\n where: migrationFileRelative(\n join(migrationsDir, violation.spaceId, violation.dirName),\n 'migration.json',\n ),\n why: `Stored hash ${violation.stored} does not match recomputed hash ${violation.computed}`,\n fix: 'Re-emit the migration package or restore from version control.',\n };\n case 'providedInvariantsMismatch':\n return {\n pnCode: 'PN-MIG-CHECK-002',\n where: packageRelative(violation.spaceId, violation.dirName),\n why: `Migration \"${violation.dirName}\" providedInvariants in migration.json disagrees with ops.json.`,\n fix: 'Re-emit the migration package so migration.json and ops.json agree.',\n };\n case 'packageUnloadable':\n return {\n pnCode: 'PN-MIG-CHECK-002',\n where: packageRelative(violation.spaceId, violation.dirName),\n why: `Migration \"${violation.dirName}\" could not be loaded: ${violation.detail}`,\n fix: 'Re-emit the migration package or restore from version control.',\n };\n case 'sameSourceAndTarget':\n return {\n pnCode: 'PN-MIG-CHECK-007',\n where: packageRelative(violation.spaceId, violation.dirName),\n why: `Migration \"${violation.dirName}\" in space \"${violation.spaceId}\" has source equal to target (${violation.hash}) with no data invariant — a true no-op self-edge.`,\n fix: 'Add a data operation if this self-edge was meant to carry a data invariant, or delete the migration if it is a true no-op.',\n };\n case 'orphanSpaceDir':\n return {\n pnCode: 'PN-MIG-CHECK-008',\n where: spaceRelative(violation.spaceId),\n why: `Contract-space directory \"${violation.spaceId}\" exists on disk but no extension declares it.`,\n fix: 'Remove the orphan directory, or declare the extension in `extensionPacks`.',\n };\n case 'declaredButUnmigrated':\n return {\n pnCode: 'PN-MIG-CHECK-009',\n where: spaceRelative(violation.spaceId),\n why: `Extension \"${violation.spaceId}\" is declared in \\`extensionPacks\\` but has no on-disk migrations directory.`,\n fix: 'Re-emit the extension contract-space artefacts with `prisma-next contract emit` and migration planning, or remove the extension from `extensionPacks` if it is unused.',\n };\n case 'headRefMissing':\n return {\n pnCode: 'PN-MIG-CHECK-010',\n where: refRelative(violation.spaceId, 'head'),\n why: `Head ref \\`refs/head.json\\` is missing for contract space \"${violation.spaceId}\".`,\n fix: 'Re-emit the contract-space migrations and head ref artefacts, or restore `refs/head.json` from version control.',\n };\n case 'headRefNotInGraph':\n return {\n pnCode: 'PN-MIG-CHECK-011',\n where: refRelative(violation.spaceId, 'head'),\n why: `Head ref ${violation.hash} for contract space \"${violation.spaceId}\" is not present in its migration graph.`,\n fix: 'Re-emit the contract space migrations, or restore the missing migration package.',\n };\n case 'refUnreadable':\n return {\n pnCode: 'PN-MIG-CHECK-012',\n where: refRelative(violation.spaceId, violation.refName),\n why: `Ref \"${violation.refName}\" for contract space \"${violation.spaceId}\" is unreadable: ${violation.detail}`,\n fix: 'Repair or remove the corrupt ref file.',\n };\n case 'targetMismatch':\n return {\n pnCode: 'PN-MIG-CHECK-013',\n where: spaceRelative(violation.spaceId),\n why: `Contract space \"${violation.spaceId}\" targets \"${violation.actual}\" but the project targets \"${violation.expected}\".`,\n fix: 'Update the extension to target the configured database, or change the project target.',\n };\n case 'disjointness':\n return {\n pnCode: 'PN-MIG-CHECK-014',\n where: migrationPathRelative(migrationsDir),\n why: `Storage element \"${violation.element}\" is claimed by multiple contract spaces: ${violation.claimedBy.join(', ')}.`,\n fix: 'Update the contracts so each storage element is owned by exactly one contract space.',\n };\n case 'contractUnreadable':\n return {\n pnCode: 'PN-MIG-CHECK-015',\n where: migrationFileRelative(join(migrationsDir, violation.spaceId), 'contract.json'),\n why: `Contract for space \"${violation.spaceId}\" is unreadable: ${violation.detail}`,\n fix: 'Re-emit the extension contract artefacts, or fix the descriptor producing the invalid contract.',\n };\n case 'duplicateMigrationHash':\n return {\n pnCode: 'PN-MIG-CHECK-016',\n where: spaceRelative(violation.spaceId),\n why: `Multiple migrations in space \"${violation.spaceId}\" share migrationHash \"${violation.migrationHash}\" (${violation.dirNames.join(', ')}).`,\n fix: 'Re-emit one of the conflicting packages so each migrationHash is unique.',\n };\n }\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport type { IntegrityViolation } from '@prisma-next/migration-tools/aggregate';\nimport { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';\nimport { verifyMigrationHash } from '@prisma-next/migration-tools/hash';\nimport { readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport { reconstructGraph } from '@prisma-next/migration-tools/migration-graph';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { readRefs } from '@prisma-next/migration-tools/refs';\nimport { Command } from 'commander';\nimport { join, relative } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport {\n addGlobalOptions,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n} from '../utils/command-helpers';\nimport { toDeclaredExtensionsFromRaw } from '../utils/extension-pack-inputs';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport {\n type CheckFailure,\n integrityViolationToCheckFailure,\n} from '../utils/integrity-violation-to-check-failure';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\nimport { INTEGRITY_FAILED, OK, PRECONDITION } from './migration-check/exit-codes';\n\ninterface MigrationCheckOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport type { CheckFailure } from '../utils/integrity-violation-to-check-failure';\n\nexport interface MigrationCheckResult {\n readonly ok: boolean;\n readonly failures: readonly CheckFailure[];\n readonly summary: string;\n}\n\nfunction migrationPathRelative(dirPath: string): string {\n return relative(process.cwd(), dirPath);\n}\n\nfunction migrationFileRelative(dirPath: string, fileName: string): string {\n return join(migrationPathRelative(dirPath), fileName);\n}\n\nfunction checkFileExists(dirPath: string, dirName: string, fileName: string): CheckFailure | null {\n if (!existsSync(join(dirPath, fileName))) {\n return {\n pnCode: 'PN-MIG-CHECK-002',\n where: migrationFileRelative(dirPath, fileName),\n why: `${fileName} is missing from ${dirName}`,\n fix: 'Re-emit the migration package or restore from version control.',\n };\n }\n return null;\n}\n\nfunction checkSnapshotConsistency(pkg: OnDiskMigrationPackage): CheckFailure | null {\n const endContractPath = join(pkg.dirPath, 'end-contract.json');\n if (!existsSync(endContractPath)) return null;\n try {\n const raw = JSON.parse(readFileSync(endContractPath, 'utf-8')) as Record<string, unknown>;\n const storage = raw['storage'] as Record<string, unknown> | undefined;\n const snapshotHash = storage?.['storageHash'];\n if (typeof snapshotHash === 'string' && snapshotHash !== pkg.metadata.to) {\n return {\n pnCode: 'PN-MIG-CHECK-005',\n where: migrationPathRelative(pkg.dirPath),\n why: `Migration \"${pkg.dirName}\" declares to=${pkg.metadata.to} but end-contract.json has storageHash=${snapshotHash}`,\n fix: 'Re-emit the migration package so migration.json and end-contract.json agree.',\n };\n }\n } catch {\n return {\n pnCode: 'PN-MIG-CHECK-006',\n where: migrationPathRelative(pkg.dirPath),\n why: `Migration \"${pkg.dirName}\" has an unparseable end-contract.json.`,\n fix: 'Re-emit the migration package to repair the snapshot file.',\n };\n }\n return null;\n}\n\nasync function loadAggregateIntegrityViolations(\n config: Awaited<ReturnType<typeof loadConfig>>,\n migrationsDir: string,\n): Promise<readonly IntegrityViolation[]> {\n try {\n const contractJsonContent = await readFile(resolveContractPath(config), 'utf-8');\n const familyInstance = config.family.create(createControlStack(config));\n const declaredExtensions = toDeclaredExtensionsFromRaw(config.extensionPacks ?? []);\n\n const parsedAppContract: unknown = JSON.parse(contractJsonContent);\n const aggregate = await loadContractSpaceAggregate({\n migrationsDir,\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n appContract: familyInstance.deserializeContract(parsedAppContract),\n });\n return aggregate.checkIntegrity({ declaredExtensions, checkContracts: true });\n } catch {\n return [];\n }\n}\n\nasync function executeMigrationCheckCommand(\n target: string | undefined,\n options: MigrationCheckOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<{ result: MigrationCheckResult; exitCode: number }> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative, refsDir } =\n resolveMigrationPaths(options.config, config);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (target) {\n details.push({ label: 'target', value: target });\n }\n const header = formatStyledHeader({\n command: 'migration check',\n description: 'Verify artifact and graph integrity',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n const failures: CheckFailure[] = [];\n\n const loaded = await readMigrationsDir(appMigrationsDir);\n const bundles: readonly OnDiskMigrationPackage[] = loaded.packages;\n const graph = reconstructGraph(bundles);\n\n if (existsSync(appMigrationsDir)) {\n const loadedDirNames = new Set(bundles.map((p) => p.dirName));\n try {\n const entries = readdirSync(appMigrationsDir);\n for (const entry of entries) {\n if (entry.startsWith('.') || entry.startsWith('_') || entry === 'refs') continue;\n const entryPath = join(appMigrationsDir, entry);\n try {\n if (!statSync(entryPath).isDirectory()) continue;\n } catch {\n continue;\n }\n if (!loadedDirNames.has(entry)) {\n for (const f of ['migration.json', 'ops.json']) {\n const fail = checkFileExists(entryPath, entry, f);\n if (fail) failures.push(fail);\n }\n }\n }\n } catch {\n // migrations dir unreadable — skip\n }\n }\n\n if (target) {\n const refs = await readRefs(refsDir);\n const migResult = parseMigrationRef(target, { graph, refs });\n if (!migResult.ok) {\n const msg =\n migResult.failure.kind === 'not-found'\n ? `Migration \"${target}\" does not exist`\n : migResult.failure.kind === 'wrong-grammar'\n ? migResult.failure.message\n : `Invalid migration reference: \"${target}\"`;\n return {\n result: { ok: false, failures: [], summary: msg },\n exitCode: PRECONDITION,\n };\n }\n\n const matchedPkg = bundles.find(\n (p) => p.metadata.migrationHash === migResult.value.migrationHash,\n );\n if (!matchedPkg) {\n return {\n result: {\n ok: false,\n failures: [],\n summary: `Migration package for \"${target}\" not found on disk`,\n },\n exitCode: PRECONDITION,\n };\n }\n\n for (const f of ['migration.json', 'ops.json']) {\n const fail = checkFileExists(matchedPkg.dirPath, matchedPkg.dirName, f);\n if (fail) failures.push(fail);\n }\n\n const verification = verifyMigrationHash(matchedPkg);\n if (!verification.ok) {\n failures.push({\n pnCode: 'PN-MIG-CHECK-001',\n where: migrationFileRelative(matchedPkg.dirPath, 'migration.json'),\n why: `Stored hash ${verification.storedHash} does not match recomputed hash ${verification.computedHash}`,\n fix: 'Re-emit the migration package or restore from version control.',\n });\n }\n\n const snapshotFailure = checkSnapshotConsistency(matchedPkg);\n if (snapshotFailure) failures.push(snapshotFailure);\n } else {\n for (const pkg of bundles) {\n const snapshotFailure = checkSnapshotConsistency(pkg);\n if (snapshotFailure) failures.push(snapshotFailure);\n }\n\n const allToHashes = new Set(bundles.map((p) => p.metadata.to));\n for (const pkg of bundles) {\n const isReachable =\n pkg.metadata.from === null ||\n allToHashes.has(pkg.metadata.from) ||\n pkg.metadata.from === 'sha256:empty';\n if (!isReachable) {\n failures.push({\n pnCode: 'PN-MIG-CHECK-003',\n where: migrationPathRelative(pkg.dirPath),\n why: `Migration \"${pkg.dirName}\" starts from ${pkg.metadata.from} which no other migration produces`,\n fix: 'This migration is unreachable in the graph. Delete it or re-emit a connecting migration.',\n });\n }\n }\n\n try {\n const refs = await readRefs(refsDir);\n for (const [name, entry] of Object.entries(refs)) {\n if (!graph.nodes.has(entry.hash)) {\n failures.push({\n pnCode: 'PN-MIG-CHECK-004',\n where: relative(process.cwd(), join(refsDir, `${name}.json`)),\n why: `Ref \"${name}\" points at ${entry.hash} which does not exist in the migration graph`,\n fix: `Update the ref with \\`prisma-next ref set ${name} <valid-hash>\\` or delete it.`,\n });\n }\n }\n } catch {\n // Refs unreadable — skip ref checks\n }\n\n for (const violation of await loadAggregateIntegrityViolations(config, migrationsDir)) {\n failures.push(integrityViolationToCheckFailure(violation, migrationsDir));\n }\n }\n\n if (failures.length === 0) {\n return {\n result: { ok: true, failures: [], summary: 'All checks passed' },\n exitCode: OK,\n };\n }\n\n return {\n result: { ok: false, failures, summary: `${failures.length} integrity failure(s)` },\n exitCode: INTEGRITY_FAILED,\n };\n}\n\nexport function createMigrationCheckCommand(): Command {\n const command = new Command('check');\n setCommandDescriptions(\n command,\n 'Verify artifact and graph integrity',\n 'Validates that on-disk migration packages are internally consistent\\n' +\n '(hashes match, manifests are complete) and that the graph is well-formed\\n' +\n '(edges connect, refs point at valid nodes). Offline — does not consult\\n' +\n 'the database.',\n );\n setCommandExamples(command, [\n 'prisma-next migration check',\n 'prisma-next migration check 20260101-add-users',\n 'prisma-next migration check --json',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n ]);\n command.exitOverride();\n addGlobalOptions(command)\n .argument('[migration]', 'Migration reference (directory name or hash) to check')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationCheckOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n\n let result: MigrationCheckResult;\n let exitCode: number;\n try {\n ({ result, exitCode } = await executeMigrationCheckCommand(target, options, flags, ui));\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n result = { ok: false, failures: [], summary: msg };\n exitCode = PRECONDITION;\n }\n\n if (flags.json) {\n ui.output(JSON.stringify(result, null, 2));\n } else if (!flags.quiet) {\n if (result.ok) {\n ui.log(`✔ ${result.summary}`);\n } else {\n for (const f of result.failures) {\n ui.log(`✗ [${f.pnCode}] ${f.where}: ${f.why}`);\n ui.log(` fix: ${f.fix}`);\n }\n ui.log(`\\n${result.summary}`);\n }\n }\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|