@prisma-next/cli 0.3.0-dev.55 → 0.3.0-dev.63

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.
Files changed (88) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +145 -6
  3. package/dist/cli-errors-JlPTsazx.mjs +3 -0
  4. package/dist/cli.mjs +29 -2
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/{client-B7f4PZZ1.mjs → client-PimzSD1f.mjs} +155 -82
  7. package/dist/client-PimzSD1f.mjs.map +1 -0
  8. package/dist/commands/contract-emit.mjs +5 -3
  9. package/dist/commands/contract-emit.mjs.map +1 -1
  10. package/dist/commands/db-init.mjs +5 -4
  11. package/dist/commands/db-init.mjs.map +1 -1
  12. package/dist/commands/db-introspect.mjs +5 -3
  13. package/dist/commands/db-introspect.mjs.map +1 -1
  14. package/dist/commands/db-schema-verify.d.mts.map +1 -1
  15. package/dist/commands/db-schema-verify.mjs +6 -4
  16. package/dist/commands/db-schema-verify.mjs.map +1 -1
  17. package/dist/commands/db-sign.d.mts.map +1 -1
  18. package/dist/commands/db-sign.mjs +6 -4
  19. package/dist/commands/db-sign.mjs.map +1 -1
  20. package/dist/commands/db-update.mjs +5 -4
  21. package/dist/commands/db-update.mjs.map +1 -1
  22. package/dist/commands/db-verify.d.mts.map +1 -1
  23. package/dist/commands/db-verify.mjs +6 -4
  24. package/dist/commands/db-verify.mjs.map +1 -1
  25. package/dist/commands/migration-apply.d.mts +23 -0
  26. package/dist/commands/migration-apply.d.mts.map +1 -0
  27. package/dist/commands/migration-apply.mjs +249 -0
  28. package/dist/commands/migration-apply.mjs.map +1 -0
  29. package/dist/commands/migration-plan.d.mts +25 -0
  30. package/dist/commands/migration-plan.d.mts.map +1 -0
  31. package/dist/commands/migration-plan.mjs +266 -0
  32. package/dist/commands/migration-plan.mjs.map +1 -0
  33. package/dist/commands/migration-show.d.mts +28 -0
  34. package/dist/commands/migration-show.d.mts.map +1 -0
  35. package/dist/commands/migration-show.mjs +138 -0
  36. package/dist/commands/migration-show.mjs.map +1 -0
  37. package/dist/commands/migration-status.d.mts +35 -0
  38. package/dist/commands/migration-status.d.mts.map +1 -0
  39. package/dist/commands/migration-status.mjs +259 -0
  40. package/dist/commands/migration-status.mjs.map +1 -0
  41. package/dist/commands/migration-verify.d.mts +16 -0
  42. package/dist/commands/migration-verify.d.mts.map +1 -0
  43. package/dist/commands/migration-verify.mjs +86 -0
  44. package/dist/commands/migration-verify.mjs.map +1 -0
  45. package/dist/{config-loader-DqKf1qSa.mjs → config-loader-PPf4CtDj.mjs} +4 -3
  46. package/dist/config-loader-PPf4CtDj.mjs.map +1 -0
  47. package/dist/config-loader.d.mts +1 -1
  48. package/dist/config-loader.d.mts.map +1 -1
  49. package/dist/config-loader.mjs +1 -1
  50. package/dist/exports/config-types.d.mts +1 -1
  51. package/dist/exports/config-types.mjs +1 -1
  52. package/dist/exports/control-api.d.mts +100 -2
  53. package/dist/exports/control-api.d.mts.map +1 -1
  54. package/dist/exports/control-api.mjs +3 -2
  55. package/dist/exports/control-api.mjs.map +1 -1
  56. package/dist/exports/index.mjs +1 -1
  57. package/dist/extract-sql-ddl-BmlKvk4o.mjs +26 -0
  58. package/dist/extract-sql-ddl-BmlKvk4o.mjs.map +1 -0
  59. package/dist/framework-components-CjV_jD8f.mjs +59 -0
  60. package/dist/framework-components-CjV_jD8f.mjs.map +1 -0
  61. package/dist/{migration-command-scaffold-BELw_do2.mjs → migration-command-scaffold-DfY_F3ev.mjs} +7 -5
  62. package/dist/migration-command-scaffold-DfY_F3ev.mjs.map +1 -0
  63. package/dist/progress-adapter-DENrzF6I.mjs +49 -0
  64. package/dist/progress-adapter-DENrzF6I.mjs.map +1 -0
  65. package/dist/{result-handler-BhmrXIvT.mjs → result-handler-iA9JtUC7.mjs} +158 -51
  66. package/dist/result-handler-iA9JtUC7.mjs.map +1 -0
  67. package/package.json +34 -12
  68. package/src/cli.ts +38 -0
  69. package/src/commands/db-schema-verify.ts +6 -4
  70. package/src/commands/db-sign.ts +6 -4
  71. package/src/commands/db-verify.ts +6 -4
  72. package/src/commands/migration-apply.ts +431 -0
  73. package/src/commands/migration-plan.ts +446 -0
  74. package/src/commands/migration-show.ts +255 -0
  75. package/src/commands/migration-status.ts +436 -0
  76. package/src/commands/migration-verify.ts +151 -0
  77. package/src/config-loader.ts +13 -3
  78. package/src/control-api/client.ts +31 -0
  79. package/src/control-api/operations/migration-apply.ts +195 -0
  80. package/src/control-api/types.ts +113 -1
  81. package/src/exports/config-types.ts +3 -3
  82. package/src/utils/command-helpers.ts +11 -0
  83. package/src/utils/migration-command-scaffold.ts +7 -6
  84. package/src/utils/output.ts +305 -3
  85. package/dist/client-B7f4PZZ1.mjs.map +0 -1
  86. package/dist/config-loader-DqKf1qSa.mjs.map +0 -1
  87. package/dist/migration-command-scaffold-BELw_do2.mjs.map +0 -1
  88. package/dist/result-handler-BhmrXIvT.mjs.map +0 -1
