prisma-next 0.11.0-dev.7 → 0.11.0-dev.70
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 +10 -11
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-oXO2WCPD.mjs → client-6WehTnUh.mjs} +72 -60
- package/dist/client-6WehTnUh.mjs.map +1 -0
- package/dist/{command-helpers-DtavI0wJ.mjs → command-helpers-CoceqqMl.mjs} +642 -45
- package/dist/command-helpers-CoceqqMl.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts.map +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.d.mts.map +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.d.mts.map +1 -1
- package/dist/commands/db-init.mjs +32 -7
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.d.mts.map +1 -1
- package/dist/commands/db-schema.mjs +3 -4
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.d.mts.map +1 -1
- package/dist/commands/db-sign.mjs +12 -10
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +41 -11
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +6 -2
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +75 -40
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +4 -3
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +1 -280
- package/dist/commands/migration-graph.d.mts +13 -2
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +2 -137
- package/dist/commands/migration-list.d.mts +67 -4
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +2 -103
- package/dist/commands/migration-log.d.mts +10 -1
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +10 -15
- package/dist/commands/migration-log.mjs.map +1 -1
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +32 -38
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +3 -2
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +4 -55
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +61 -153
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +12 -49
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +85 -81
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +38 -10
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/config-loader-B6sJjXTv.mjs.map +1 -1
- package/dist/config-loader.d.mts.map +1 -1
- package/dist/contract-at-errors-Bhf2jnkp.mjs +42 -0
- package/dist/contract-at-errors-Bhf2jnkp.mjs.map +1 -0
- package/dist/{contract-emit-CmsklifJ.mjs → contract-emit-C47r1loe.mjs} +4 -6
- package/dist/{contract-emit-CmsklifJ.mjs.map → contract-emit-C47r1loe.mjs.map} +1 -1
- package/dist/{contract-emit-o-8VmdQX.mjs → contract-emit-DxEfEc-M.mjs} +21 -7
- package/dist/{contract-emit-o-8VmdQX.mjs.map → contract-emit-DxEfEc-M.mjs.map} +1 -1
- package/dist/{contract-enrichment-Dani0mMW.mjs → contract-enrichment-a0V5Y_mL.mjs} +4 -25
- package/dist/contract-enrichment-a0V5Y_mL.mjs.map +1 -0
- package/dist/{contract-infer-pKkiCt7C.mjs → contract-infer-BLiomU8g.mjs} +3 -4
- package/dist/{contract-infer-pKkiCt7C.mjs.map → contract-infer-BLiomU8g.mjs.map} +1 -1
- package/dist/contract-space-aggregate-loader-lafgkTwG.mjs +247 -0
- package/dist/contract-space-aggregate-loader-lafgkTwG.mjs.map +1 -0
- package/dist/{db-verify-AoIUriL4.mjs → db-verify-D44Qj3w9.mjs} +5 -7
- package/dist/{db-verify-AoIUriL4.mjs.map → db-verify-D44Qj3w9.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +3 -3
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +3 -3
- package/dist/exports/index.d.mts.map +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/index.mjs.map +1 -1
- package/dist/exports/init-output.d.mts.map +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/extension-pack-inputs-IDvjRCi3.mjs +62 -0
- package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +1 -0
- package/dist/{framework-components-65gOHkHB.mjs → framework-components-R_O3y5IW.mjs} +2 -2
- package/dist/{framework-components-65gOHkHB.mjs.map → framework-components-R_O3y5IW.mjs.map} +1 -1
- package/dist/global-flags-DG4uY5tV.d.mts +34 -0
- package/dist/global-flags-DG4uY5tV.d.mts.map +1 -0
- package/dist/{graph-render-DJVv0_uf.mjs → graph-render-rFAqZujX.mjs} +2 -2
- package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-rFAqZujX.mjs.map} +1 -1
- package/dist/{init-Db5Itt5r.mjs → init-DE-phHWK.mjs} +4 -5
- package/dist/{init-Db5Itt5r.mjs.map → init-DE-phHWK.mjs.map} +1 -1
- package/dist/{inspect-live-schema-LeWvkZVz.mjs → inspect-live-schema-Ccnmg5bz.mjs} +4 -5
- package/dist/{inspect-live-schema-LeWvkZVz.mjs.map → inspect-live-schema-Ccnmg5bz.mjs.map} +1 -1
- package/dist/migration-check-CKfQlAWR.mjs +341 -0
- package/dist/migration-check-CKfQlAWR.mjs.map +1 -0
- package/dist/migration-cli.d.mts.map +1 -1
- package/dist/migration-cli.mjs +4 -4
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs → migration-command-scaffold-C_KuV0Gm.mjs} +4 -5
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs.map → migration-command-scaffold-C_KuV0Gm.mjs.map} +1 -1
- package/dist/migration-graph-kPluRdF2.mjs +1232 -0
- package/dist/migration-graph-kPluRdF2.mjs.map +1 -0
- package/dist/migration-list-CE35R5Ag.mjs +505 -0
- package/dist/migration-list-CE35R5Ag.mjs.map +1 -0
- package/dist/migration-list-styler-DeAwACt3.mjs +402 -0
- package/dist/migration-list-styler-DeAwACt3.mjs.map +1 -0
- package/dist/{migration-plan-C2jeH1J5.mjs → migration-plan-DHLa2Khm.mjs} +372 -133
- package/dist/migration-plan-DHLa2Khm.mjs.map +1 -0
- package/dist/{migration-types-BXWvz12q.d.mts → migration-types-CAQ-0TEE.d.mts} +1 -1
- package/dist/{migration-types-BXWvz12q.d.mts.map → migration-types-CAQ-0TEE.d.mts.map} +1 -1
- package/dist/{migrations-CwZMa1Ck.mjs → migrations-CjO1DsYe.mjs} +12 -13
- package/dist/migrations-CjO1DsYe.mjs.map +1 -0
- package/dist/{output-BlsrGMEF.mjs → output-CF_hqzI-.mjs} +1 -1
- package/dist/{output-BlsrGMEF.mjs.map → output-CF_hqzI-.mjs.map} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs → progress-adapter-C644QK8l.mjs} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs.map → progress-adapter-C644QK8l.mjs.map} +1 -1
- package/dist/ref-advancement-DUZqsue6.mjs +50 -0
- package/dist/ref-advancement-DUZqsue6.mjs.map +1 -0
- package/dist/terminal-ui-BbtqsQYY.d.mts +133 -0
- package/dist/terminal-ui-BbtqsQYY.d.mts.map +1 -0
- package/dist/{types-C9FfXb1l.d.mts → types-Ci7TndCS.d.mts} +21 -28
- package/dist/types-Ci7TndCS.d.mts.map +1 -0
- package/dist/{verify-Bom75OYI.mjs → verify-vl983Ed-.mjs} +2 -2
- package/dist/{verify-Bom75OYI.mjs.map → verify-vl983Ed-.mjs.map} +1 -1
- package/package.json +11 -11
- package/dist/cli-errors-Czmx92Zy.d.mts +0 -3
- package/dist/cli-errors-Djtz98Vm.mjs +0 -71
- package/dist/cli-errors-Djtz98Vm.mjs.map +0 -1
- package/dist/client-oXO2WCPD.mjs.map +0 -1
- package/dist/command-helpers-DtavI0wJ.mjs.map +0 -1
- package/dist/commands/migration-check.mjs.map +0 -1
- package/dist/commands/migration-graph.mjs.map +0 -1
- package/dist/commands/migration-list.mjs.map +0 -1
- package/dist/contract-enrichment-Dani0mMW.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs +0 -160
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs.map +0 -1
- package/dist/global-flags-CdE7M0d9.d.mts +0 -15
- package/dist/global-flags-CdE7M0d9.d.mts.map +0 -1
- package/dist/migration-plan-C2jeH1J5.mjs.map +0 -1
- package/dist/migrations-CwZMa1Ck.mjs.map +0 -1
- package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
- package/dist/terminal-ui-BiB_8KNo.mjs +0 -379
- package/dist/terminal-ui-BiB_8KNo.mjs.map +0 -1
- package/dist/types-C9FfXb1l.d.mts.map +0 -1
|
@@ -1,39 +1,20 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
5
|
-
import { t as createControlClient } from "../client-oXO2WCPD.mjs";
|
|
6
|
-
import { t as buildContractSpaceAggregate } from "../contract-space-aggregate-loader-BmNQwlws.mjs";
|
|
7
|
-
import { a as formatMigrationShowOutput } from "../migrations-CwZMa1Ck.mjs";
|
|
2
|
+
import { P as errorContractValidationFailed, R as errorFileNotFound, T as formatStyledHeader, X as errorRuntime, _ as createTerminalUI, d as setCommandSeeAlso, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, o as resolveContractPath, rt as mapRefResolutionError, s as resolveMigrationPaths, t as addGlobalOptions, tt as errorUnexpected, u as setCommandExamples, y as handleResult } from "../command-helpers-CoceqqMl.mjs";
|
|
3
|
+
import { t as createControlClient } from "../client-6WehTnUh.mjs";
|
|
4
|
+
import { a as formatMigrationShowOutput } from "../migrations-CjO1DsYe.mjs";
|
|
8
5
|
import { Command } from "commander";
|
|
9
6
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
10
7
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
11
8
|
import { isAbsolute, relative, resolve } from "pathe";
|
|
12
9
|
import { readFile } from "node:fs/promises";
|
|
13
10
|
import { APP_SPACE_ID, createControlStack } from "@prisma-next/framework-components/control";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { spaceMigrationDirectory } from "@prisma-next/migration-tools/spaces";
|
|
17
|
-
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
11
|
+
import { loadContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
|
|
12
|
+
import { castAs } from "@prisma-next/utils/casts";
|
|
18
13
|
import { parseMigrationRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
19
|
-
import { readRefs } from "@prisma-next/migration-tools/refs";
|
|
20
14
|
//#region src/commands/migration-show.ts
|
|
21
15
|
function looksLikePath(target) {
|
|
22
16
|
return target.includes("/") || target.includes("\\");
|
|
23
17
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Validate that a path-like `migration show` target resolves inside the app
|
|
26
|
-
* migrations directory. The returned result is always emitted under
|
|
27
|
-
* `aggregate.app.spaceId`, so accepting an extension-space (or otherwise
|
|
28
|
-
* external) path here would silently mislabel the result. Returns the
|
|
29
|
-
* resolved absolute path on success.
|
|
30
|
-
*
|
|
31
|
-
* `pathe.relative` can return an absolute path when the target cannot be
|
|
32
|
-
* expressed relative to the base (e.g. on Windows when `target` is on a
|
|
33
|
-
* different drive than `appMigrationsDir`). That case does not start with
|
|
34
|
-
* `..`, so the absolute-check below is required to reject cross-drive
|
|
35
|
-
* targets rather than mislabeling them as app-space.
|
|
36
|
-
*/
|
|
37
18
|
function resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative) {
|
|
38
19
|
const targetPath = resolve(target);
|
|
39
20
|
const relativeToApp = relative(appMigrationsDir, targetPath);
|
|
@@ -43,48 +24,10 @@ function resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative) {
|
|
|
43
24
|
}));
|
|
44
25
|
return ok(targetPath);
|
|
45
26
|
}
|
|
46
|
-
function
|
|
47
|
-
const
|
|
48
|
-
const matches = packages.filter((p) => p.metadata.migrationHash.startsWith(normalizedPrefix));
|
|
49
|
-
if (matches.length === 1) return ok(matches[0]);
|
|
50
|
-
if (matches.length === 0) return notOk(errorRuntime("No migration found matching prefix", {
|
|
51
|
-
why: `No migration has a migrationHash starting with "${normalizedPrefix}"`,
|
|
52
|
-
fix: "Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages."
|
|
53
|
-
}));
|
|
54
|
-
return notOk(errorRuntime("Ambiguous hash prefix", {
|
|
55
|
-
why: `Multiple migrations match prefix "${normalizedPrefix}":\n${matches.map((p) => ` ${p.dirName} ${p.metadata.migrationHash}`).join("\n")}`,
|
|
56
|
-
fix: "Provide a longer prefix to uniquely identify the migration."
|
|
57
|
-
}));
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Resolve the latest migration from a space directory.
|
|
61
|
-
*
|
|
62
|
-
* Returns `ok(null)` only when the directory is empty or absent (ENOENT is
|
|
63
|
-
* absorbed by `readMigrationsDir`). If `readMigrationsDir` returned packages
|
|
64
|
-
* but `findLatestMigration` cannot pick a leaf, the on-disk history is
|
|
65
|
-
* corrupt — return a runtime error rather than collapsing it to a `missing`
|
|
66
|
-
* placeholder, which would hide the corruption from the caller.
|
|
67
|
-
*/
|
|
68
|
-
async function resolveLatestFromDir(spaceDir) {
|
|
69
|
-
try {
|
|
70
|
-
const allPackages = await readMigrationsDir(spaceDir);
|
|
71
|
-
if (allPackages.length === 0) return ok(null);
|
|
72
|
-
const latestMigration = findLatestMigration(reconstructGraph(allPackages));
|
|
73
|
-
if (!latestMigration) return notOk(errorRuntime("Could not resolve latest migration", {
|
|
74
|
-
why: `No latest migration found in ${relative(process.cwd(), spaceDir)}`,
|
|
75
|
-
fix: "The migrations directory may be corrupted. Inspect the migration.json files."
|
|
76
|
-
}));
|
|
77
|
-
return ok(allPackages.find((p) => p.metadata.migrationHash === latestMigration.migrationHash) ?? null);
|
|
78
|
-
} catch (error) {
|
|
79
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
80
|
-
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read migrations: ${error instanceof Error ? error.message : String(error)}` }));
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
function pkgToSpaceResult(spaceId, pkg, client) {
|
|
84
|
-
const ops = pkg.ops;
|
|
27
|
+
function pkgToPresent(spaceId, pkg, client) {
|
|
28
|
+
const ops = castAs(pkg.ops);
|
|
85
29
|
const preview = client.toOperationPreview(ops) ?? { statements: [] };
|
|
86
30
|
return {
|
|
87
|
-
kind: "present",
|
|
88
31
|
spaceId,
|
|
89
32
|
dirName: pkg.dirName,
|
|
90
33
|
dirPath: relative(process.cwd(), pkg.dirPath),
|
|
@@ -101,34 +44,37 @@ function pkgToSpaceResult(spaceId, pkg, client) {
|
|
|
101
44
|
summary: `${ops.length} operation(s)`
|
|
102
45
|
};
|
|
103
46
|
}
|
|
47
|
+
function findPackageByDirPath(packages, resolvedDirPath) {
|
|
48
|
+
const normalized = resolve(resolvedDirPath);
|
|
49
|
+
return packages.find((p) => resolve(p.dirPath) === normalized);
|
|
50
|
+
}
|
|
104
51
|
async function executeMigrationShowCommand(target, options, flags, ui) {
|
|
105
52
|
const config = await loadConfig(options.config);
|
|
106
|
-
const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative
|
|
53
|
+
const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative } = resolveMigrationPaths(options.config, config);
|
|
107
54
|
const contractPathAbsolute = resolveContractPath(config);
|
|
108
55
|
const contractPath = relative(process.cwd(), contractPathAbsolute);
|
|
109
56
|
if (!flags.json && !flags.quiet) {
|
|
110
|
-
const details = [
|
|
111
|
-
{
|
|
112
|
-
label: "config",
|
|
113
|
-
value: configPath
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
label: "contract",
|
|
117
|
-
value: contractPath
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
label: "migrations",
|
|
121
|
-
value: appMigrationsRelative
|
|
122
|
-
}
|
|
123
|
-
];
|
|
124
|
-
if (target) details.push({
|
|
125
|
-
label: "target",
|
|
126
|
-
value: target
|
|
127
|
-
});
|
|
128
57
|
const header = formatStyledHeader({
|
|
129
58
|
command: "migration show",
|
|
130
59
|
description: "Display migration package contents",
|
|
131
|
-
details
|
|
60
|
+
details: [
|
|
61
|
+
{
|
|
62
|
+
label: "config",
|
|
63
|
+
value: configPath
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
label: "contract",
|
|
67
|
+
value: contractPath
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
label: "migrations",
|
|
71
|
+
value: appMigrationsRelative
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
label: "target",
|
|
75
|
+
value: target
|
|
76
|
+
}
|
|
77
|
+
],
|
|
132
78
|
flags
|
|
133
79
|
});
|
|
134
80
|
ui.stderr(header);
|
|
@@ -140,38 +86,6 @@ async function executeMigrationShowCommand(target, options, flags, ui) {
|
|
|
140
86
|
...ifDefined("driver", config.driver),
|
|
141
87
|
extensionPacks: config.extensionPacks ?? []
|
|
142
88
|
});
|
|
143
|
-
if (target) try {
|
|
144
|
-
let appPkg;
|
|
145
|
-
if (looksLikePath(target)) {
|
|
146
|
-
const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);
|
|
147
|
-
if (!resolved.ok) return resolved;
|
|
148
|
-
appPkg = await readMigrationPackage(resolved.value);
|
|
149
|
-
} else {
|
|
150
|
-
const allPackages = await readMigrationsDir(appMigrationsDir);
|
|
151
|
-
if (allPackages.length === 0) return notOk(errorRuntime("No migrations found", {
|
|
152
|
-
why: `No migration packages found in ${appMigrationsRelative}`,
|
|
153
|
-
fix: "Run `prisma-next migration plan` to create a migration first."
|
|
154
|
-
}));
|
|
155
|
-
const migResult = parseMigrationRef(target, {
|
|
156
|
-
graph: reconstructGraph(allPackages),
|
|
157
|
-
refs: await readRefs(refsDir)
|
|
158
|
-
});
|
|
159
|
-
if (!migResult.ok) return notOk(mapRefResolutionError(migResult.failure));
|
|
160
|
-
const matchedPkg = allPackages.find((p) => p.metadata.migrationHash === migResult.value.migrationHash);
|
|
161
|
-
if (!matchedPkg) return notOk(errorRuntime("Migration package not found", {
|
|
162
|
-
why: `Resolved migration "${migResult.value.dirName}" but the package was not loaded`,
|
|
163
|
-
fix: "The migrations directory may be corrupted. Inspect the migration.json files."
|
|
164
|
-
}));
|
|
165
|
-
appPkg = matchedPkg;
|
|
166
|
-
}
|
|
167
|
-
return ok({
|
|
168
|
-
ok: true,
|
|
169
|
-
spaces: [pkgToSpaceResult(APP_SPACE_ID, appPkg, client)]
|
|
170
|
-
});
|
|
171
|
-
} catch (error) {
|
|
172
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
173
|
-
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read app-space migration: ${error instanceof Error ? error.message : String(error)}` }));
|
|
174
|
-
}
|
|
175
89
|
let contractJsonContent;
|
|
176
90
|
try {
|
|
177
91
|
contractJsonContent = await readFile(contractPathAbsolute, "utf-8");
|
|
@@ -186,60 +100,54 @@ async function executeMigrationShowCommand(target, options, flags, ui) {
|
|
|
186
100
|
const familyInstance = config.family.create(stack);
|
|
187
101
|
let appContract;
|
|
188
102
|
try {
|
|
189
|
-
appContract = familyInstance.deserializeContract(JSON.parse(contractJsonContent));
|
|
103
|
+
appContract = familyInstance.deserializeContract(castAs(JSON.parse(contractJsonContent)));
|
|
190
104
|
} catch (error) {
|
|
191
105
|
return notOk(errorContractValidationFailed(`Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`, { where: { path: contractPathAbsolute } }));
|
|
192
106
|
}
|
|
193
|
-
const
|
|
194
|
-
targetId: config.target.targetId,
|
|
107
|
+
const aggregate = await loadContractSpaceAggregate({
|
|
195
108
|
migrationsDir,
|
|
196
109
|
appContract,
|
|
197
|
-
extensionPacks: config.extensionPacks ?? [],
|
|
198
110
|
deserializeContract: (json) => familyInstance.deserializeContract(json)
|
|
199
111
|
});
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
112
|
+
const packages = aggregate.app.packages;
|
|
113
|
+
const graph = aggregate.app.graph();
|
|
114
|
+
const refs = aggregate.app.refs;
|
|
115
|
+
let appPkg;
|
|
116
|
+
if (looksLikePath(target)) {
|
|
117
|
+
const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);
|
|
118
|
+
if (!resolved.ok) return resolved;
|
|
119
|
+
const matched = findPackageByDirPath(packages, resolved.value);
|
|
120
|
+
if (!matched) return notOk(errorRuntime("Migration package not found", {
|
|
121
|
+
why: `No loaded migration package at ${relative(process.cwd(), resolved.value)}`,
|
|
122
|
+
fix: "Pass a directory name, hash prefix, or path to an on-disk app-space migration package."
|
|
123
|
+
}));
|
|
124
|
+
appPkg = matched;
|
|
125
|
+
} else {
|
|
126
|
+
if (packages.length === 0) return notOk(errorRuntime("No migrations found", {
|
|
206
127
|
why: `No migration packages found in ${appMigrationsRelative}`,
|
|
207
128
|
fix: "Run `prisma-next migration plan` to create a migration first."
|
|
208
129
|
}));
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
if (!
|
|
216
|
-
why: `
|
|
130
|
+
const migResult = parseMigrationRef(target, {
|
|
131
|
+
graph,
|
|
132
|
+
refs
|
|
133
|
+
});
|
|
134
|
+
if (!migResult.ok) return notOk(mapRefResolutionError(migResult.failure));
|
|
135
|
+
const matchedPkg = packages.find((p) => p.metadata.migrationHash === migResult.value.migrationHash);
|
|
136
|
+
if (!matchedPkg) return notOk(errorRuntime("Migration package not found", {
|
|
137
|
+
why: `Resolved migration "${migResult.value.dirName}" but the package was not loaded`,
|
|
217
138
|
fix: "The migrations directory may be corrupted. Inspect the migration.json files."
|
|
218
139
|
}));
|
|
219
|
-
|
|
220
|
-
} catch (error) {
|
|
221
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
222
|
-
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read app-space migration: ${error instanceof Error ? error.message : String(error)}` }));
|
|
223
|
-
}
|
|
224
|
-
for (const ext of aggregate.extensions) {
|
|
225
|
-
const extPkgResult = await resolveLatestFromDir(spaceMigrationDirectory(migrationsDir, ext.spaceId));
|
|
226
|
-
if (!extPkgResult.ok) return extPkgResult;
|
|
227
|
-
if (extPkgResult.value !== null) spaces.push(pkgToSpaceResult(ext.spaceId, extPkgResult.value, client));
|
|
228
|
-
else spaces.push({
|
|
229
|
-
kind: "missing",
|
|
230
|
-
spaceId: ext.spaceId,
|
|
231
|
-
summary: "No on-disk migration package for this space"
|
|
232
|
-
});
|
|
140
|
+
appPkg = matchedPkg;
|
|
233
141
|
}
|
|
234
142
|
return ok({
|
|
235
143
|
ok: true,
|
|
236
|
-
|
|
144
|
+
migration: pkgToPresent(APP_SPACE_ID, appPkg, client)
|
|
237
145
|
});
|
|
238
146
|
}
|
|
239
147
|
function createMigrationShowCommand() {
|
|
240
148
|
const command = new Command("show");
|
|
241
|
-
setCommandDescriptions(command, "Display migration package contents", "Shows the operations, statement preview, and metadata for
|
|
242
|
-
setCommandExamples(command, ["prisma-next migration show", "prisma-next migration show sha256:a1b2c3"]);
|
|
149
|
+
setCommandDescriptions(command, "Display migration package contents", "Shows the operations, statement preview, and metadata for one app-space migration.\nAccepts a directory path, directory name, or hash prefix.");
|
|
150
|
+
setCommandExamples(command, ["prisma-next migration show 20260101_100000_add_user", "prisma-next migration show sha256:a1b2c3"]);
|
|
243
151
|
setCommandSeeAlso(command, [
|
|
244
152
|
{
|
|
245
153
|
verb: "migration status",
|
|
@@ -258,7 +166,7 @@ function createMigrationShowCommand() {
|
|
|
258
166
|
oneLiner: "Show the migration graph topology"
|
|
259
167
|
}
|
|
260
168
|
]);
|
|
261
|
-
addGlobalOptions(command).argument("
|
|
169
|
+
addGlobalOptions(command).argument("<target>", "Migration reference: directory name, hash/prefix, or path").option("--config <path>", "Path to prisma-next.config.ts").action(async (target, options) => {
|
|
262
170
|
const flags = parseGlobalFlagsOrExit(options);
|
|
263
171
|
const ui = createTerminalUI(flags);
|
|
264
172
|
const exitCode = handleResult(await executeMigrationShowCommand(target, options, flags, ui), flags, ui, (showResult) => {
|
|
@@ -270,6 +178,6 @@ function createMigrationShowCommand() {
|
|
|
270
178
|
return command;
|
|
271
179
|
}
|
|
272
180
|
//#endregion
|
|
273
|
-
export { createMigrationShowCommand, resolveAppTargetPath
|
|
181
|
+
export { createMigrationShowCommand, resolveAppTargetPath };
|
|
274
182
|
|
|
275
183
|
//# sourceMappingURL=migration-show.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-show.mjs","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport {\n APP_SPACE_ID,\n createControlStack,\n type MigrationPlanOperation,\n type 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 { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { readRefs } from '@prisma-next/migration-tools/refs';\nimport { spaceMigrationDirectory } from '@prisma-next/migration-tools/spaces';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { isAbsolute, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n type CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n} from '../utils/command-helpers';\nimport { buildContractSpaceAggregate } from '../utils/contract-space-aggregate-loader';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\n/**\n * Details of one space's latest (or targeted) migration package.\n */\nexport interface MigrationShowSpacePresent {\n readonly kind: 'present';\n readonly spaceId: string;\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. Always\n * defined; statements is empty for a no-op migration or a family that does\n * not implement the `OperationPreviewCapable` capability.\n */\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\n/**\n * Placeholder for a loaded contract space that has no on-disk migration\n * package — the extension descriptor declared the space but no migrations\n * directory has been materialised for it yet. Surfaces the space in the\n * response so JSON consumers see every loaded extension instead of having\n * silently-skipped entries.\n */\nexport interface MigrationShowSpaceMissing {\n readonly kind: 'missing';\n readonly spaceId: string;\n readonly summary: string;\n}\n\nexport type MigrationShowSpaceResult = MigrationShowSpacePresent | MigrationShowSpaceMissing;\n\nexport interface MigrationShowResult {\n readonly ok: true;\n /**\n * Per-space results, ordered: app first, then extensions alphabetically\n * (matching the aggregate's canonical ordering).\n */\n readonly spaces: readonly MigrationShowSpaceResult[];\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\n/**\n * Validate that a path-like `migration show` target resolves inside the app\n * migrations directory. The returned result is always emitted under\n * `aggregate.app.spaceId`, so accepting an extension-space (or otherwise\n * external) path here would silently mislabel the result. Returns the\n * resolved absolute path on success.\n *\n * `pathe.relative` can return an absolute path when the target cannot be\n * expressed relative to the base (e.g. on Windows when `target` is on a\n * different drive than `appMigrationsDir`). That case does not start with\n * `..`, so the absolute-check below is required to reject cross-drive\n * targets rather than mislabeling them as app-space.\n */\nexport function resolveAppTargetPath(\n target: string,\n appMigrationsDir: string,\n appMigrationsRelative: string,\n): Result<string, CliStructuredError> {\n const targetPath = resolve(target);\n const relativeToApp = relative(appMigrationsDir, targetPath);\n const isOutsideAppDir =\n relativeToApp === '' ||\n relativeToApp === '.' ||\n relativeToApp.startsWith('..') ||\n isAbsolute(relativeToApp);\n if (isOutsideAppDir) {\n return notOk(\n errorRuntime('Target must point to an app-space migration', {\n why: `Expected a path under ${appMigrationsRelative}, got ${target}`,\n fix: 'Pass an app-space migration directory or use a hash prefix.',\n }),\n );\n }\n return ok(targetPath);\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\n/**\n * Resolve the latest migration from a space directory.\n *\n * Returns `ok(null)` only when the directory is empty or absent (ENOENT is\n * absorbed by `readMigrationsDir`). If `readMigrationsDir` returned packages\n * but `findLatestMigration` cannot pick a leaf, the on-disk history is\n * corrupt — return a runtime error rather than collapsing it to a `missing`\n * placeholder, which would hide the corruption from the caller.\n */\nexport async function resolveLatestFromDir(\n spaceDir: string,\n): Promise<Result<OnDiskMigrationPackage | null, CliStructuredError>> {\n try {\n const allPackages = await readMigrationsDir(spaceDir);\n if (allPackages.length === 0) return ok(null);\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 ${relative(process.cwd(), spaceDir)}`,\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 return ok(leafPkg ?? null);\n } catch (error) {\n if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migrations: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n}\n\nfunction pkgToSpaceResult(\n spaceId: string,\n pkg: OnDiskMigrationPackage,\n client: ReturnType<typeof createControlClient>,\n): MigrationShowSpacePresent {\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n return {\n kind: 'present',\n spaceId,\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}\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, migrationsDir, appMigrationsDir, appMigrationsRelative, refsDir } =\n resolveMigrationPaths(options.config, config);\n\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (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 // `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 ...ifDefined('driver', config.driver),\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Explicit-target path. Read the app-space migrations directory directly\n // and resolve `target` against the app graph. We deliberately skip\n // `buildContractSpaceAggregate` here for two reasons:\n //\n // 1. Functional: the user asked about ONE specific migration. They don't\n // need extension-space enumeration; resolving + rendering the named\n // package is enough.\n // 2. UX: the aggregate's layout-integrity check (PN-MIG-5001) fires when\n // an extension is declared but its migrations directory hasn't been\n // materialised. Gating an offline read-only inspect command on that\n // check forces users to run `migrate` against a database before they\n // can see what a migration contains — which contradicts what an\n // offline read-only verb should require.\n //\n // Same pattern as `migration list`, `migration graph`, `migration check`:\n // those verbs read `appMigrationsDir` directly without ever consulting\n // the aggregate.\n if (target) {\n try {\n let appPkg: OnDiskMigrationPackage;\n if (looksLikePath(target)) {\n const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);\n if (!resolved.ok) return resolved;\n appPkg = await readMigrationPackage(resolved.value);\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 const graph = reconstructGraph(allPackages);\n const refs = await readRefs(refsDir);\n const migResult = parseMigrationRef(target, { graph, refs });\n if (!migResult.ok) {\n return notOk(mapRefResolutionError(migResult.failure));\n }\n const matchedPkg = allPackages.find(\n (p) => p.metadata.migrationHash === migResult.value.migrationHash,\n );\n if (!matchedPkg) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `Resolved migration \"${migResult.value.dirName}\" but the package was not loaded`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n appPkg = matchedPkg;\n }\n return ok({\n ok: true,\n spaces: [pkgToSpaceResult(APP_SPACE_ID, appPkg, client)],\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 app-space migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n }\n\n // No-target path. Enumerate the latest migration per space (app +\n // extensions). The aggregate-loader is needed here because we need to\n // know which extension spaces are declared; its layout-integrity check\n // is appropriate at this entry point because the user is asking the\n // system to report on every loaded space.\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to read contract file',\n }),\n );\n }\n\n // Construct the family instance up-front so the on-disk app contract\n // read crosses the serializer seam (`familyInstance.deserializeContract`)\n // at the read site. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let appContract: Contract;\n try {\n appContract = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const aggregateResult = await buildContractSpaceAggregate({\n targetId: config.target.targetId,\n migrationsDir,\n appContract,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n if (!aggregateResult.ok) {\n return notOk(aggregateResult.failure);\n }\n const aggregate = aggregateResult.value;\n\n const spaces: MigrationShowSpaceResult[] = [];\n\n // App space: latest leaf.\n try {\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 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 spaces.push(pkgToSpaceResult(aggregate.app.spaceId, leafPkg, client));\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 app-space migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Extension spaces: always emit one entry per loaded extension so the\n // response enumerates every space the aggregate knows about. Spaces\n // with no on-disk migration package yet (e.g. an extension was declared\n // but never `migrate`d) become `kind: 'missing'` placeholders instead\n // of being silently skipped.\n for (const ext of aggregate.extensions) {\n const extSpaceDir = spaceMigrationDirectory(migrationsDir, ext.spaceId);\n const extPkgResult = await resolveLatestFromDir(extSpaceDir);\n if (!extPkgResult.ok) return extPkgResult;\n if (extPkgResult.value !== null) {\n spaces.push(pkgToSpaceResult(ext.spaceId, extPkgResult.value, client));\n } else {\n spaces.push({\n kind: 'missing',\n spaceId: ext.spaceId,\n summary: 'No on-disk migration package for this space',\n });\n }\n }\n\n return ok({ ok: true, spaces });\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 every loaded contract\\n' +\n 'space (app + extensions). Accepts a directory path or hash prefix to target a\\n' +\n 'specific app-space migration; defaults to the latest per space.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration log', oneLiner: 'Show executed migration history' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n ]);\n addGlobalOptions(command)\n .argument(\n '[target]',\n 'Migration reference: directory name, hash/prefix, or path (defaults to latest)',\n )\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n\n const ui = createTerminalUI(flags);\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 { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport {\n APP_SPACE_ID,\n createControlStack,\n type MigrationPlanOperation,\n type OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { castAs } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { isAbsolute, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n type CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorRuntime,\n errorUnexpected,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\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, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowPresent {\n readonly spaceId: string;\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 readonly preview: OperationPreview;\n readonly summary: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly migration: MigrationShowPresent;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveAppTargetPath(\n target: string,\n appMigrationsDir: string,\n appMigrationsRelative: string,\n): Result<string, CliStructuredError> {\n const targetPath = resolve(target);\n const relativeToApp = relative(appMigrationsDir, targetPath);\n const isOutsideAppDir =\n relativeToApp === '' ||\n relativeToApp === '.' ||\n relativeToApp.startsWith('..') ||\n isAbsolute(relativeToApp);\n if (isOutsideAppDir) {\n return notOk(\n errorRuntime('Target must point to an app-space migration', {\n why: `Expected a path under ${appMigrationsRelative}, got ${target}`,\n fix: 'Pass an app-space migration directory or use a hash prefix.',\n }),\n );\n }\n return ok(targetPath);\n}\n\nfunction pkgToPresent(\n spaceId: string,\n pkg: OnDiskMigrationPackage,\n client: ReturnType<typeof createControlClient>,\n): MigrationShowPresent {\n const ops = castAs<readonly MigrationPlanOperation[]>(pkg.ops);\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n return {\n spaceId,\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}\n\nfunction findPackageByDirPath(\n packages: readonly OnDiskMigrationPackage[],\n resolvedDirPath: string,\n): OnDiskMigrationPackage | undefined {\n const normalized = resolve(resolvedDirPath);\n return packages.find((p) => resolve(p.dirPath) === normalized);\n}\n\nasync function executeMigrationShowCommand(\n target: string,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative } =\n resolveMigrationPaths(options.config, config);\n\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n if (!flags.json && !flags.quiet) {\n const header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n { label: 'target', value: target },\n ],\n flags,\n });\n ui.stderr(header);\n }\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...ifDefined('driver', config.driver),\n extensionPacks: config.extensionPacks ?? [],\n });\n\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as NodeJS.ErrnoException).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to read contract file',\n }),\n );\n }\n\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let appContract: Contract;\n try {\n appContract = familyInstance.deserializeContract(\n castAs<unknown>(JSON.parse(contractJsonContent)),\n );\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const aggregate = await loadContractSpaceAggregate({\n migrationsDir,\n appContract,\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n\n const packages = aggregate.app.packages;\n const graph = aggregate.app.graph();\n const refs = aggregate.app.refs;\n\n let appPkg: OnDiskMigrationPackage;\n if (looksLikePath(target)) {\n const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);\n if (!resolved.ok) return resolved;\n const matched = findPackageByDirPath(packages, resolved.value);\n if (!matched) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `No loaded migration package at ${relative(process.cwd(), resolved.value)}`,\n fix: 'Pass a directory name, hash prefix, or path to an on-disk app-space migration package.',\n }),\n );\n }\n appPkg = matched;\n } else {\n if (packages.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 const migResult = parseMigrationRef(target, { graph, refs });\n if (!migResult.ok) {\n return notOk(mapRefResolutionError(migResult.failure));\n }\n const matchedPkg = packages.find(\n (p) => p.metadata.migrationHash === migResult.value.migrationHash,\n );\n if (!matchedPkg) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `Resolved migration \"${migResult.value.dirName}\" but the package was not loaded`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n appPkg = matchedPkg;\n }\n\n return ok({\n ok: true,\n migration: pkgToPresent(APP_SPACE_ID, appPkg, client),\n });\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 one app-space migration.\\n' +\n 'Accepts a directory path, directory name, or hash prefix.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show 20260101_100000_add_user',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration log', oneLiner: 'Show executed migration history' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n ]);\n addGlobalOptions(command)\n .argument('<target>', 'Migration reference: directory name, hash/prefix, or path')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string, options: MigrationShowOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n\n const ui = createTerminalUI(flags);\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,41 +1,9 @@
|
|
|
1
|
-
import { n as StatusRef, t as StatusDiagnostic } from "../migration-types-
|
|
1
|
+
import { n as StatusRef, t as StatusDiagnostic } from "../migration-types-CAQ-0TEE.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
-
import {
|
|
4
|
-
import { ControlExtensionDescriptor } from "@prisma-next/framework-components/control";
|
|
5
|
-
import { ContractMarkerRecordLike } from "@prisma-next/migration-tools/aggregate";
|
|
6
|
-
import { Contract } from "@prisma-next/contract/types";
|
|
7
|
-
import { OnDiskMigrationPackage } from "@prisma-next/migration-tools/package";
|
|
3
|
+
import { ContractMarkerRecordLike, ContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
|
|
8
4
|
import { MigrationGraph } from "@prisma-next/migration-tools/graph";
|
|
5
|
+
import { OnDiskMigrationPackage } from "@prisma-next/migration-tools/package";
|
|
9
6
|
|
|
10
|
-
//#region src/utils/contract-space-aggregate-loader.d.ts
|
|
11
|
-
/**
|
|
12
|
-
* Inputs needed to compose the aggregate loader at the CLI surface.
|
|
13
|
-
*
|
|
14
|
-
* Keeps the loader framework-neutral (no `Config` import) by accepting
|
|
15
|
-
* already-resolved structural inputs: validated app contract, target
|
|
16
|
-
* id, migrations root directory, and the set of extension descriptors.
|
|
17
|
-
*/
|
|
18
|
-
interface BuildAggregateInputs<TFamilyId extends string, TTargetId extends string> {
|
|
19
|
-
readonly targetId: TTargetId;
|
|
20
|
-
readonly migrationsDir: string;
|
|
21
|
-
readonly appContract: Contract;
|
|
22
|
-
readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
|
|
23
|
-
readonly deserializeContract: (contractJson: unknown) => Contract;
|
|
24
|
-
/**
|
|
25
|
-
* App-space migration packages to hydrate the app member's
|
|
26
|
-
* migration graph with. Defaults to `[]` (matches the `db init` /
|
|
27
|
-
* `db update` daily-driver behaviour, where the app's authored
|
|
28
|
-
* `migrations/` graph is not walked — the planner uses the synth
|
|
29
|
-
* strategy for the app member instead).
|
|
30
|
-
*
|
|
31
|
-
* `migrate` callers thread the user's authored app-space
|
|
32
|
-
* packages (loaded via `loadMigrationPackages(appMigrationsDir)`)
|
|
33
|
-
* through here so the graph-walk strategy can plot a path through
|
|
34
|
-
* them — the prod-time replay path explicitly forbids synth.
|
|
35
|
-
*/
|
|
36
|
-
readonly appMigrationPackages?: ReadonlyArray<OnDiskMigrationPackage>;
|
|
37
|
-
}
|
|
38
|
-
//#endregion
|
|
39
7
|
//#region src/utils/formatters/graph-migration-mapper.d.ts
|
|
40
8
|
type EdgeStatusKind = 'applied' | 'pending' | 'unreachable';
|
|
41
9
|
/** Minimal per-edge status from the CLI's status result. */
|
|
@@ -137,10 +105,9 @@ interface MigrationStatusResult {
|
|
|
137
105
|
* migrations directory) where the existing diagnostics already
|
|
138
106
|
* surface the failure.
|
|
139
107
|
*
|
|
140
|
-
* The
|
|
141
|
-
* `
|
|
142
|
-
*
|
|
143
|
-
* detail for extension members lives only on this list.
|
|
108
|
+
* The top-level fields (`migrations`, `markerHash`, `targetHash`,
|
|
109
|
+
* `pathDecision`, …) describe the **app member** specifically.
|
|
110
|
+
* Per-space detail for extension members lives only on this list.
|
|
144
111
|
*/
|
|
145
112
|
readonly spaces?: readonly MigrationStatusSpaceEntry[];
|
|
146
113
|
/** Cross-space pending-migration total (sum of `spaces[].pendingCount`). Present when `spaces` is. */
|
|
@@ -171,20 +138,16 @@ declare function deriveEdgeStatuses(graph: MigrationGraph, targetHash: string, c
|
|
|
171
138
|
/**
|
|
172
139
|
* Build the aggregate enumeration of contract spaces for the status
|
|
173
140
|
* output. Loads the aggregate from disk (lossy on failure — extension
|
|
174
|
-
* spaces are simply omitted, the
|
|
175
|
-
*
|
|
141
|
+
* spaces are simply omitted, the app member's output keeps working),
|
|
142
|
+
* reads per-space marker rows when online, and uses
|
|
176
143
|
* {@link graphWalkStrategy} to compute each space's pending count.
|
|
177
144
|
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* cross-space totals.
|
|
145
|
+
* The aggregate-walking status reports per-space marker + pending
|
|
146
|
+
* state alongside the cross-space totals.
|
|
181
147
|
*/
|
|
182
148
|
declare function loadAggregateStatusSpaces(args: {
|
|
183
|
-
readonly
|
|
184
|
-
readonly
|
|
185
|
-
readonly appContractRaw: unknown;
|
|
186
|
-
readonly extensionPacks: BuildAggregateInputs<string, string>['extensionPacks'];
|
|
187
|
-
readonly deserializeContract: BuildAggregateInputs<string, string>['deserializeContract'];
|
|
149
|
+
readonly aggregate: ContractSpaceAggregate;
|
|
150
|
+
readonly extensionPacks: ReadonlyArray<unknown>;
|
|
188
151
|
readonly markersBySpace: ReadonlyMap<string, ContractMarkerRecordLike> | null;
|
|
189
152
|
}): Promise<readonly MigrationStatusSpaceEntry[]>;
|
|
190
153
|
declare function createMigrationStatusCommand(): Command;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/
|
|
1
|
+
{"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/formatters/graph-migration-mapper.ts","../../src/commands/migration-status.ts"],"mappings":";;;;;;;KAiBY,cAAA;;UAmBK,UAAA;EAAA,SACN,OAAA;EAAA,SACA,MAAA,EAAQ,cAAc;AAAA;;;UC+ChB,oBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,cAAA;EAAA,SACA,gBAAA;EAAA,SACA,cAAA;EAAA,SACA,MAAA,EAAQ,cAAc;AAAA;;;;;ADvDA;;;;AC+CjC;;;;;;;;;;;UA8BiB,yBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;EAAA,SACA,YAAA;EAAA,SACA,MAAA;AAAA;;;;;;;;iBAUK,+BAAA,CACd,MAA4C,WAA3B,yBAAyB;AAAA,UAa3B,qBAAA;EAAA,SACN,EAAA;EAAA,SACA,IAAA;EAAA,SACA,UAAA,WAAqB,oBAAA;EAAA,SACrB,UAAA;EAAA,SACA,UAAA;EAAA,SACA,YAAA;EAAA,SACA,IAAA,YAAgB,SAAA;EAAA;EAAA,SAEhB,kBAAA;EA0CkB;;;;;;;;EAAA,SAjClB,iBAAA;EAfqB;EAAA,SAiBrB,iBAAA;EAAA,SACA,YAAA;IAAA,SACE,QAAA;IAAA,SACA,MAAA;IAAA,SACA,gBAAA;IAAA,SACA,eAAA;IAAA,SACA,OAAA;IAAA,SACA,kBAAA;IAAA,SACA,mBAAA;IAAA,SACA,YAAA;MAAA,SACE,OAAA;MAAA,SACA,aAAA;MAAA,SACA,IAAA;MAAA,SACA,EAAA;MAAA,SACA,UAAA;IAAA;EAAA;EAAA,SAGJ,OAAA;EAAA,SACA,WAAA,WAAsB,gBAAA;EANlB;;;;;;;;;;;;EAAA,SAmBJ,MAAA,YAAkB,yBAAA;EAKlB;EAAA,SAHA,wBAAA;EAAA,SACA,KAAA,GAAQ,cAAA;EAAA,SACR,OAAA,YAAmB,sBAAA;EAAA,SACnB,YAAA,YAAwB,UAAA;EAAA,SACxB,aAAA;EAAA,SACA,aAAA;EAAA,SACA,QAAA;AAAA;;;;;;;;;;;AAqDE;AAqLb;;;;iBA3LgB,kBAAA,CACd,KAAA,EAAO,cAAA,EACP,UAAA,UACA,YAAA,UACA,UAAA,sBACA,IAAA,yBACC,UAAU;;;;;;;;;;;iBAqLS,yBAAA,CAA0B,IAAA;EAAA,SACrC,SAAA,EAAW,sBAAA;EAAA,SACX,cAAA,EAAgB,aAAA;EAAA,SAChB,cAAA,EAAgB,WAAA,SAAoB,wBAAA;AAAA,IAC3C,OAAA,UAAiB,yBAAA;AAAA,iBA+pBL,4BAAA,CAAA,GAAgC,OAAO;AAAA,iBAoGvC,mBAAA,CAAoB,MAAA,EAAQ,qBAAqB,EAAE,QAAA"}
|