prisma-next 0.5.0-dev.67 → 0.5.0-dev.68
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 +8 -8
- package/dist/cli.mjs.map +1 -1
- package/dist/client-0ZX24FXF.mjs +1398 -0
- package/dist/client-0ZX24FXF.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.d.mts.map +1 -1
- package/dist/commands/db-init.mjs +7 -5
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +2 -2
- package/dist/commands/db-sign.mjs +2 -2
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +7 -5
- 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 -320
- package/dist/commands/migration-apply.mjs +11 -11
- package/dist/commands/migration-apply.mjs.map +1 -1
- package/dist/commands/migration-new.mjs +5 -5
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -344
- package/dist/commands/migration-ref.d.mts +1 -1
- package/dist/commands/migration-ref.mjs +1 -1
- package/dist/commands/migration-show.d.mts +1 -1
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +8 -7
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.mjs +1 -1
- package/dist/{contract-emit-B0nGrDtk.mjs → contract-emit-DkMqO7f2.mjs} +2 -2
- package/dist/{contract-emit-B0nGrDtk.mjs.map → contract-emit-DkMqO7f2.mjs.map} +1 -1
- package/dist/{contract-infer-BjMJaOOa.mjs → contract-infer-BDKAE0B0.mjs} +3 -3
- package/dist/{contract-infer-BjMJaOOa.mjs.map → contract-infer-BDKAE0B0.mjs.map} +1 -1
- package/dist/db-verify-B4TdDKOI.mjs +403 -0
- package/dist/db-verify-B4TdDKOI.mjs.map +1 -0
- package/dist/exports/control-api.d.mts +201 -3
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.d.mts.map +1 -1
- package/dist/exports/index.mjs +17 -17
- package/dist/exports/index.mjs.map +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{init-C3qdc0Sh.mjs → init-Deo7U8_U.mjs} +2 -2
- package/dist/{init-C3qdc0Sh.mjs.map → init-Deo7U8_U.mjs.map} +1 -1
- package/dist/{inspect-live-schema-33rxnu0K.mjs → inspect-live-schema-BAgQMYpD.mjs} +3 -3
- package/dist/{inspect-live-schema-33rxnu0K.mjs.map → inspect-live-schema-BAgQMYpD.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-DQo4R0XT.mjs → migration-command-scaffold-B8J702Uh.mjs} +3 -3
- package/dist/{migration-command-scaffold-DQo4R0XT.mjs.map → migration-command-scaffold-B8J702Uh.mjs.map} +1 -1
- package/dist/migration-plan-BcKNnTM7.mjs +530 -0
- package/dist/migration-plan-BcKNnTM7.mjs.map +1 -0
- package/dist/{migration-status-C_2FSkbf.mjs → migration-status-CjwB2of-.mjs} +6 -6
- package/dist/{migration-status-C_2FSkbf.mjs.map → migration-status-CjwB2of-.mjs.map} +1 -1
- package/dist/{output-BTgnZ5c_.mjs → output-DnjfCC_u.mjs} +1 -1
- package/dist/{output-BTgnZ5c_.mjs.map → output-DnjfCC_u.mjs.map} +1 -1
- package/dist/{result-handler-C0QeiqKO.mjs → result-handler-DWb1rFS-.mjs} +18 -3
- package/dist/result-handler-DWb1rFS-.mjs.map +1 -0
- package/package.json +11 -11
- package/dist/client-CW1hcUtM.mjs +0 -1025
- package/dist/client-CW1hcUtM.mjs.map +0 -1
- package/dist/commands/db-verify.mjs.map +0 -1
- package/dist/commands/migration-plan.mjs.map +0 -1
- package/dist/result-handler-C0QeiqKO.mjs.map +0 -1
- /package/dist/{cli-errors-BWn943z2.d.mts → cli-errors-QH8kf-C2.d.mts} +0 -0
|
@@ -1,345 +1,2 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import { _ as errorUnexpected, a as errorContractValidationFailed, f as errorMigrationPlanningFailed, h as errorTargetMigrationNotSupported, l as errorFileNotFound, m as errorRuntime, t as CliStructuredError, v as mapMigrationToolsError } from "../cli-errors-D3_sMh2K.mjs";
|
|
3
|
-
import { t as assertFrameworkComponentsCompatible } from "../framework-components-gwAHl7ml.mjs";
|
|
4
|
-
import { t as TerminalUI } from "../terminal-ui-zaRDhJnP.mjs";
|
|
5
|
-
import { a as loadMigrationPackages, c as resolveContractPath, d as setCommandDescriptions, f as setCommandExamples, g as parseGlobalFlags, i as getTargetMigrations, l as resolveMigrationPaths, n as addGlobalOptions, t as handleResult, y as formatStyledHeader } from "../result-handler-C0QeiqKO.mjs";
|
|
6
|
-
import { Command } from "commander";
|
|
7
|
-
import { getEmittedArtifactPaths } from "@prisma-next/emitter";
|
|
8
|
-
import { notOk, ok } from "@prisma-next/utils/result";
|
|
9
|
-
import { join, relative } from "pathe";
|
|
10
|
-
import { readFile } from "node:fs/promises";
|
|
11
|
-
import { APP_SPACE_ID, createControlStack, hasOperationPreview } from "@prisma-next/framework-components/control";
|
|
12
|
-
import { copyFilesWithRename, formatMigrationDirName, writeMigrationPackage } from "@prisma-next/migration-tools/io";
|
|
13
|
-
import { findLatestMigration } from "@prisma-next/migration-tools/migration-graph";
|
|
14
|
-
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
15
|
-
import { computeMigrationHash } from "@prisma-next/migration-tools/hash";
|
|
16
|
-
import { writeMigrationTs } from "@prisma-next/migration-tools/migration-ts";
|
|
17
|
-
import { deriveProvidedInvariants } from "@prisma-next/migration-tools/invariants";
|
|
18
|
-
//#region src/commands/migration-plan.ts
|
|
19
|
-
async function executeMigrationPlanCommand(options, flags, ui, startTime) {
|
|
20
|
-
const config = await loadConfig(options.config);
|
|
21
|
-
const { configPath, migrationsDir, migrationsRelative } = resolveMigrationPaths(options.config, config);
|
|
22
|
-
const contractPathAbsolute = resolveContractPath(config);
|
|
23
|
-
const contractPath = relative(process.cwd(), contractPathAbsolute);
|
|
24
|
-
if (!flags.json && !flags.quiet) {
|
|
25
|
-
const details = [
|
|
26
|
-
{
|
|
27
|
-
label: "config",
|
|
28
|
-
value: configPath
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
label: "contract",
|
|
32
|
-
value: contractPath
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
label: "migrations",
|
|
36
|
-
value: migrationsRelative
|
|
37
|
-
}
|
|
38
|
-
];
|
|
39
|
-
if (options.from) details.push({
|
|
40
|
-
label: "from",
|
|
41
|
-
value: options.from
|
|
42
|
-
});
|
|
43
|
-
if (options.name) details.push({
|
|
44
|
-
label: "name",
|
|
45
|
-
value: options.name
|
|
46
|
-
});
|
|
47
|
-
const header = formatStyledHeader({
|
|
48
|
-
command: "migration plan",
|
|
49
|
-
description: "Plan a migration from contract changes",
|
|
50
|
-
url: "https://pris.ly/migration-plan",
|
|
51
|
-
details,
|
|
52
|
-
flags
|
|
53
|
-
});
|
|
54
|
-
ui.stderr(header);
|
|
55
|
-
}
|
|
56
|
-
let contractJsonContent;
|
|
57
|
-
try {
|
|
58
|
-
contractJsonContent = await readFile(contractPathAbsolute, "utf-8");
|
|
59
|
-
} catch (error) {
|
|
60
|
-
if (error instanceof Error && error.code === "ENOENT") return notOk(errorFileNotFound(contractPathAbsolute, {
|
|
61
|
-
why: `Contract file not found at ${contractPathAbsolute}`,
|
|
62
|
-
fix: `Run \`prisma-next contract emit\` to generate ${contractPath}, or update \`config.contract.output\` in ${configPath}`
|
|
63
|
-
}));
|
|
64
|
-
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}` }));
|
|
65
|
-
}
|
|
66
|
-
let toContractJson;
|
|
67
|
-
try {
|
|
68
|
-
toContractJson = JSON.parse(contractJsonContent);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
return notOk(errorContractValidationFailed(`Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`, { where: { path: contractPathAbsolute } }));
|
|
71
|
-
}
|
|
72
|
-
const rawStorageHash = toContractJson.storage?.storageHash;
|
|
73
|
-
if (typeof rawStorageHash !== "string") return notOk(errorContractValidationFailed("Contract is missing storageHash", { where: { path: contractPathAbsolute } }));
|
|
74
|
-
const toStorageHash = rawStorageHash;
|
|
75
|
-
let fromContract = null;
|
|
76
|
-
let fromHash = null;
|
|
77
|
-
let fromContractSourceDir = null;
|
|
78
|
-
try {
|
|
79
|
-
const { bundles, graph } = await loadMigrationPackages(migrationsDir);
|
|
80
|
-
if (options.from) {
|
|
81
|
-
const resolved = resolveBundleByPrefix(bundles, options.from);
|
|
82
|
-
if (!resolved.ok) {
|
|
83
|
-
const f = resolved.failure;
|
|
84
|
-
return notOk(f.reason === "ambiguous" ? errorRuntime("Multiple matching migrations found", {
|
|
85
|
-
why: `Prefix "${options.from}" matches ${f.count} migrations in ${migrationsRelative}`,
|
|
86
|
-
fix: "Provide a longer prefix to disambiguate, or omit --from to use the latest migration target."
|
|
87
|
-
}) : errorRuntime("Starting contract not found", {
|
|
88
|
-
why: `No migration with to hash matching "${options.from}" exists in ${migrationsRelative}`,
|
|
89
|
-
fix: "Check that the --from hash matches a known migration target hash, or omit --from to use the latest migration target."
|
|
90
|
-
}));
|
|
91
|
-
}
|
|
92
|
-
fromHash = resolved.value.metadata.to;
|
|
93
|
-
fromContract = resolved.value.metadata.toContract;
|
|
94
|
-
fromContractSourceDir = resolved.value.dirPath;
|
|
95
|
-
} else {
|
|
96
|
-
const latestMigration = findLatestMigration(graph);
|
|
97
|
-
if (latestMigration) {
|
|
98
|
-
fromHash = latestMigration.to;
|
|
99
|
-
const leafPkg = bundles.find((p) => p.metadata.migrationHash === latestMigration.migrationHash);
|
|
100
|
-
if (leafPkg) {
|
|
101
|
-
fromContract = leafPkg.metadata.toContract;
|
|
102
|
-
fromContractSourceDir = leafPkg.dirPath;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
} catch (error) {
|
|
107
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
108
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
109
|
-
return notOk(errorUnexpected(message, { why: `Unexpected error while loading migrations: ${message}` }));
|
|
110
|
-
}
|
|
111
|
-
if (fromHash === toStorageHash) return ok({
|
|
112
|
-
ok: true,
|
|
113
|
-
noOp: true,
|
|
114
|
-
from: fromHash,
|
|
115
|
-
to: toStorageHash,
|
|
116
|
-
operations: [],
|
|
117
|
-
summary: "No changes detected between contracts",
|
|
118
|
-
timings: { total: Date.now() - startTime }
|
|
119
|
-
});
|
|
120
|
-
const migrations = getTargetMigrations(config.target);
|
|
121
|
-
if (!migrations) return notOk(errorTargetMigrationNotSupported({ why: `Target "${config.target.id}" does not support migrations` }));
|
|
122
|
-
const frameworkComponents = assertFrameworkComponentsCompatible(config.family.familyId, config.target.targetId, [
|
|
123
|
-
config.target,
|
|
124
|
-
config.adapter,
|
|
125
|
-
...config.extensionPacks ?? []
|
|
126
|
-
]);
|
|
127
|
-
const timestamp = /* @__PURE__ */ new Date();
|
|
128
|
-
const packageDir = join(migrationsDir, formatMigrationDirName(timestamp, options.name ?? "migration"));
|
|
129
|
-
const baseMetadata = {
|
|
130
|
-
from: fromHash,
|
|
131
|
-
to: toStorageHash,
|
|
132
|
-
fromContract,
|
|
133
|
-
toContract: toContractJson,
|
|
134
|
-
hints: {
|
|
135
|
-
used: [],
|
|
136
|
-
applied: [],
|
|
137
|
-
plannerVersion: "2.0.0"
|
|
138
|
-
},
|
|
139
|
-
labels: [],
|
|
140
|
-
createdAt: timestamp.toISOString()
|
|
141
|
-
};
|
|
142
|
-
try {
|
|
143
|
-
const stack = createControlStack(config);
|
|
144
|
-
const familyInstance = config.family.create(stack);
|
|
145
|
-
const planner = migrations.createPlanner(familyInstance);
|
|
146
|
-
const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);
|
|
147
|
-
const plannerResult = planner.plan({
|
|
148
|
-
contract: toContractJson,
|
|
149
|
-
schema: fromSchema,
|
|
150
|
-
policy: { allowedOperationClasses: [
|
|
151
|
-
"additive",
|
|
152
|
-
"widening",
|
|
153
|
-
"destructive",
|
|
154
|
-
"data"
|
|
155
|
-
] },
|
|
156
|
-
fromContract,
|
|
157
|
-
frameworkComponents,
|
|
158
|
-
spaceId: APP_SPACE_ID
|
|
159
|
-
});
|
|
160
|
-
if (plannerResult.kind === "failure") return notOk(errorMigrationPlanningFailed({ conflicts: plannerResult.conflicts }));
|
|
161
|
-
let plannedOps = [];
|
|
162
|
-
let hasPlaceholders = false;
|
|
163
|
-
try {
|
|
164
|
-
plannedOps = plannerResult.plan.operations;
|
|
165
|
-
if (plannedOps.length === 0) return notOk(errorMigrationPlanningFailed({ conflicts: [{
|
|
166
|
-
kind: "unsupportedChange",
|
|
167
|
-
summary: "Contract changed but planner produced no operations. This indicates unsupported or ignored changes."
|
|
168
|
-
}] }));
|
|
169
|
-
} catch (e) {
|
|
170
|
-
if (CliStructuredError.is(e) && e.domain === "MIG" && e.code === "2001") hasPlaceholders = true;
|
|
171
|
-
else throw e;
|
|
172
|
-
}
|
|
173
|
-
const migrationTsContent = plannerResult.plan.renderTypeScript();
|
|
174
|
-
const opsForWrite = hasPlaceholders ? [] : plannedOps;
|
|
175
|
-
const metadataWithInvariants = {
|
|
176
|
-
...baseMetadata,
|
|
177
|
-
providedInvariants: deriveProvidedInvariants(opsForWrite)
|
|
178
|
-
};
|
|
179
|
-
await writeMigrationPackage(packageDir, {
|
|
180
|
-
...metadataWithInvariants,
|
|
181
|
-
migrationHash: computeMigrationHash(metadataWithInvariants, opsForWrite)
|
|
182
|
-
}, opsForWrite);
|
|
183
|
-
const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);
|
|
184
|
-
await copyFilesWithRename(packageDir, [{
|
|
185
|
-
sourcePath: destinationArtifacts.jsonPath,
|
|
186
|
-
destName: "end-contract.json"
|
|
187
|
-
}, {
|
|
188
|
-
sourcePath: destinationArtifacts.dtsPath,
|
|
189
|
-
destName: "end-contract.d.ts"
|
|
190
|
-
}]);
|
|
191
|
-
if (fromContractSourceDir !== null) {
|
|
192
|
-
const sourceArtifacts = getEmittedArtifactPaths(join(fromContractSourceDir, "end-contract.json"));
|
|
193
|
-
await copyFilesWithRename(packageDir, [{
|
|
194
|
-
sourcePath: sourceArtifacts.jsonPath,
|
|
195
|
-
destName: "start-contract.json"
|
|
196
|
-
}, {
|
|
197
|
-
sourcePath: sourceArtifacts.dtsPath,
|
|
198
|
-
destName: "start-contract.d.ts"
|
|
199
|
-
}]);
|
|
200
|
-
}
|
|
201
|
-
await writeMigrationTs(packageDir, migrationTsContent);
|
|
202
|
-
if (hasPlaceholders) return ok({
|
|
203
|
-
ok: true,
|
|
204
|
-
noOp: false,
|
|
205
|
-
from: fromHash,
|
|
206
|
-
to: toStorageHash,
|
|
207
|
-
dir: relative(process.cwd(), packageDir),
|
|
208
|
-
operations: [],
|
|
209
|
-
pendingPlaceholders: true,
|
|
210
|
-
summary: "Planned migration with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit",
|
|
211
|
-
timings: { total: Date.now() - startTime }
|
|
212
|
-
});
|
|
213
|
-
const preview = hasOperationPreview(familyInstance) ? familyInstance.toOperationPreview(plannedOps) : void 0;
|
|
214
|
-
return ok({
|
|
215
|
-
ok: true,
|
|
216
|
-
noOp: false,
|
|
217
|
-
from: fromHash,
|
|
218
|
-
to: toStorageHash,
|
|
219
|
-
dir: relative(process.cwd(), packageDir),
|
|
220
|
-
operations: plannedOps.map((op) => ({
|
|
221
|
-
id: op.id,
|
|
222
|
-
label: op.label,
|
|
223
|
-
operationClass: op.operationClass
|
|
224
|
-
})),
|
|
225
|
-
...preview !== void 0 ? { preview } : {},
|
|
226
|
-
summary: `Planned ${plannedOps.length} operation(s)`,
|
|
227
|
-
timings: { total: Date.now() - startTime }
|
|
228
|
-
});
|
|
229
|
-
} catch (error) {
|
|
230
|
-
if (CliStructuredError.is(error)) return notOk(error);
|
|
231
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
232
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
233
|
-
return notOk(errorUnexpected(message, { why: `Unexpected error during migration plan: ${message}` }));
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
function createMigrationPlanCommand() {
|
|
237
|
-
const command = new Command("plan");
|
|
238
|
-
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.");
|
|
239
|
-
setCommandExamples(command, ["prisma-next migration plan", "prisma-next migration plan --name add-users-table"]);
|
|
240
|
-
addGlobalOptions(command).option("--config <path>", "Path to prisma-next.config.ts").option("--name <slug>", "Name slug for the migration directory", "migration").option("--from <hash>", "Explicit starting contract hash (overrides latest migration target)").action(async (options) => {
|
|
241
|
-
const flags = parseGlobalFlags(options);
|
|
242
|
-
const startTime = Date.now();
|
|
243
|
-
const ui = new TerminalUI({
|
|
244
|
-
color: flags.color,
|
|
245
|
-
interactive: flags.interactive
|
|
246
|
-
});
|
|
247
|
-
const exitCode = handleResult(await executeMigrationPlanCommand(options, flags, ui, startTime), flags, ui, (planResult) => {
|
|
248
|
-
if (flags.json) ui.output(JSON.stringify(planResult, null, 2));
|
|
249
|
-
else if (!flags.quiet) ui.log(formatMigrationPlanOutput(planResult, flags));
|
|
250
|
-
});
|
|
251
|
-
process.exit(exitCode);
|
|
252
|
-
});
|
|
253
|
-
return command;
|
|
254
|
-
}
|
|
255
|
-
function formatMigrationPlanOutput(result, flags) {
|
|
256
|
-
const lines = [];
|
|
257
|
-
const useColor = flags.color !== false;
|
|
258
|
-
const green_ = useColor ? (s) => `\x1b[32m${s}\x1b[0m` : (s) => s;
|
|
259
|
-
const yellow_ = useColor ? (s) => `\x1b[33m${s}\x1b[0m` : (s) => s;
|
|
260
|
-
const dim_ = useColor ? (s) => `\x1b[2m${s}\x1b[0m` : (s) => s;
|
|
261
|
-
if (result.noOp) {
|
|
262
|
-
lines.push(`${green_("✔")} No changes detected`);
|
|
263
|
-
lines.push(dim_(` from: ${result.from}`));
|
|
264
|
-
lines.push(dim_(` to: ${result.to}`));
|
|
265
|
-
return lines.join("\n");
|
|
266
|
-
}
|
|
267
|
-
if (result.pendingPlaceholders) {
|
|
268
|
-
lines.push(`${yellow_("⚠")} ${result.summary}`);
|
|
269
|
-
lines.push("");
|
|
270
|
-
lines.push(dim_(`from: ${result.from}`));
|
|
271
|
-
lines.push(dim_(`to: ${result.to}`));
|
|
272
|
-
if (result.dir) lines.push(dim_(`dir: ${result.dir}`));
|
|
273
|
-
lines.push("");
|
|
274
|
-
lines.push("Open migration.ts and replace each `placeholder(...)` call with your actual query.");
|
|
275
|
-
lines.push(`Then run: ${green_(`node ${result.dir ?? "<dir>"}/migration.ts`)}`);
|
|
276
|
-
return lines.join("\n");
|
|
277
|
-
}
|
|
278
|
-
lines.push(`${green_("✔")} ${result.summary}`);
|
|
279
|
-
lines.push("");
|
|
280
|
-
if (result.operations.length > 0) {
|
|
281
|
-
lines.push(dim_("│"));
|
|
282
|
-
for (let i = 0; i < result.operations.length; i++) {
|
|
283
|
-
const op = result.operations[i];
|
|
284
|
-
const treeChar = i === result.operations.length - 1 ? "└" : "├";
|
|
285
|
-
const opClassLabel = op.operationClass === "destructive" ? yellow_(`[${op.operationClass}]`) : dim_(`[${op.operationClass}]`);
|
|
286
|
-
lines.push(`${dim_(treeChar)}─ ${op.label} ${opClassLabel}`);
|
|
287
|
-
}
|
|
288
|
-
if (result.operations.some((op) => op.operationClass === "destructive")) {
|
|
289
|
-
lines.push("");
|
|
290
|
-
lines.push(`${yellow_("⚠")} This migration contains destructive operations that may cause data loss.`);
|
|
291
|
-
}
|
|
292
|
-
lines.push("");
|
|
293
|
-
}
|
|
294
|
-
lines.push(dim_(`from: ${result.from}`));
|
|
295
|
-
lines.push(dim_(`to: ${result.to}`));
|
|
296
|
-
if (result.dir) lines.push(dim_(`dir: ${result.dir}`));
|
|
297
|
-
lines.push("");
|
|
298
|
-
lines.push(`Next: review ${green_(result.dir ?? "<dir>")} if needed, then run ${green_("prisma-next migration apply")}.`);
|
|
299
|
-
if (result.preview && result.preview.statements.length > 0) {
|
|
300
|
-
const allSql = result.preview.statements.every((s) => s.language === "sql");
|
|
301
|
-
lines.push("");
|
|
302
|
-
lines.push(dim_(allSql ? "DDL preview" : "Operation preview"));
|
|
303
|
-
lines.push("");
|
|
304
|
-
for (const statement of result.preview.statements) {
|
|
305
|
-
const trimmed = statement.text.trim();
|
|
306
|
-
if (!trimmed) continue;
|
|
307
|
-
const line = statement.language === "sql" && !trimmed.endsWith(";") ? `${trimmed};` : trimmed;
|
|
308
|
-
lines.push(line);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
if (flags.verbose && result.timings) {
|
|
312
|
-
lines.push("");
|
|
313
|
-
lines.push(dim_(`Total time: ${result.timings.total}ms`));
|
|
314
|
-
}
|
|
315
|
-
return lines.join("\n");
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Resolve a migration package by **target contract hash** (`metadata.to`)
|
|
319
|
-
* using exact match or prefix match.
|
|
320
|
-
*
|
|
321
|
-
* Note: matches `metadata.to` (the contract hash this migration produces),
|
|
322
|
-
* not `metadata.migrationHash` (the package's content-addressed identity).
|
|
323
|
-
* Tries exact match first, then prefix match (auto-prepending `sha256:` when
|
|
324
|
-
* the needle omits the scheme). Returns the matched package on success, or a
|
|
325
|
-
* discriminated failure indicating whether the prefix was ambiguous or simply
|
|
326
|
-
* not found.
|
|
327
|
-
*
|
|
328
|
-
* @internal Exported for testing only.
|
|
329
|
-
*/
|
|
330
|
-
function resolveBundleByPrefix(bundles, needle) {
|
|
331
|
-
const exact = bundles.find((p) => p.metadata.to === needle);
|
|
332
|
-
if (exact) return ok(exact);
|
|
333
|
-
const prefixWithScheme = needle.startsWith("sha256:") ? needle : `sha256:${needle}`;
|
|
334
|
-
const candidates = bundles.filter((p) => p.metadata.to.startsWith(prefixWithScheme));
|
|
335
|
-
if (candidates.length === 1) return ok(candidates[0]);
|
|
336
|
-
if (candidates.length > 1) return notOk({
|
|
337
|
-
reason: "ambiguous",
|
|
338
|
-
count: candidates.length
|
|
339
|
-
});
|
|
340
|
-
return notOk({ reason: "not-found" });
|
|
341
|
-
}
|
|
342
|
-
//#endregion
|
|
1
|
+
import { n as resolveBundleByPrefix, t as createMigrationPlanCommand } from "../migration-plan-BcKNnTM7.mjs";
|
|
343
2
|
export { createMigrationPlanCommand, resolveBundleByPrefix };
|
|
344
|
-
|
|
345
|
-
//# sourceMappingURL=migration-plan.mjs.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as CliStructuredError } from "../cli-errors-
|
|
1
|
+
import { t as CliStructuredError } from "../cli-errors-QH8kf-C2.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { Result } from "@prisma-next/utils/result";
|
|
4
4
|
import { RefEntry } from "@prisma-next/migration-tools/refs";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { _ as errorUnexpected, m as errorRuntime, t as CliStructuredError, v as mapMigrationToolsError } from "../cli-errors-D3_sMh2K.mjs";
|
|
3
3
|
import { t as TerminalUI } from "../terminal-ui-zaRDhJnP.mjs";
|
|
4
|
-
import { _ as formatCommandHelp, d as setCommandDescriptions, g as parseGlobalFlags, l as resolveMigrationPaths, n as addGlobalOptions, t as handleResult } from "../result-handler-
|
|
4
|
+
import { _ as formatCommandHelp, d as setCommandDescriptions, g as parseGlobalFlags, l as resolveMigrationPaths, n as addGlobalOptions, t as handleResult } from "../result-handler-DWb1rFS-.mjs";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
7
7
|
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as CliStructuredError } from "../cli-errors-
|
|
1
|
+
import { t as CliStructuredError } from "../cli-errors-QH8kf-C2.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { Result } from "@prisma-next/utils/result";
|
|
4
4
|
import { OperationPreview } from "@prisma-next/framework-components/control";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-show.d.mts","names":[],"sources":["../../src/commands/migration-show.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"migration-show.d.mts","names":[],"sources":["../../src/commands/migration-show.ts"],"mappings":";;;;;;;UAuCiB,mBAAA;EAAA,SACN,EAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,SAAA;EAAA,SACA,UAAA;IAAA,SACE,EAAA;IAAA,SACA,KAAA;IAAA,SACA,cAAA;EAAA;EAHF;;;;;;EAAA,SAWA,OAAA,EAAS,gBAAA;EAAA,SACT,OAAA;AAAA;AAAA,iBAOK,mBAAA,CACd,QAAA,WAAmB,sBAAA,IACnB,MAAA,WACC,MAAA,CAAO,sBAAA,EAAwB,kBAAA;AAAA,iBAsJlB,0BAAA,CAAA,GAA8B,OAAA"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { _ as errorUnexpected, m as errorRuntime, v as mapMigrationToolsError } from "../cli-errors-D3_sMh2K.mjs";
|
|
3
3
|
import { t as TerminalUI } from "../terminal-ui-zaRDhJnP.mjs";
|
|
4
|
-
import { d as setCommandDescriptions, f as setCommandExamples, g as parseGlobalFlags, n as addGlobalOptions, t as handleResult, y as formatStyledHeader } from "../result-handler-
|
|
5
|
-
import { t as createControlClient } from "../client-
|
|
4
|
+
import { d as setCommandDescriptions, f as setCommandExamples, g as parseGlobalFlags, n as addGlobalOptions, t as handleResult, y as formatStyledHeader } from "../result-handler-DWb1rFS-.mjs";
|
|
5
|
+
import { t as createControlClient } from "../client-0ZX24FXF.mjs";
|
|
6
6
|
import { a as formatMigrationShowOutput } from "../migrations-CIK94AJf.mjs";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
9
9
|
import { relative, resolve } from "pathe";
|
|
10
10
|
import { readMigrationPackage, readMigrationsDir } from "@prisma-next/migration-tools/io";
|
|
11
11
|
import { findLatestMigration, reconstructGraph } from "@prisma-next/migration-tools/migration-graph";
|
|
12
|
+
import { APP_SPACE_ID, spaceMigrationDirectory } from "@prisma-next/migration-tools/spaces";
|
|
12
13
|
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
13
14
|
//#region src/commands/migration-show.ts
|
|
14
15
|
function looksLikePath(target) {
|
|
@@ -30,15 +31,15 @@ function resolveByHashPrefix(packages, prefix) {
|
|
|
30
31
|
async function executeMigrationShowCommand(target, options, flags, ui) {
|
|
31
32
|
const config = await loadConfig(options.config);
|
|
32
33
|
const configPath = options.config ? relative(process.cwd(), resolve(options.config)) : "prisma-next.config.ts";
|
|
33
|
-
const
|
|
34
|
-
const
|
|
34
|
+
const appMigrationsDir = spaceMigrationDirectory(resolve(options.config ? resolve(options.config, "..") : process.cwd(), config.migrations?.dir ?? "migrations"), APP_SPACE_ID);
|
|
35
|
+
const appMigrationsRelative = relative(process.cwd(), appMigrationsDir);
|
|
35
36
|
if (!flags.json && !flags.quiet) {
|
|
36
37
|
const details = [{
|
|
37
38
|
label: "config",
|
|
38
39
|
value: configPath
|
|
39
40
|
}, {
|
|
40
41
|
label: "migrations",
|
|
41
|
-
value:
|
|
42
|
+
value: appMigrationsRelative
|
|
42
43
|
}];
|
|
43
44
|
if (target) details.push({
|
|
44
45
|
label: "target",
|
|
@@ -56,9 +57,9 @@ async function executeMigrationShowCommand(target, options, flags, ui) {
|
|
|
56
57
|
try {
|
|
57
58
|
if (target && looksLikePath(target)) pkg = await readMigrationPackage(resolve(target));
|
|
58
59
|
else {
|
|
59
|
-
const allPackages = await readMigrationsDir(
|
|
60
|
+
const allPackages = await readMigrationsDir(appMigrationsDir);
|
|
60
61
|
if (allPackages.length === 0) return notOk(errorRuntime("No migrations found", {
|
|
61
|
-
why: `No migration packages found in ${
|
|
62
|
+
why: `No migration packages found in ${appMigrationsRelative}`,
|
|
62
63
|
fix: "Run `prisma-next migration plan` to create a migration first."
|
|
63
64
|
}));
|
|
64
65
|
if (target) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-show.mjs","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import type {\n MigrationPlanOperation,\n OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport {\n findLatestMigration,\n reconstructGraph,\n} from '@prisma-next/migration-tools/migration-graph';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n type CliStructuredError,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string | null;\n readonly to: string;\n readonly migrationHash: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the migration's operations. Replaces\n * the previous string-array DDL field. Always defined; statements is empty\n * for a no-op migration or a family that does not implement the\n * `OperationPreviewCapable` capability.\n */\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveByHashPrefix(\n packages: readonly OnDiskMigrationPackage[],\n prefix: string,\n): Result<OnDiskMigrationPackage, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const matches = packages.filter((p) => p.metadata.migrationHash.startsWith(normalizedPrefix));\n\n if (matches.length === 1) {\n return ok(matches[0]!);\n }\n\n if (matches.length === 0) {\n return notOk(\n errorRuntime('No migration found matching prefix', {\n why: `No migration has a migrationHash starting with \"${normalizedPrefix}\"`,\n fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',\n }),\n );\n }\n\n const candidates = matches.map((p) => ` ${p.dirName} ${p.metadata.migrationHash}`).join('\\n');\n return notOk(\n errorRuntime('Ambiguous hash prefix', {\n why: `Multiple migrations match prefix \"${normalizedPrefix}\":\\n${candidates}`,\n fix: 'Provide a longer prefix to uniquely identify the migration.',\n }),\n );\n}\n\nasync function executeMigrationShowCommand(\n target: string | undefined,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (target) {\n details.push({ label: 'target', value: target });\n }\n const header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let pkg: OnDiskMigrationPackage;\n\n try {\n if (target && looksLikePath(target)) {\n pkg = await readMigrationPackage(resolve(target));\n } else {\n const allPackages = await readMigrationsDir(migrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${migrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n\n if (target) {\n const resolved = resolveByHashPrefix(allPackages, target);\n if (!resolved.ok) return resolved;\n pkg = resolved.value;\n } else {\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: 'No latest migration found in the migration history',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n if (!leafPkg) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `Latest migration ${latestMigration.dirName} does not match any package`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n pkg = leafPkg;\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n\n // `migration show` is an offline command; the control client is constructed\n // purely to dispatch the family-specific `toOperationPreview` capability and\n // is not connected to a database.\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...(config.driver ? { driver: config.driver } : {}),\n extensionPacks: config.extensionPacks ?? [],\n });\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n\n const result: MigrationShowResult = {\n ok: true,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.metadata.from,\n to: pkg.metadata.to,\n migrationHash: pkg.metadata.migrationHash,\n createdAt: pkg.metadata.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n preview,\n summary: `${ops.length} operation(s)`,\n };\n return ok(result);\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, statement preview, and metadata for a migration package.\\n' +\n 'Accepts a directory path, a hash prefix (git-style), or defaults to the\\n' +\n 'latest migration.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n addGlobalOptions(command)\n .argument('[target]', 'Migration directory path or migrationHash prefix (defaults to latest)')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"migration-show.mjs","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import type {\n MigrationPlanOperation,\n OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport {\n findLatestMigration,\n reconstructGraph,\n} from '@prisma-next/migration-tools/migration-graph';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { APP_SPACE_ID, spaceMigrationDirectory } from '@prisma-next/migration-tools/spaces';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n type CliStructuredError,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string | null;\n readonly to: string;\n readonly migrationHash: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the migration's operations. Replaces\n * the previous string-array DDL field. Always defined; statements is empty\n * for a no-op migration or a family that does not implement the\n * `OperationPreviewCapable` capability.\n */\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveByHashPrefix(\n packages: readonly OnDiskMigrationPackage[],\n prefix: string,\n): Result<OnDiskMigrationPackage, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const matches = packages.filter((p) => p.metadata.migrationHash.startsWith(normalizedPrefix));\n\n if (matches.length === 1) {\n return ok(matches[0]!);\n }\n\n if (matches.length === 0) {\n return notOk(\n errorRuntime('No migration found matching prefix', {\n why: `No migration has a migrationHash starting with \"${normalizedPrefix}\"`,\n fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',\n }),\n );\n }\n\n const candidates = matches.map((p) => ` ${p.dirName} ${p.metadata.migrationHash}`).join('\\n');\n return notOk(\n errorRuntime('Ambiguous hash prefix', {\n why: `Multiple migrations match prefix \"${normalizedPrefix}\":\\n${candidates}`,\n fix: 'Provide a longer prefix to uniquely identify the migration.',\n }),\n );\n}\n\nasync function executeMigrationShowCommand(\n target: string | undefined,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n const migrationsDirRoot = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const appMigrationsDir = spaceMigrationDirectory(migrationsDirRoot, APP_SPACE_ID);\n const appMigrationsRelative = relative(process.cwd(), appMigrationsDir);\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 show',\n description: 'Display migration package contents',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let pkg: OnDiskMigrationPackage;\n\n try {\n if (target && looksLikePath(target)) {\n pkg = await readMigrationPackage(resolve(target));\n } else {\n const allPackages = await readMigrationsDir(appMigrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${appMigrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n\n if (target) {\n const resolved = resolveByHashPrefix(allPackages, target);\n if (!resolved.ok) return resolved;\n pkg = resolved.value;\n } else {\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: 'No latest migration found in the migration history',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n if (!leafPkg) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `Latest migration ${latestMigration.dirName} does not match any package`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n pkg = leafPkg;\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n\n // `migration show` is an offline command; the control client is constructed\n // purely to dispatch the family-specific `toOperationPreview` capability and\n // is not connected to a database.\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...(config.driver ? { driver: config.driver } : {}),\n extensionPacks: config.extensionPacks ?? [],\n });\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n\n const result: MigrationShowResult = {\n ok: true,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.metadata.from,\n to: pkg.metadata.to,\n migrationHash: pkg.metadata.migrationHash,\n createdAt: pkg.metadata.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n preview,\n summary: `${ops.length} operation(s)`,\n };\n return ok(result);\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, statement preview, and metadata for a migration package.\\n' +\n 'Accepts a directory path, a hash prefix (git-style), or defaults to the\\n' +\n 'latest migration.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n addGlobalOptions(command)\n .argument('[target]', 'Migration directory path or migrationHash prefix (defaults to latest)')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as deriveEdgeStatuses, r as formatStatusSummary, t as createMigrationStatusCommand } from "../migration-status-
|
|
1
|
+
import { n as deriveEdgeStatuses, r as formatStatusSummary, t as createMigrationStatusCommand } from "../migration-status-CjwB2of-.mjs";
|
|
2
2
|
export { createMigrationStatusCommand, deriveEdgeStatuses, formatStatusSummary };
|
|
@@ -2,7 +2,7 @@ import { n as executeContractEmit } from "./contract-emit-B3ChISB_.mjs";
|
|
|
2
2
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
3
3
|
import { _ as errorUnexpected$1, t as CliStructuredError$1 } from "./cli-errors-D3_sMh2K.mjs";
|
|
4
4
|
import { s as isVerbose, t as TerminalUI } from "./terminal-ui-zaRDhJnP.mjs";
|
|
5
|
-
import { b as formatSuccessMessage, d as setCommandDescriptions, f as setCommandExamples, g as parseGlobalFlags, n as addGlobalOptions, t as handleResult, y as formatStyledHeader } from "./result-handler-
|
|
5
|
+
import { b as formatSuccessMessage, d as setCommandDescriptions, f as setCommandExamples, g as parseGlobalFlags, n as addGlobalOptions, t as handleResult, y as formatStyledHeader } from "./result-handler-DWb1rFS-.mjs";
|
|
6
6
|
import { t as createProgressAdapter } from "./progress-adapter-xASh41wr.mjs";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import { getEmittedArtifactPaths } from "@prisma-next/emitter";
|
|
@@ -145,4 +145,4 @@ function createContractEmitCommand() {
|
|
|
145
145
|
//#endregion
|
|
146
146
|
export { createContractEmitCommand as t };
|
|
147
147
|
|
|
148
|
-
//# sourceMappingURL=contract-emit-
|
|
148
|
+
//# sourceMappingURL=contract-emit-DkMqO7f2.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-emit-B0nGrDtk.mjs","names":["CliStructuredError","errorUnexpected"],"sources":["../src/utils/formatters/emit.ts","../src/commands/contract-emit.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { relative } from 'pathe';\n\nimport type { GlobalFlags } from '../global-flags';\nimport { isVerbose } from './helpers';\n\n// EmitContractResult type for CLI output formatting (includes file paths)\nexport interface EmitContractResult {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n readonly outDir: string;\n readonly files: {\n readonly json: string;\n readonly dts: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for contract emit.\n */\nexport function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n // Convert absolute paths to relative paths from cwd\n const jsonPath = relative(process.cwd(), result.files.json);\n const dtsPath = relative(process.cwd(), result.files.dts);\n\n lines.push(`✔ Emitted contract.json → ${jsonPath}`);\n lines.push(`✔ Emitted contract.d.ts → ${dtsPath}`);\n lines.push(` storageHash: ${result.storageHash}`);\n if (result.executionHash) {\n lines.push(` executionHash: ${result.executionHash}`);\n }\n if (result.profileHash) {\n lines.push(` profileHash: ${result.profileHash}`);\n }\n if (isVerbose(flags, 1)) {\n lines.push(` Total time: ${result.timings.total}ms`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for contract emit.\n */\nexport function formatEmitJson(result: EmitContractResult): string {\n const output = {\n ok: true,\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n ...(result.profileHash ? { profileHash: result.profileHash } : {}),\n outDir: result.outDir,\n files: result.files,\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n","import { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { errorContractConfigMissing } from '@prisma-next/errors/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { executeContractEmit } from '../control-api/operations/contract-emit';\nimport type { ContractEmitResult } from '../control-api/types';\nimport { CliStructuredError, errorUnexpected } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport {\n type EmitContractResult,\n formatEmitJson,\n formatEmitOutput,\n} from '../utils/formatters/emit';\nimport { formatStyledHeader, formatSuccessMessage } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface ContractEmitOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\ninterface HeaderPaths {\n readonly displayConfigPath: string;\n readonly outputJsonPath: string;\n readonly outputDtsPath: string;\n}\n\n/**\n * Pre-load the config just to compute display paths for the styled header. The\n * actual emit work goes through `executeContractEmit`, which loads the config\n * itself; the redundant load here is bounded and lets the header render before\n * the emit spans start.\n */\nasync function resolveHeaderPaths(\n configOption: string | undefined,\n): Promise<Result<HeaderPaths, CliStructuredError>> {\n const displayConfigPath = configOption\n ? relative(process.cwd(), resolve(configOption))\n : 'prisma-next.config.ts';\n\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(configOption);\n } catch (error) {\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to load config',\n }),\n );\n }\n\n if (!config.contract?.output) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract.output is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n }),\n );\n }\n\n try {\n const { jsonPath: outputJsonPath, dtsPath: outputDtsPath } = getEmittedArtifactPaths(\n config.contract.output,\n );\n return ok({ displayConfigPath, outputJsonPath, outputDtsPath });\n } catch (error) {\n return notOk(\n errorContractConfigMissing({\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n}\n\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n const headerPathsResult = await resolveHeaderPaths(options.config);\n if (!headerPathsResult.ok) {\n return headerPathsResult;\n }\n const { displayConfigPath, outputJsonPath, outputDtsPath } = headerPathsResult.value;\n\n if (!flags.json && !flags.quiet) {\n ui.stderr(\n formatStyledHeader({\n command: 'contract emit',\n description: 'Emit your contract artifacts',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: displayConfigPath },\n { label: 'contract', value: relative(process.cwd(), outputJsonPath) },\n { label: 'types', value: relative(process.cwd(), outputDtsPath) },\n ],\n flags,\n }),\n );\n }\n\n const onProgress = createProgressAdapter({ ui, flags });\n const configPath = options.config ? resolve(options.config) : 'prisma-next.config.ts';\n\n let result: ContractEmitResult;\n try {\n result = await executeContractEmit({ configPath, onProgress });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n\n if (result.validationWarning) {\n ui.warn(result.validationWarning);\n }\n\n return ok({\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n profileHash: result.profileHash,\n outDir: dirname(result.files.json),\n files: result.files,\n timings: { total: Date.now() - startTime },\n });\n}\n\nexport function createContractEmitCommand(): Command {\n const command = new Command('emit');\n setCommandDescriptions(\n command,\n 'Emit your contract artifacts',\n 'Reads your contract source (TypeScript or Prisma schema) and emits contract.json and\\n' +\n 'contract.d.ts. The contract.json contains the canonical contract structure, and\\n' +\n 'contract.d.ts provides TypeScript types for type-safe query building.',\n );\n setCommandExamples(command, [\n 'prisma-next contract emit',\n 'prisma-next contract emit --config ./custom-config.ts',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (emitResult) => {\n if (flags.json) {\n ui.output(formatEmitJson(emitResult));\n } else {\n const output = formatEmitOutput(emitResult, flags);\n if (output) {\n ui.log(output);\n }\n if (!flags.quiet) {\n ui.success(formatSuccessMessage(flags));\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"contract-emit-DkMqO7f2.mjs","names":["CliStructuredError","errorUnexpected"],"sources":["../src/utils/formatters/emit.ts","../src/commands/contract-emit.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { relative } from 'pathe';\n\nimport type { GlobalFlags } from '../global-flags';\nimport { isVerbose } from './helpers';\n\n// EmitContractResult type for CLI output formatting (includes file paths)\nexport interface EmitContractResult {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n readonly outDir: string;\n readonly files: {\n readonly json: string;\n readonly dts: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for contract emit.\n */\nexport function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n // Convert absolute paths to relative paths from cwd\n const jsonPath = relative(process.cwd(), result.files.json);\n const dtsPath = relative(process.cwd(), result.files.dts);\n\n lines.push(`✔ Emitted contract.json → ${jsonPath}`);\n lines.push(`✔ Emitted contract.d.ts → ${dtsPath}`);\n lines.push(` storageHash: ${result.storageHash}`);\n if (result.executionHash) {\n lines.push(` executionHash: ${result.executionHash}`);\n }\n if (result.profileHash) {\n lines.push(` profileHash: ${result.profileHash}`);\n }\n if (isVerbose(flags, 1)) {\n lines.push(` Total time: ${result.timings.total}ms`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for contract emit.\n */\nexport function formatEmitJson(result: EmitContractResult): string {\n const output = {\n ok: true,\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n ...(result.profileHash ? { profileHash: result.profileHash } : {}),\n outDir: result.outDir,\n files: result.files,\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n","import { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { errorContractConfigMissing } from '@prisma-next/errors/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { executeContractEmit } from '../control-api/operations/contract-emit';\nimport type { ContractEmitResult } from '../control-api/types';\nimport { CliStructuredError, errorUnexpected } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport {\n type EmitContractResult,\n formatEmitJson,\n formatEmitOutput,\n} from '../utils/formatters/emit';\nimport { formatStyledHeader, formatSuccessMessage } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface ContractEmitOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\ninterface HeaderPaths {\n readonly displayConfigPath: string;\n readonly outputJsonPath: string;\n readonly outputDtsPath: string;\n}\n\n/**\n * Pre-load the config just to compute display paths for the styled header. The\n * actual emit work goes through `executeContractEmit`, which loads the config\n * itself; the redundant load here is bounded and lets the header render before\n * the emit spans start.\n */\nasync function resolveHeaderPaths(\n configOption: string | undefined,\n): Promise<Result<HeaderPaths, CliStructuredError>> {\n const displayConfigPath = configOption\n ? relative(process.cwd(), resolve(configOption))\n : 'prisma-next.config.ts';\n\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(configOption);\n } catch (error) {\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to load config',\n }),\n );\n }\n\n if (!config.contract?.output) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract.output is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n }),\n );\n }\n\n try {\n const { jsonPath: outputJsonPath, dtsPath: outputDtsPath } = getEmittedArtifactPaths(\n config.contract.output,\n );\n return ok({ displayConfigPath, outputJsonPath, outputDtsPath });\n } catch (error) {\n return notOk(\n errorContractConfigMissing({\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n}\n\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n const headerPathsResult = await resolveHeaderPaths(options.config);\n if (!headerPathsResult.ok) {\n return headerPathsResult;\n }\n const { displayConfigPath, outputJsonPath, outputDtsPath } = headerPathsResult.value;\n\n if (!flags.json && !flags.quiet) {\n ui.stderr(\n formatStyledHeader({\n command: 'contract emit',\n description: 'Emit your contract artifacts',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: displayConfigPath },\n { label: 'contract', value: relative(process.cwd(), outputJsonPath) },\n { label: 'types', value: relative(process.cwd(), outputDtsPath) },\n ],\n flags,\n }),\n );\n }\n\n const onProgress = createProgressAdapter({ ui, flags });\n const configPath = options.config ? resolve(options.config) : 'prisma-next.config.ts';\n\n let result: ContractEmitResult;\n try {\n result = await executeContractEmit({ configPath, onProgress });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n\n if (result.validationWarning) {\n ui.warn(result.validationWarning);\n }\n\n return ok({\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n profileHash: result.profileHash,\n outDir: dirname(result.files.json),\n files: result.files,\n timings: { total: Date.now() - startTime },\n });\n}\n\nexport function createContractEmitCommand(): Command {\n const command = new Command('emit');\n setCommandDescriptions(\n command,\n 'Emit your contract artifacts',\n 'Reads your contract source (TypeScript or Prisma schema) and emits contract.json and\\n' +\n 'contract.d.ts. The contract.json contains the canonical contract structure, and\\n' +\n 'contract.d.ts provides TypeScript types for type-safe query building.',\n );\n setCommandExamples(command, [\n 'prisma-next contract emit',\n 'prisma-next contract emit --config ./custom-config.ts',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (emitResult) => {\n if (flags.json) {\n ui.output(formatEmitJson(emitResult));\n } else {\n const output = formatEmitOutput(emitResult, flags);\n if (output) {\n ui.log(output);\n }\n if (!flags.quiet) {\n ui.success(formatSuccessMessage(flags));\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as TerminalUI } from "./terminal-ui-zaRDhJnP.mjs";
|
|
2
|
-
import { d as setCommandDescriptions, f as setCommandExamples, g as parseGlobalFlags, n as addGlobalOptions, t as handleResult } from "./result-handler-
|
|
3
|
-
import { t as inspectLiveSchema } from "./inspect-live-schema-
|
|
2
|
+
import { d as setCommandDescriptions, f as setCommandExamples, g as parseGlobalFlags, n as addGlobalOptions, t as handleResult } from "./result-handler-DWb1rFS-.mjs";
|
|
3
|
+
import { t as inspectLiveSchema } from "./inspect-live-schema-BAgQMYpD.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
6
6
|
import { dirname, relative, resolve } from "pathe";
|
|
@@ -77,4 +77,4 @@ function createContractInferCommand() {
|
|
|
77
77
|
//#endregion
|
|
78
78
|
export { createContractInferCommand as t };
|
|
79
79
|
|
|
80
|
-
//# sourceMappingURL=contract-infer-
|
|
80
|
+
//# sourceMappingURL=contract-infer-BDKAE0B0.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-infer-
|
|
1
|
+
{"version":3,"file":"contract-infer-BDKAE0B0.mjs","names":[],"sources":["../src/commands/contract-infer-paths.ts","../src/commands/contract-infer.ts"],"sourcesContent":["import { dirname, resolve } from 'pathe';\n\ninterface ContractInferPathOptions {\n readonly output?: string;\n readonly config?: string;\n}\n\n/**\n * Resolves the output path for the inferred PSL contract.\n *\n * Priority:\n * 1. --output <path> flag (resolved relative to cwd)\n * 2. contract.prisma next to config.contract.output\n * 3. Canonical default: contract.prisma in the config directory\n */\nexport function resolveContractInferOutputPath(\n options: ContractInferPathOptions,\n contractOutput: string | undefined,\n): string {\n const configDir = options.config\n ? dirname(resolve(process.cwd(), options.config))\n : process.cwd();\n\n if (options.output) {\n return resolve(process.cwd(), options.output);\n }\n if (contractOutput) {\n const contractPath = resolve(configDir, contractOutput);\n return resolve(dirname(contractPath), 'contract.prisma');\n }\n return resolve(configDir, 'contract.prisma');\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { errorRuntime } from '@prisma-next/errors/execution';\nimport { printPsl } from '@prisma-next/psl-printer';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, relative } from 'pathe';\nimport type { CliStructuredError } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\nimport { resolveContractInferOutputPath } from './contract-infer-paths';\nimport {\n type InspectLiveSchemaOptions,\n type InspectLiveSchemaResult,\n inspectLiveSchema,\n} from './inspect-live-schema';\n\ninterface ContractInferOptions extends InspectLiveSchemaOptions {\n readonly output?: string;\n}\n\ninterface ContractInferSuccessResult {\n readonly ok: true;\n readonly summary: string;\n readonly target: InspectLiveSchemaResult['target'];\n readonly psl: {\n readonly path: string;\n };\n readonly meta: InspectLiveSchemaResult['meta'];\n readonly timings: {\n readonly total: number;\n };\n}\n\nasync function executeContractInferCommand(\n options: ContractInferOptions,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<ContractInferSuccessResult, CliStructuredError>> {\n const flags = parseGlobalFlags(options);\n const inspectResult = await inspectLiveSchema(options, flags, ui, startTime, {\n commandName: 'contract infer',\n description: 'Infer a PSL contract from the live database schema',\n url: 'https://pris.ly/contract-infer',\n });\n\n if (!inspectResult.ok) {\n return inspectResult;\n }\n\n const { config, target, meta, pslContractAst } = inspectResult.value;\n\n if (!pslContractAst) {\n return notOk(\n errorRuntime('contract infer is not supported for this family', {\n why: 'The configured family does not implement the PslContractInferCapable capability, so an inferred PSL contract cannot be produced from the live database schema.',\n fix: 'Use a family that supports contract inference (e.g. SQL/Postgres).',\n }),\n );\n }\n\n const outputPath = resolveContractInferOutputPath(options, config.contract?.output);\n const pslContent = printPsl(pslContractAst);\n\n if (existsSync(outputPath) && !flags.json && !flags.quiet) {\n ui.stderr(`\\u26A0 Overwriting existing file: ${relative(process.cwd(), outputPath)}`);\n }\n\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, pslContent, 'utf-8');\n\n const pslPath = relative(process.cwd(), outputPath);\n if (!flags.json && !flags.quiet) {\n ui.stderr(`\\u2714 Contract written to ${pslPath}`);\n }\n\n return ok({\n ok: true,\n summary: 'Contract inferred successfully',\n target,\n psl: {\n path: pslPath,\n },\n meta,\n timings: {\n total: Date.now() - startTime,\n },\n });\n}\n\nexport function createContractInferCommand(): Command {\n const command = new Command('infer');\n setCommandDescriptions(\n command,\n 'Infer a PSL contract from the live database schema',\n 'Reads the live database schema and writes an inferred PSL contract to disk.\\n' +\n 'This command stops at `contract.prisma`; follow it with `contract emit` and\\n' +\n '`db sign` as separate steps.',\n );\n setCommandExamples(command, [\n 'prisma-next contract infer --db $DATABASE_URL',\n 'prisma-next contract infer --db $DATABASE_URL --output ./prisma/contract.prisma',\n 'prisma-next contract infer --db $DATABASE_URL --json',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--output <path>', 'Write the inferred PSL contract to the specified path')\n .action(async (options: ContractInferOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const startTime = Date.now();\n\n const result = await executeContractInferCommand(options, ui, startTime);\n const exitCode = handleResult(result, flags, ui, (value) => {\n if (flags.json) {\n ui.output(JSON.stringify(value, null, 2));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAeA,SAAgB,+BACd,SACA,gBACQ;CACR,MAAM,YAAY,QAAQ,SACtB,QAAQ,QAAQ,QAAQ,KAAK,EAAE,QAAQ,OAAO,CAAC,GAC/C,QAAQ,KAAK;CAEjB,IAAI,QAAQ,QACV,OAAO,QAAQ,QAAQ,KAAK,EAAE,QAAQ,OAAO;CAE/C,IAAI,gBAEF,OAAO,QAAQ,QADM,QAAQ,WAAW,eACL,CAAC,EAAE,kBAAkB;CAE1D,OAAO,QAAQ,WAAW,kBAAkB;;;;ACS9C,eAAe,4BACb,SACA,IACA,WACiE;CACjE,MAAM,QAAQ,iBAAiB,QAAQ;CACvC,MAAM,gBAAgB,MAAM,kBAAkB,SAAS,OAAO,IAAI,WAAW;EAC3E,aAAa;EACb,aAAa;EACb,KAAK;EACN,CAAC;CAEF,IAAI,CAAC,cAAc,IACjB,OAAO;CAGT,MAAM,EAAE,QAAQ,QAAQ,MAAM,mBAAmB,cAAc;CAE/D,IAAI,CAAC,gBACH,OAAO,MACL,aAAa,mDAAmD;EAC9D,KAAK;EACL,KAAK;EACN,CAAC,CACH;CAGH,MAAM,aAAa,+BAA+B,SAAS,OAAO,UAAU,OAAO;CACnF,MAAM,aAAa,SAAS,eAAe;CAE3C,IAAI,WAAW,WAAW,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OAClD,GAAG,OAAO,qCAAqC,SAAS,QAAQ,KAAK,EAAE,WAAW,GAAG;CAGvF,UAAU,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;CACnD,cAAc,YAAY,YAAY,QAAQ;CAE9C,MAAM,UAAU,SAAS,QAAQ,KAAK,EAAE,WAAW;CACnD,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OACxB,GAAG,OAAO,8BAA8B,UAAU;CAGpD,OAAO,GAAG;EACR,IAAI;EACJ,SAAS;EACT;EACA,KAAK,EACH,MAAM,SACP;EACD;EACA,SAAS,EACP,OAAO,KAAK,KAAK,GAAG,WACrB;EACF,CAAC;;AAGJ,SAAgB,6BAAsC;CACpD,MAAM,UAAU,IAAI,QAAQ,QAAQ;CACpC,uBACE,SACA,sDACA,yLAGD;CACD,mBAAmB,SAAS;EAC1B;EACA;EACA;EACD,CAAC;CACF,iBAAiB,QAAQ,CACtB,OAAO,cAAc,6BAA6B,CAClD,OAAO,mBAAmB,gCAAgC,CAC1D,OAAO,mBAAmB,wDAAwD,CAClF,OAAO,OAAO,YAAkC;EAC/C,MAAM,QAAQ,iBAAiB,QAAQ;EACvC,MAAM,KAAK,IAAI,WAAW;GAAE,OAAO,MAAM;GAAO,aAAa,MAAM;GAAa,CAAC;EAIjF,MAAM,WAAW,aAAa,MADT,4BAA4B,SAAS,IAFxC,KAAK,KAEgD,CAAC,EAClC,OAAO,KAAK,UAAU;GAC1D,IAAI,MAAM,MACR,GAAG,OAAO,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;IAE3C;EAEF,QAAQ,KAAK,SAAS;GACtB;CAEJ,OAAO"}
|