@@ -0,0 +1,28 @@
1
+ import { Command } from "commander";
2
+ import { CliStructuredError } from "@prisma-next/core-control-plane/errors";
3
+ import { Result } from "@prisma-next/utils/result";
4
+ import { MigrationPackage } from "@prisma-next/migration-tools/types";
5
+
6
+ //#region src/commands/migration-show.d.ts
7
+ interface MigrationShowResult {
8
+ readonly ok: true;
9
+ readonly dirName: string;
10
+ readonly dirPath: string;
11
+ readonly from: string;
12
+ readonly to: string;
13
+ readonly migrationId: string | null;
14
+ readonly kind: string;
15
+ readonly createdAt: string;
16
+ readonly operations: readonly {
17
+ readonly id: string;
18
+ readonly label: string;
19
+ readonly operationClass: string;
20
+ }[];
21
+ readonly sql: readonly string[];
22
+ readonly summary: string;
23
+ }
24
+ declare function resolveByHashPrefix(packages: readonly MigrationPackage[], prefix: string): Result<MigrationPackage, CliStructuredError>;
25
+ declare function createMigrationShowCommand(): Command;
26
+ //#endregion
27
+ export { MigrationShowResult, createMigrationShowCommand, resolveByHashPrefix };
28
+ //# sourceMappingURL=migration-show.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-show.d.mts","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":[],"mappings":";;;;;;UA8BiB,mBAAA;;EAAA,SAAA,OAAA,EAAA,MAAmB;EAsBpB,SAAA,OAAA,EAAA,MAAmB;EACd,SAAA,IAAA,EAAA,MAAA;EAEX,SAAA,EAAA,EAAA,MAAA;EAAkB,SAAA,WAAA,EAAA,MAAA,GAAA,IAAA;EAAzB,SAAA,IAAA,EAAA,MAAA;EAAM,SAAA,SAAA,EAAA,MAAA;EA0JO,SAAA,UAAA,EAAA,SAA0B;;;;;;;;iBA7J1B,mBAAA,oBACK,qCAElB,OAAO,kBAAkB;iBA0JZ,0BAAA,CAAA,GAA8B"}
@@ -0,0 +1,138 @@
1
+ import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
+ import { _ as errorUnexpected, m as errorRuntime } from "../cli-errors-JlPTsazx.mjs";
3
+ import { t as extractSqlDdl } from "../extract-sql-ddl-BmlKvk4o.mjs";
4
+ import { C as parseGlobalFlags, D as setCommandDescriptions, d as formatMigrationShowOutput, n as formatCommandHelp, t as handleResult, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
5
+ import { Command } from "commander";
6
+ import { notOk, ok } from "@prisma-next/utils/result";
7
+ import { relative, resolve } from "pathe";
8
+ import { findLatestMigration, reconstructGraph } from "@prisma-next/migration-tools/dag";
9
+ import { readMigrationPackage, readMigrationsDir } from "@prisma-next/migration-tools/io";
10
+ import { MigrationToolsError } from "@prisma-next/migration-tools/types";
11
+
12
+ //#region src/commands/migration-show.ts
13
+ function looksLikePath(target) {
14
+ return target.includes("/") || target.includes("\\");
15
+ }
16
+ function resolveByHashPrefix(packages, prefix) {
17
+ const normalizedPrefix = prefix.startsWith("sha256:") ? prefix : `sha256:${prefix}`;
18
+ const matches = packages.filter((p) => typeof p.manifest.migrationId === "string").filter((p) => p.manifest.migrationId.startsWith(normalizedPrefix));
19
+ if (matches.length === 1) return ok(matches[0]);
20
+ if (matches.length === 0) return notOk(errorRuntime("No migration found matching prefix", {
21
+ why: `No attested migration has a migrationId starting with "${normalizedPrefix}"`,
22
+ fix: "Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages."
23
+ }));
24
+ return notOk(errorRuntime("Ambiguous hash prefix", {
25
+ why: `Multiple migrations match prefix "${normalizedPrefix}":\n${matches.map((p) => ` ${p.dirName} ${p.manifest.migrationId}`).join("\n")}`,
26
+ fix: "Provide a longer prefix to uniquely identify the migration."
27
+ }));
28
+ }
29
+ async function executeMigrationShowCommand(target, options, flags) {
30
+ const config = await loadConfig(options.config);
31
+ const configPath = options.config ? relative(process.cwd(), resolve(options.config)) : "prisma-next.config.ts";
32
+ const migrationsDir = resolve(options.config ? resolve(options.config, "..") : process.cwd(), config.migrations?.dir ?? "migrations");
33
+ const migrationsRelative = relative(process.cwd(), migrationsDir);
34
+ if (flags.json !== "object" && !flags.quiet) {
35
+ const details = [{
36
+ label: "config",
37
+ value: configPath
38
+ }, {
39
+ label: "migrations",
40
+ value: migrationsRelative
41
+ }];
42
+ if (target) details.push({
43
+ label: "target",
44
+ value: target
45
+ });
46
+ const header = formatStyledHeader({
47
+ command: "migration show",
48
+ description: "Display migration package contents",
49
+ details,
50
+ flags
51
+ });
52
+ console.log(header);
53
+ }
54
+ let pkg;
55
+ try {
56
+ if (target && looksLikePath(target)) pkg = await readMigrationPackage(resolve(target));
57
+ else {
58
+ const allPackages = await readMigrationsDir(migrationsDir);
59
+ if (allPackages.length === 0) return notOk(errorRuntime("No migrations found", {
60
+ why: `No migration packages found in ${migrationsRelative}`,
61
+ fix: "Run `prisma-next migration plan` to create a migration first."
62
+ }));
63
+ if (target) {
64
+ const resolved = resolveByHashPrefix(allPackages, target);
65
+ if (!resolved.ok) return resolved;
66
+ pkg = resolved.value;
67
+ } else {
68
+ const attested = allPackages.filter((p) => typeof p.manifest.migrationId === "string");
69
+ if (attested.length === 0) return notOk(errorRuntime("No attested migrations found", {
70
+ why: `All migrations in ${migrationsRelative} are drafts (migrationId: null)`,
71
+ fix: "Run `prisma-next migration verify --dir <path>` to attest a draft migration."
72
+ }));
73
+ const latestMigration = findLatestMigration(reconstructGraph(attested));
74
+ if (!latestMigration) return notOk(errorRuntime("Could not resolve latest migration", {
75
+ why: "No latest migration found in the migration chain",
76
+ fix: "The migrations directory may be corrupted. Inspect the migration.json files."
77
+ }));
78
+ const leafPkg = attested.find((p) => p.manifest.migrationId === latestMigration.migrationId);
79
+ if (!leafPkg) return notOk(errorRuntime("Could not resolve latest migration", {
80
+ why: `Latest migration ${latestMigration.dirName} does not match any package`,
81
+ fix: "The migrations directory may be corrupted. Inspect the migration.json files."
82
+ }));
83
+ pkg = leafPkg;
84
+ }
85
+ }
86
+ } catch (error) {
87
+ if (MigrationToolsError.is(error)) return notOk(errorRuntime(error.message, {
88
+ why: error.why,
89
+ fix: error.fix,
90
+ meta: {
91
+ code: error.code,
92
+ ...error.details ?? {}
93
+ }
94
+ }));
95
+ return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read migration: ${error instanceof Error ? error.message : String(error)}` }));
96
+ }
97
+ const ops = pkg.ops;
98
+ const sql = extractSqlDdl(ops);
99
+ return ok({
100
+ ok: true,
101
+ dirName: pkg.dirName,
102
+ dirPath: relative(process.cwd(), pkg.dirPath),
103
+ from: pkg.manifest.from,
104
+ to: pkg.manifest.to,
105
+ migrationId: pkg.manifest.migrationId,
106
+ kind: pkg.manifest.kind,
107
+ createdAt: pkg.manifest.createdAt,
108
+ operations: ops.map((op) => ({
109
+ id: op.id,
110
+ label: op.label,
111
+ operationClass: op.operationClass
112
+ })),
113
+ sql,
114
+ summary: `${ops.length} operation(s)`
115
+ });
116
+ }
117
+ function createMigrationShowCommand() {
118
+ const command = new Command("show");
119
+ setCommandDescriptions(command, "Display migration package contents", "Shows the operations, DDL preview, and metadata for a migration package.\nAccepts a directory path, a hash prefix (git-style), or defaults to the\nlatest migration.");
120
+ command.configureHelp({ formatHelp: (cmd) => {
121
+ return formatCommandHelp({
122
+ command: cmd,
123
+ flags: parseGlobalFlags({})
124
+ });
125
+ } }).argument("[target]", "Migration directory path or migrationId hash prefix (defaults to latest)").option("--config <path>", "Path to prisma-next.config.ts").option("--json [format]", "Output as JSON (object)", false).option("-q, --quiet", "Quiet mode: errors only").option("-v, --verbose", "Verbose output").option("-vv, --trace", "Trace output").option("--timestamps", "Add timestamps to output").option("--color", "Force color output").option("--no-color", "Disable color output").action(async (target, options) => {
126
+ const flags = parseGlobalFlags(options);
127
+ const exitCode = handleResult(await executeMigrationShowCommand(target, options, flags), flags, (showResult) => {
128
+ if (flags.json === "object") console.log(JSON.stringify(showResult, null, 2));
129
+ else if (!flags.quiet) console.log(formatMigrationShowOutput(showResult, flags));
130
+ });
131
+ process.exit(exitCode);
132
+ });
133
+ return command;
134
+ }
135
+
136
+ //#endregion
137
+ export { createMigrationShowCommand, resolveByHashPrefix };
138
+ //# sourceMappingURL=migration-show.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-show.mjs","names":["details: Array<{ label: string; value: string }>","pkg: MigrationPackage"],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import type { MigrationPlanOperation } from '@prisma-next/core-control-plane/types';\nimport { findLatestMigration, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type { MigrationPackage } from '@prisma-next/migration-tools/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/types';\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 { extractSqlDdl } from '../control-api/operations/extract-sql-ddl';\nimport { type CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors';\nimport { setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { formatCommandHelp, formatMigrationShowOutput, formatStyledHeader } from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ninterface MigrationShowOptions {\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string | null;\n readonly kind: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly sql: readonly string[];\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 MigrationPackage[],\n prefix: string,\n): Result<MigrationPackage, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const attested = packages.filter((p) => typeof p.manifest.migrationId === 'string');\n const matches = attested.filter((p) => p.manifest.migrationId!.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 attested migration has a migrationId 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.manifest.migrationId}`).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): 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 !== 'object' && !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 console.log(header);\n }\n\n let pkg: MigrationPackage;\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 attested = allPackages.filter((p) => typeof p.manifest.migrationId === 'string');\n if (attested.length === 0) {\n return notOk(\n errorRuntime('No attested migrations found', {\n why: `All migrations in ${migrationsRelative} are drafts (migrationId: null)`,\n fix: 'Run `prisma-next migration verify --dir <path>` to attest a draft migration.',\n }),\n );\n }\n const graph = reconstructGraph(attested);\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 chain',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = attested.find(\n (p) => p.manifest.migrationId === latestMigration.migrationId,\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(\n errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n }),\n );\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 const sql = extractSqlDdl(ops);\n\n const result: MigrationShowResult = {\n ok: true,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.manifest.from,\n to: pkg.manifest.to,\n migrationId: pkg.manifest.migrationId,\n kind: pkg.manifest.kind,\n createdAt: pkg.manifest.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n sql,\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, DDL 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 command\n .configureHelp({\n formatHelp: (cmd) => {\n const defaultFlags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags: defaultFlags });\n },\n })\n .argument(\n '[target]',\n 'Migration directory path or migrationId hash prefix (defaults to latest)',\n )\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output')\n .option('-vv, --trace', 'Trace output')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const result = await executeMigrationShowCommand(target, options, flags);\n\n const exitCode = handleResult(result, flags, (showResult) => {\n if (flags.json === 'object') {\n console.log(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n console.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { Command } from "commander";
2
+ import { MigrationChainEntry, MigrationPackage } from "@prisma-next/migration-tools/types";
3
+
4
+ //#region src/commands/migration-status.d.ts
5
+ interface MigrationStatusEntry {
6
+ readonly dirName: string;
7
+ readonly from: string;
8
+ readonly to: string;
9
+ readonly migrationId: string | null;
10
+ readonly operationCount: number;
11
+ readonly operationSummary: string;
12
+ readonly hasDestructive: boolean;
13
+ readonly status: 'applied' | 'pending' | 'unknown';
14
+ }
15
+ interface StatusDiagnostic {
16
+ readonly code: string;
17
+ readonly severity: 'warn' | 'info';
18
+ readonly message: string;
19
+ readonly hints: readonly string[];
20
+ }
21
+ interface MigrationStatusResult {
22
+ readonly ok: true;
23
+ readonly mode: 'online' | 'offline';
24
+ readonly migrations: readonly MigrationStatusEntry[];
25
+ readonly markerHash?: string;
26
+ readonly leafHash: string;
27
+ readonly contractHash: string;
28
+ readonly summary: string;
29
+ readonly diagnostics: readonly StatusDiagnostic[];
30
+ }
31
+ declare function buildMigrationEntries(chain: readonly MigrationChainEntry[], packages: readonly MigrationPackage[], markerHash: string | undefined): MigrationStatusEntry[];
32
+ declare function createMigrationStatusCommand(): Command;
33
+ //#endregion
34
+ export { MigrationStatusEntry, MigrationStatusResult, StatusDiagnostic, buildMigrationEntries, createMigrationStatusCommand };
35
+ //# sourceMappingURL=migration-status.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/commands/migration-status.ts"],"sourcesContent":[],"mappings":";;;;UA6CiB,oBAAA;;EAAA,SAAA,IAAA,EAAA,MAAA;EAWA,SAAA,EAAA,EAAA,MAAgB;EAOhB,SAAA,WAAA,EAAA,MAAqB,GAAA,IAGN;EAqChB,SAAA,cAAA,EAAqB,MAAA;EACnB,SAAA,gBAAA,EAAA,MAAA;EACG,SAAA,cAAA,EAAA,OAAA;EAElB,SAAA,MAAA,EAAA,SAAA,GAAA,SAAA,GAAA,SAAA;;AA8Ra,UAjVC,gBAAA,CAiVD;;;;;;UA1UC,qBAAA;;;gCAGe;;;;;iCAKC;;iBAgCjB,qBAAA,iBACE,0CACG,qDAElB;iBA8Ra,4BAAA,CAAA,GAAgC"}
@@ -0,0 +1,259 @@
1
+ import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
+ import { _ as errorUnexpected, m as errorRuntime } from "../cli-errors-JlPTsazx.mjs";
3
+ import { t as createControlClient } from "../client-PimzSD1f.mjs";
4
+ import { C as parseGlobalFlags, D as setCommandDescriptions, T as resolveContractPath, f as formatMigrationStatusOutput, n as formatCommandHelp, t as handleResult, w as maskConnectionUrl, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
5
+ import { Command } from "commander";
6
+ import { notOk, ok } from "@prisma-next/utils/result";
7
+ import { relative, resolve } from "pathe";
8
+ import { EMPTY_CONTRACT_HASH } from "@prisma-next/core-control-plane/constants";
9
+ import { readFile } from "node:fs/promises";
10
+ import { findLeaf, findPath, reconstructGraph } from "@prisma-next/migration-tools/dag";
11
+ import { readMigrationsDir } from "@prisma-next/migration-tools/io";
12
+ import { MigrationToolsError } from "@prisma-next/migration-tools/types";
13
+
14
+ //#region src/commands/migration-status.ts
15
+ function summarizeOps(ops) {
16
+ if (ops.length === 0) return {
17
+ summary: "0 ops",
18
+ hasDestructive: false
19
+ };
20
+ const classes = /* @__PURE__ */ new Map();
21
+ for (const op of ops) classes.set(op.operationClass, (classes.get(op.operationClass) ?? 0) + 1);
22
+ const hasDestructive = classes.has("destructive");
23
+ const count = ops.length;
24
+ const noun = count === 1 ? "op" : "ops";
25
+ if (classes.size === 1) return {
26
+ summary: `${count} ${noun} (all ${[...classes.keys()][0]})`,
27
+ hasDestructive
28
+ };
29
+ const destructiveCount = classes.get("destructive");
30
+ if (destructiveCount) return {
31
+ summary: `${count} ${noun} (${destructiveCount} destructive)`,
32
+ hasDestructive
33
+ };
34
+ return {
35
+ summary: `${count} ${noun} (${[...classes.entries()].map(([cls, n]) => `${n} ${cls}`).join(", ")})`,
36
+ hasDestructive
37
+ };
38
+ }
39
+ function buildMigrationEntries(chain, packages, markerHash) {
40
+ const pkgByDirName = new Map(packages.map((p) => [p.dirName, p]));
41
+ const markerInChain = markerHash === void 0 || markerHash === EMPTY_CONTRACT_HASH || chain.some((e) => e.to === markerHash);
42
+ const entries = [];
43
+ let reachedMarker = markerHash === void 0 || markerHash === EMPTY_CONTRACT_HASH;
44
+ for (const migration of chain) {
45
+ const ops = pkgByDirName.get(migration.dirName)?.ops ?? [];
46
+ const { summary, hasDestructive } = summarizeOps(ops);
47
+ let status;
48
+ if (markerHash === void 0 || !markerInChain) status = "unknown";
49
+ else if (reachedMarker) status = "pending";
50
+ else status = "applied";
51
+ entries.push({
52
+ dirName: migration.dirName,
53
+ from: migration.from,
54
+ to: migration.to,
55
+ migrationId: migration.migrationId,
56
+ operationCount: ops.length,
57
+ operationSummary: summary,
58
+ hasDestructive,
59
+ status
60
+ });
61
+ if (!reachedMarker && migration.to === markerHash) reachedMarker = true;
62
+ }
63
+ return entries;
64
+ }
65
+ async function executeMigrationStatusCommand(options, flags) {
66
+ const config = await loadConfig(options.config);
67
+ const configPath = options.config ? relative(process.cwd(), resolve(options.config)) : "prisma-next.config.ts";
68
+ const migrationsDir = resolve(options.config ? resolve(options.config, "..") : process.cwd(), config.migrations?.dir ?? "migrations");
69
+ const migrationsRelative = relative(process.cwd(), migrationsDir);
70
+ const dbConnection = options.db ?? config.db?.connection;
71
+ const hasDriver = !!config.driver;
72
+ if (flags.json !== "object" && !flags.quiet) {
73
+ const details = [{
74
+ label: "config",
75
+ value: configPath
76
+ }, {
77
+ label: "migrations",
78
+ value: migrationsRelative
79
+ }];
80
+ if (dbConnection && hasDriver) details.push({
81
+ label: "database",
82
+ value: maskConnectionUrl(String(dbConnection))
83
+ });
84
+ const header = formatStyledHeader({
85
+ command: "migration status",
86
+ description: "Show migration chain and applied status",
87
+ details,
88
+ flags
89
+ });
90
+ console.log(header);
91
+ }
92
+ const diagnostics = [];
93
+ let contractHash = EMPTY_CONTRACT_HASH;
94
+ try {
95
+ const contractContent = await readFile(resolveContractPath(config), "utf-8");
96
+ try {
97
+ const hash = JSON.parse(contractContent)["storageHash"];
98
+ if (typeof hash === "string") contractHash = hash;
99
+ else diagnostics.push({
100
+ code: "CONTRACT.MISSING_HASH",
101
+ severity: "warn",
102
+ message: "Contract file exists but has no storageHash field",
103
+ hints: ["Run 'prisma-next contract emit' to regenerate the contract"]
104
+ });
105
+ } catch {
106
+ diagnostics.push({
107
+ code: "CONTRACT.INVALID_JSON",
108
+ severity: "warn",
109
+ message: "Contract file contains invalid JSON",
110
+ hints: ["Run 'prisma-next contract emit' to regenerate the contract"]
111
+ });
112
+ }
113
+ } catch {
114
+ diagnostics.push({
115
+ code: "CONTRACT.UNREADABLE",
116
+ severity: "warn",
117
+ message: "Could not read contract file — contract state unknown",
118
+ hints: ["Run 'prisma-next contract emit' to generate a contract"]
119
+ });
120
+ }
121
+ let allPackages;
122
+ try {
123
+ allPackages = await readMigrationsDir(migrationsDir);
124
+ } catch (error) {
125
+ if (MigrationToolsError.is(error)) return notOk(errorRuntime(error.message, {
126
+ why: error.why,
127
+ fix: error.fix,
128
+ meta: { code: error.code }
129
+ }));
130
+ return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read migrations directory: ${error instanceof Error ? error.message : String(error)}` }));
131
+ }
132
+ const attested = allPackages.filter((p) => typeof p.manifest.migrationId === "string");
133
+ if (attested.length === 0) {
134
+ if (contractHash !== EMPTY_CONTRACT_HASH) diagnostics.push({
135
+ code: "CONTRACT.AHEAD",
136
+ severity: "warn",
137
+ message: "Contract has changed since the last migration was planned",
138
+ hints: ["Run 'prisma-next migration plan' to generate a migration for the current contract"]
139
+ });
140
+ return ok({
141
+ ok: true,
142
+ mode: dbConnection && hasDriver ? "online" : "offline",
143
+ migrations: [],
144
+ leafHash: EMPTY_CONTRACT_HASH,
145
+ contractHash,
146
+ summary: "No migrations found",
147
+ diagnostics
148
+ });
149
+ }
150
+ let graph;
151
+ let leafHash;
152
+ try {
153
+ graph = reconstructGraph(attested);
154
+ leafHash = findLeaf(graph);
155
+ } catch (error) {
156
+ if (MigrationToolsError.is(error)) return notOk(errorRuntime(error.message, {
157
+ why: error.why,
158
+ fix: error.fix,
159
+ meta: { code: error.code }
160
+ }));
161
+ throw error;
162
+ }
163
+ const chain = findPath(graph, EMPTY_CONTRACT_HASH, leafHash);
164
+ if (!chain) return notOk(errorRuntime("Cannot reconstruct migration chain", {
165
+ why: `No path from ${EMPTY_CONTRACT_HASH} to leaf ${leafHash}`,
166
+ fix: "The migration history may have gaps. Check the migrations directory for missing or corrupted packages."
167
+ }));
168
+ let markerHash;
169
+ let mode = "offline";
170
+ if (dbConnection && hasDriver) try {
171
+ const client = createControlClient({
172
+ family: config.family,
173
+ target: config.target,
174
+ adapter: config.adapter,
175
+ driver: config.driver,
176
+ extensionPacks: config.extensionPacks ?? []
177
+ });
178
+ try {
179
+ await client.connect(dbConnection);
180
+ markerHash = (await client.readMarker())?.storageHash ?? EMPTY_CONTRACT_HASH;
181
+ mode = "online";
182
+ } finally {
183
+ await client.close();
184
+ }
185
+ } catch {
186
+ if (flags.json !== "object" && !flags.quiet) console.log(" ⚠ Could not connect to database — showing offline status\n");
187
+ }
188
+ const entries = buildMigrationEntries(chain, attested, mode === "online" ? markerHash : void 0);
189
+ const markerInChain = markerHash === void 0 || markerHash === EMPTY_CONTRACT_HASH || chain.some((e) => e.to === markerHash);
190
+ let summary;
191
+ if (mode === "online") if (!markerInChain) summary = `Database marker does not match any migration — was the database managed with 'db update'?`;
192
+ else {
193
+ const pendingCount = entries.filter((e) => e.status === "pending").length;
194
+ const appliedCount = entries.filter((e) => e.status === "applied").length;
195
+ if (pendingCount === 0) summary = `Database is up to date (${appliedCount} migration${appliedCount !== 1 ? "s" : ""} applied)`;
196
+ else if (markerHash === EMPTY_CONTRACT_HASH) summary = `${pendingCount} pending migration(s) — database has no marker`;
197
+ else summary = `${pendingCount} pending migration(s) — run 'prisma-next migration apply' to apply`;
198
+ }
199
+ else summary = `${entries.length} migration(s) on disk`;
200
+ if (contractHash !== EMPTY_CONTRACT_HASH && contractHash !== leafHash) diagnostics.push({
201
+ code: "CONTRACT.AHEAD",
202
+ severity: "warn",
203
+ message: "Contract has changed since the last migration was planned",
204
+ hints: ["Run 'prisma-next migration plan' to generate a migration for the current contract"]
205
+ });
206
+ if (mode === "online") {
207
+ const pendingCount = entries.filter((e) => e.status === "pending").length;
208
+ if (!markerInChain) diagnostics.push({
209
+ code: "MIGRATION.MARKER_DIVERGED",
210
+ severity: "warn",
211
+ message: "Database marker does not match any migration in the chain",
212
+ hints: ["The database may have been managed with 'db update' instead of migrations", "Run 'prisma-next db verify' to inspect the database state"]
213
+ });
214
+ else if (pendingCount > 0) diagnostics.push({
215
+ code: "MIGRATION.DATABASE_BEHIND",
216
+ severity: "info",
217
+ message: `${pendingCount} migration(s) pending`,
218
+ hints: ["Run 'prisma-next migration apply' to apply pending migrations"]
219
+ });
220
+ else diagnostics.push({
221
+ code: "MIGRATION.UP_TO_DATE",
222
+ severity: "info",
223
+ message: "Database is up to date",
224
+ hints: []
225
+ });
226
+ }
227
+ return ok({
228
+ ok: true,
229
+ mode,
230
+ migrations: entries,
231
+ leafHash,
232
+ contractHash,
233
+ summary,
234
+ diagnostics,
235
+ ...markerHash !== void 0 ? { markerHash } : {}
236
+ });
237
+ }
238
+ function createMigrationStatusCommand() {
239
+ const command = new Command("status");
240
+ setCommandDescriptions(command, "Show migration chain and applied status", "Displays the migration chain in order. When a database connection\nis available, shows which migrations are applied and which are pending.\nWithout a database connection, shows the chain from disk only.");
241
+ command.configureHelp({ formatHelp: (cmd) => {
242
+ return formatCommandHelp({
243
+ command: cmd,
244
+ flags: parseGlobalFlags({})
245
+ });
246
+ } }).option("--db <url>", "Database connection string").option("--config <path>", "Path to prisma-next.config.ts").option("--json [format]", "Output as JSON (object)", false).option("-q, --quiet", "Quiet mode: errors only").option("-v, --verbose", "Verbose output").option("-vv, --trace", "Trace output").option("--timestamps", "Add timestamps to output").option("--color", "Force color output").option("--no-color", "Disable color output").action(async (options) => {
247
+ const flags = parseGlobalFlags(options);
248
+ const exitCode = handleResult(await executeMigrationStatusCommand(options, flags), flags, (statusResult) => {
249
+ if (flags.json === "object") console.log(JSON.stringify(statusResult, null, 2));
250
+ else if (!flags.quiet) console.log(formatMigrationStatusOutput(statusResult, flags));
251
+ });
252
+ process.exit(exitCode);
253
+ });
254
+ return command;
255
+ }
256
+
257
+ //#endregion
258
+ export { buildMigrationEntries, createMigrationStatusCommand };
259
+ //# sourceMappingURL=migration-status.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-status.mjs","names":["entries: MigrationStatusEntry[]","status: 'applied' | 'pending' | 'unknown'","details: Array<{ label: string; value: string }>","diagnostics: StatusDiagnostic[]","contractHash: string","allPackages: readonly MigrationPackage[]","graph: MigrationGraph","leafHash: string","markerHash: string | undefined","mode: 'online' | 'offline'","summary: string"],"sources":["../../src/commands/migration-status.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { EMPTY_CONTRACT_HASH } from '@prisma-next/core-control-plane/constants';\nimport type { MigrationPlanOperation } from '@prisma-next/core-control-plane/types';\nimport { findLeaf, findPath, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type {\n MigrationChainEntry,\n MigrationGraph,\n MigrationPackage,\n} from '@prisma-next/migration-tools/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/types';\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 { type CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatMigrationStatusOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ninterface MigrationStatusOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\nexport interface MigrationStatusEntry {\n readonly dirName: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string | null;\n readonly operationCount: number;\n readonly operationSummary: string;\n readonly hasDestructive: boolean;\n readonly status: 'applied' | 'pending' | 'unknown';\n}\n\nexport interface StatusDiagnostic {\n readonly code: string;\n readonly severity: 'warn' | 'info';\n readonly message: string;\n readonly hints: readonly string[];\n}\n\nexport interface MigrationStatusResult {\n readonly ok: true;\n readonly mode: 'online' | 'offline';\n readonly migrations: readonly MigrationStatusEntry[];\n readonly markerHash?: string;\n readonly leafHash: string;\n readonly contractHash: string;\n readonly summary: string;\n readonly diagnostics: readonly StatusDiagnostic[];\n}\n\nfunction summarizeOps(ops: readonly MigrationPlanOperation[]): {\n summary: string;\n hasDestructive: boolean;\n} {\n if (ops.length === 0) return { summary: '0 ops', hasDestructive: false };\n\n const classes = new Map<string, number>();\n for (const op of ops) {\n classes.set(op.operationClass, (classes.get(op.operationClass) ?? 0) + 1);\n }\n\n const hasDestructive = classes.has('destructive');\n const count = ops.length;\n const noun = count === 1 ? 'op' : 'ops';\n\n if (classes.size === 1) {\n const cls = [...classes.keys()][0]!;\n return { summary: `${count} ${noun} (all ${cls})`, hasDestructive };\n }\n\n const destructiveCount = classes.get('destructive');\n if (destructiveCount) {\n return { summary: `${count} ${noun} (${destructiveCount} destructive)`, hasDestructive };\n }\n\n const parts = [...classes.entries()].map(([cls, n]) => `${n} ${cls}`);\n return { summary: `${count} ${noun} (${parts.join(', ')})`, hasDestructive };\n}\n\nexport function buildMigrationEntries(\n chain: readonly MigrationChainEntry[],\n packages: readonly MigrationPackage[],\n markerHash: string | undefined,\n): MigrationStatusEntry[] {\n const pkgByDirName = new Map(packages.map((p) => [p.dirName, p]));\n\n const markerInChain =\n markerHash === undefined ||\n markerHash === EMPTY_CONTRACT_HASH ||\n chain.some((e) => e.to === markerHash);\n\n const entries: MigrationStatusEntry[] = [];\n let reachedMarker = markerHash === undefined || markerHash === EMPTY_CONTRACT_HASH;\n\n for (const migration of chain) {\n const pkg = pkgByDirName.get(migration.dirName);\n const ops = (pkg?.ops ?? []) as readonly MigrationPlanOperation[];\n const { summary, hasDestructive } = summarizeOps(ops);\n\n let status: 'applied' | 'pending' | 'unknown';\n if (markerHash === undefined || !markerInChain) {\n status = 'unknown';\n } else if (reachedMarker) {\n status = 'pending';\n } else {\n status = 'applied';\n }\n\n entries.push({\n dirName: migration.dirName,\n from: migration.from,\n to: migration.to,\n migrationId: migration.migrationId,\n operationCount: ops.length,\n operationSummary: summary,\n hasDestructive,\n status,\n });\n\n if (!reachedMarker && migration.to === markerHash) {\n reachedMarker = true;\n }\n }\n\n return entries;\n}\n\nasync function executeMigrationStatusCommand(\n options: MigrationStatusOptions,\n flags: GlobalFlags,\n): Promise<Result<MigrationStatusResult, 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 const dbConnection = options.db ?? config.db?.connection;\n const hasDriver = !!config.driver;\n\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (dbConnection && hasDriver) {\n details.push({ label: 'database', value: maskConnectionUrl(String(dbConnection)) });\n }\n const header = formatStyledHeader({\n command: 'migration status',\n description: 'Show migration chain and applied status',\n details,\n flags,\n });\n console.log(header);\n }\n\n const diagnostics: StatusDiagnostic[] = [];\n let contractHash: string = EMPTY_CONTRACT_HASH;\n try {\n const contractPathAbsolute = resolveContractPath(config);\n const contractContent = await readFile(contractPathAbsolute, 'utf-8');\n try {\n const contractRaw = JSON.parse(contractContent) as Record<string, unknown>;\n const hash = contractRaw['storageHash'];\n if (typeof hash === 'string') {\n contractHash = hash;\n } else {\n diagnostics.push({\n code: 'CONTRACT.MISSING_HASH',\n severity: 'warn',\n message: 'Contract file exists but has no storageHash field',\n hints: [\"Run 'prisma-next contract emit' to regenerate the contract\"],\n });\n }\n } catch {\n diagnostics.push({\n code: 'CONTRACT.INVALID_JSON',\n severity: 'warn',\n message: 'Contract file contains invalid JSON',\n hints: [\"Run 'prisma-next contract emit' to regenerate the contract\"],\n });\n }\n } catch {\n diagnostics.push({\n code: 'CONTRACT.UNREADABLE',\n severity: 'warn',\n message: 'Could not read contract file — contract state unknown',\n hints: [\"Run 'prisma-next contract emit' to generate a contract\"],\n });\n }\n\n let allPackages: readonly MigrationPackage[];\n try {\n allPackages = await readMigrationsDir(migrationsDir);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, { why: error.why, fix: error.fix, meta: { code: error.code } }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migrations directory: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const attested = allPackages.filter((p) => typeof p.manifest.migrationId === 'string');\n\n if (attested.length === 0) {\n if (contractHash !== EMPTY_CONTRACT_HASH) {\n diagnostics.push({\n code: 'CONTRACT.AHEAD',\n severity: 'warn',\n message: 'Contract has changed since the last migration was planned',\n hints: [\n \"Run 'prisma-next migration plan' to generate a migration for the current contract\",\n ],\n });\n }\n return ok({\n ok: true,\n mode: dbConnection && hasDriver ? 'online' : 'offline',\n migrations: [],\n leafHash: EMPTY_CONTRACT_HASH,\n contractHash,\n summary: 'No migrations found',\n diagnostics,\n });\n }\n\n let graph: MigrationGraph;\n let leafHash: string;\n try {\n graph = reconstructGraph(attested);\n leafHash = findLeaf(graph);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, { why: error.why, fix: error.fix, meta: { code: error.code } }),\n );\n }\n throw error;\n }\n\n const chain = findPath(graph, EMPTY_CONTRACT_HASH, leafHash);\n if (!chain) {\n return notOk(\n errorRuntime('Cannot reconstruct migration chain', {\n why: `No path from ${EMPTY_CONTRACT_HASH} to leaf ${leafHash}`,\n fix: 'The migration history may have gaps. Check the migrations directory for missing or corrupted packages.',\n }),\n );\n }\n\n let markerHash: string | undefined;\n let mode: 'online' | 'offline' = 'offline';\n\n if (dbConnection && hasDriver) {\n try {\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n try {\n await client.connect(dbConnection);\n const marker = await client.readMarker();\n markerHash = marker?.storageHash ?? EMPTY_CONTRACT_HASH;\n mode = 'online';\n } finally {\n await client.close();\n }\n } catch {\n if (flags.json !== 'object' && !flags.quiet) {\n console.log(' ⚠ Could not connect to database — showing offline status\\n');\n }\n }\n }\n\n const entries = buildMigrationEntries(\n chain,\n attested,\n mode === 'online' ? markerHash : undefined,\n );\n\n const markerInChain =\n markerHash === undefined ||\n markerHash === EMPTY_CONTRACT_HASH ||\n chain.some((e) => e.to === markerHash);\n\n let summary: string;\n if (mode === 'online') {\n if (!markerInChain) {\n summary = `Database marker does not match any migration — was the database managed with 'db update'?`;\n } else {\n const pendingCount = entries.filter((e) => e.status === 'pending').length;\n const appliedCount = entries.filter((e) => e.status === 'applied').length;\n if (pendingCount === 0) {\n summary = `Database is up to date (${appliedCount} migration${appliedCount !== 1 ? 's' : ''} applied)`;\n } else if (markerHash === EMPTY_CONTRACT_HASH) {\n summary = `${pendingCount} pending migration(s) — database has no marker`;\n } else {\n summary = `${pendingCount} pending migration(s) — run 'prisma-next migration apply' to apply`;\n }\n }\n } else {\n summary = `${entries.length} migration(s) on disk`;\n }\n\n if (contractHash !== EMPTY_CONTRACT_HASH && contractHash !== leafHash) {\n diagnostics.push({\n code: 'CONTRACT.AHEAD',\n severity: 'warn',\n message: 'Contract has changed since the last migration was planned',\n hints: [\"Run 'prisma-next migration plan' to generate a migration for the current contract\"],\n });\n }\n\n if (mode === 'online') {\n const pendingCount = entries.filter((e) => e.status === 'pending').length;\n if (!markerInChain) {\n diagnostics.push({\n code: 'MIGRATION.MARKER_DIVERGED',\n severity: 'warn',\n message: 'Database marker does not match any migration in the chain',\n hints: [\n \"The database may have been managed with 'db update' instead of migrations\",\n \"Run 'prisma-next db verify' to inspect the database state\",\n ],\n });\n } else if (pendingCount > 0) {\n diagnostics.push({\n code: 'MIGRATION.DATABASE_BEHIND',\n severity: 'info',\n message: `${pendingCount} migration(s) pending`,\n hints: [\"Run 'prisma-next migration apply' to apply pending migrations\"],\n });\n } else {\n diagnostics.push({\n code: 'MIGRATION.UP_TO_DATE',\n severity: 'info',\n message: 'Database is up to date',\n hints: [],\n });\n }\n }\n\n const result: MigrationStatusResult = {\n ok: true,\n mode,\n migrations: entries,\n leafHash,\n contractHash,\n summary,\n diagnostics,\n ...(markerHash !== undefined ? { markerHash } : {}),\n };\n return ok(result);\n}\n\nexport function createMigrationStatusCommand(): Command {\n const command = new Command('status');\n setCommandDescriptions(\n command,\n 'Show migration chain and applied status',\n 'Displays the migration chain in order. When a database connection\\n' +\n 'is available, shows which migrations are applied and which are pending.\\n' +\n 'Without a database connection, shows the chain from disk only.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const defaultFlags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags: defaultFlags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output')\n .option('-vv, --trace', 'Trace output')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: MigrationStatusOptions) => {\n const flags = parseGlobalFlags(options);\n\n const result = await executeMigrationStatusCommand(options, flags);\n\n const exitCode = handleResult(result, flags, (statusResult) => {\n if (flags.json === 'object') {\n console.log(JSON.stringify(statusResult, null, 2));\n } else if (!flags.quiet) {\n console.log(formatMigrationStatusOutput(statusResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Command } from "commander";
2
+
3
+ //#region src/commands/migration-verify.d.ts
4
+ interface MigrationVerifyResult {
5
+ readonly ok: boolean;
6
+ readonly status: 'verified' | 'attested';
7
+ readonly dir: string;
8
+ readonly migrationId?: string;
9
+ readonly storedMigrationId?: string;
10
+ readonly computedMigrationId?: string;
11
+ readonly summary: string;
12
+ }
13
+ declare function createMigrationVerifyCommand(): Command;
14
+ //#endregion
15
+ export { MigrationVerifyResult, createMigrationVerifyCommand };
16
+ //# sourceMappingURL=migration-verify.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-verify.d.mts","names":[],"sources":["../../src/commands/migration-verify.ts"],"sourcesContent":[],"mappings":";;;UA6BiB,qBAAA;;EAAA,SAAA,MAAA,EAAA,UAAqB,GAAA,UAAA;EAgFtB,SAAA,GAAA,EAAA,MAAA;;;;;;iBAAA,4BAAA,CAAA,GAAgC"}