prisma-next 0.12.0-dev.3 → 0.12.0-dev.31

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 (113) hide show
  1. package/dist/cli.mjs +180 -163
  2. package/dist/cli.mjs.map +1 -1
  3. package/dist/{client-KgJorIvG.mjs → client-xeWpMlq1.mjs} +39 -15
  4. package/dist/client-xeWpMlq1.mjs.map +1 -0
  5. package/dist/{command-helpers-Bbw1GbwL.mjs → command-helpers-DK_5ItoJ.mjs} +284 -24
  6. package/dist/command-helpers-DK_5ItoJ.mjs.map +1 -0
  7. package/dist/commands/contract-emit.mjs +1 -1
  8. package/dist/commands/contract-infer.mjs +1 -1
  9. package/dist/commands/db-init.mjs +4 -5
  10. package/dist/commands/db-init.mjs.map +1 -1
  11. package/dist/commands/db-schema.mjs +3 -3
  12. package/dist/commands/db-sign.mjs +4 -4
  13. package/dist/commands/db-update.d.mts.map +1 -1
  14. package/dist/commands/db-update.mjs +10 -7
  15. package/dist/commands/db-update.mjs.map +1 -1
  16. package/dist/commands/db-verify.mjs +1 -1
  17. package/dist/commands/migrate.d.mts +1 -1
  18. package/dist/commands/migrate.mjs +5 -6
  19. package/dist/commands/migrate.mjs.map +1 -1
  20. package/dist/commands/migration-check.mjs +1 -1
  21. package/dist/commands/migration-graph.d.mts +13 -7
  22. package/dist/commands/migration-graph.d.mts.map +1 -1
  23. package/dist/commands/migration-graph.mjs +171 -2
  24. package/dist/commands/migration-graph.mjs.map +1 -0
  25. package/dist/commands/migration-list.d.mts +24 -26
  26. package/dist/commands/migration-list.d.mts.map +1 -1
  27. package/dist/commands/migration-list.mjs +2 -190
  28. package/dist/commands/migration-log.d.mts +6 -18
  29. package/dist/commands/migration-log.d.mts.map +1 -1
  30. package/dist/commands/migration-log.mjs +1 -137
  31. package/dist/commands/migration-new.mjs +3 -3
  32. package/dist/commands/migration-plan.d.mts +1 -1
  33. package/dist/commands/migration-plan.mjs +1 -1
  34. package/dist/commands/migration-show.d.mts +1 -1
  35. package/dist/commands/migration-show.mjs +3 -4
  36. package/dist/commands/migration-show.mjs.map +1 -1
  37. package/dist/commands/migration-status.d.mts +41 -141
  38. package/dist/commands/migration-status.d.mts.map +1 -1
  39. package/dist/commands/migration-status.mjs +2 -759
  40. package/dist/commands/ref.d.mts +1 -1
  41. package/dist/commands/ref.mjs +3 -3
  42. package/dist/commands/telemetry/index.d.mts +7 -0
  43. package/dist/commands/telemetry/index.d.mts.map +1 -0
  44. package/dist/commands/telemetry/index.mjs +2 -0
  45. package/dist/{contract-at-errors-BxP-TOMl.mjs → contract-at-errors-DG3kjgoz.mjs} +2 -2
  46. package/dist/{contract-at-errors-BxP-TOMl.mjs.map → contract-at-errors-DG3kjgoz.mjs.map} +1 -1
  47. package/dist/{contract-emit-D-4jrNve.mjs → contract-emit-BO0l6fnT.mjs} +3 -3
  48. package/dist/{contract-emit-D-4jrNve.mjs.map → contract-emit-BO0l6fnT.mjs.map} +1 -1
  49. package/dist/{contract-emit-DxcGl4Uq.mjs → contract-emit-C0Bs0VRj.mjs} +3 -3
  50. package/dist/{contract-emit-DxcGl4Uq.mjs.map → contract-emit-C0Bs0VRj.mjs.map} +1 -1
  51. package/dist/{contract-infer-D8uEbJuu.mjs → contract-infer-2wtPflGH.mjs} +3 -3
  52. package/dist/{contract-infer-D8uEbJuu.mjs.map → contract-infer-2wtPflGH.mjs.map} +1 -1
  53. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs → contract-space-aggregate-loader-Dbr3-jHF.mjs} +4 -4
  54. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs.map → contract-space-aggregate-loader-Dbr3-jHF.mjs.map} +1 -1
  55. package/dist/{db-verify-v_vUKXTU.mjs → db-verify-CxHiSiTG.mjs} +4 -4
  56. package/dist/{db-verify-v_vUKXTU.mjs.map → db-verify-CxHiSiTG.mjs.map} +1 -1
  57. package/dist/exports/control-api.d.mts +1 -1
  58. package/dist/exports/control-api.d.mts.map +1 -1
  59. package/dist/exports/control-api.mjs +2 -2
  60. package/dist/exports/index.mjs +1 -1
  61. package/dist/exports/init-output.mjs +1 -1
  62. package/dist/{framework-components-fYXjz_in.mjs → framework-components-CxOVKAAh.mjs} +2 -2
  63. package/dist/{framework-components-fYXjz_in.mjs.map → framework-components-CxOVKAAh.mjs.map} +1 -1
  64. package/dist/{global-flags-DEHjV8_s.d.mts → global-flags-DG4uY5tV.d.mts} +1 -1
  65. package/dist/{global-flags-DEHjV8_s.d.mts.map → global-flags-DG4uY5tV.d.mts.map} +1 -1
  66. package/dist/{init-Cv9UzWL5.mjs → init-R272pxux.mjs} +5 -58
  67. package/dist/init-R272pxux.mjs.map +1 -0
  68. package/dist/{inspect-live-schema-C6ohV_oQ.mjs → inspect-live-schema-RekOwfi5.mjs} +3 -3
  69. package/dist/{inspect-live-schema-C6ohV_oQ.mjs.map → inspect-live-schema-RekOwfi5.mjs.map} +1 -1
  70. package/dist/{migration-check-BiBJoYYW.mjs → migration-check-Dc0cOhKH.mjs} +2 -2
  71. package/dist/{migration-check-BiBJoYYW.mjs.map → migration-check-Dc0cOhKH.mjs.map} +1 -1
  72. package/dist/{migration-command-scaffold-CjvwO6at.mjs → migration-command-scaffold-ApB3NxWY.mjs} +3 -3
  73. package/dist/{migration-command-scaffold-CjvwO6at.mjs.map → migration-command-scaffold-ApB3NxWY.mjs.map} +1 -1
  74. package/dist/migration-graph-space-render-dmLLWift.mjs +1966 -0
  75. package/dist/migration-graph-space-render-dmLLWift.mjs.map +1 -0
  76. package/dist/migration-list-C5sXrl0U.mjs +228 -0
  77. package/dist/migration-list-C5sXrl0U.mjs.map +1 -0
  78. package/dist/migration-list-types-DS63IdFd.d.mts +23 -0
  79. package/dist/migration-list-types-DS63IdFd.d.mts.map +1 -0
  80. package/dist/migration-log-DD_vCbYW.mjs +203 -0
  81. package/dist/migration-log-DD_vCbYW.mjs.map +1 -0
  82. package/dist/{migration-plan-9DJ7q7_z.mjs → migration-plan-CeTjQOIG.mjs} +5 -5
  83. package/dist/{migration-plan-9DJ7q7_z.mjs.map → migration-plan-CeTjQOIG.mjs.map} +1 -1
  84. package/dist/migration-status-qV8ctwPy.mjs +432 -0
  85. package/dist/migration-status-qV8ctwPy.mjs.map +1 -0
  86. package/dist/{output-B60Gw5fu.mjs → output-CF_hqzI-.mjs} +1 -1
  87. package/dist/{output-B60Gw5fu.mjs.map → output-CF_hqzI-.mjs.map} +1 -1
  88. package/dist/{ref-advancement-DUZqsue6.mjs → ref-advancement-V1o-9LVK.mjs} +1 -1
  89. package/dist/{ref-advancement-DUZqsue6.mjs.map → ref-advancement-V1o-9LVK.mjs.map} +1 -1
  90. package/dist/telemetry-S-NGi9U6.mjs +122 -0
  91. package/dist/telemetry-S-NGi9U6.mjs.map +1 -0
  92. package/dist/{types-Dt_SfqFm.d.mts → types-Mh7mdPHM.d.mts} +13 -2
  93. package/dist/types-Mh7mdPHM.d.mts.map +1 -0
  94. package/dist/{verify-DCA9Sldu.mjs → verify-BdI-BgYi.mjs} +2 -2
  95. package/dist/{verify-DCA9Sldu.mjs.map → verify-BdI-BgYi.mjs.map} +1 -1
  96. package/package.json +11 -12
  97. package/dist/client-KgJorIvG.mjs.map +0 -1
  98. package/dist/command-helpers-Bbw1GbwL.mjs.map +0 -1
  99. package/dist/commands/migration-list.mjs.map +0 -1
  100. package/dist/commands/migration-log.mjs.map +0 -1
  101. package/dist/commands/migration-status.mjs.map +0 -1
  102. package/dist/graph-render-rFAqZujX.mjs +0 -1081
  103. package/dist/graph-render-rFAqZujX.mjs.map +0 -1
  104. package/dist/init-Cv9UzWL5.mjs.map +0 -1
  105. package/dist/migration-graph-D7DVUElV.mjs +0 -1232
  106. package/dist/migration-graph-D7DVUElV.mjs.map +0 -1
  107. package/dist/migration-list-styler-BRwF4-gy.mjs +0 -399
  108. package/dist/migration-list-styler-BRwF4-gy.mjs.map +0 -1
  109. package/dist/migration-types-D2FW63pr.d.mts +0 -15
  110. package/dist/migration-types-D2FW63pr.d.mts.map +0 -1
  111. package/dist/migrations-Cv2jxNNK.mjs +0 -228
  112. package/dist/migrations-Cv2jxNNK.mjs.map +0 -1
  113. package/dist/types-Dt_SfqFm.d.mts.map +0 -1
@@ -1,4 +1,4 @@
1
- import { E as PerSpaceExecutionEntry, w as MigrationApplyPathDecision } from "../types-Dt_SfqFm.mjs";
1
+ import { E as PerSpaceExecutionEntry, w as MigrationApplyPathDecision } from "../types-Mh7mdPHM.mjs";
2
2
  import { Command } from "commander";
3
3
 
4
4
  //#region src/commands/migrate.d.ts
@@ -1,11 +1,10 @@
1
1
  import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
2
- import { $ as errorTargetMigrationNotSupported, A as CliStructuredError, F as errorDatabaseConnectionRequired, L as errorDriverRequired, P as errorContractValidationFailed, R as errorFileNotFound, T as formatStyledHeader, V as errorMarkerMismatch, W as errorPathUnreachable, X as errorRuntime, _ as createTerminalUI, f as targetSupportsMigrations, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, l as setCommandDescriptions, n as collectDeclaredInvariants, nt as mapMigrationToolsError, o as resolveContractPath, rt as mapRefResolutionError, s as resolveMigrationPaths, t as addGlobalOptions, tt as errorUnexpected, u as setCommandExamples, y as handleResult } from "../command-helpers-Bbw1GbwL.mjs";
3
- import { t as createControlClient } from "../client-KgJorIvG.mjs";
2
+ import { A as formatStyledHeader, B as errorDatabaseConnectionRequired, F as CliStructuredError, H as errorDriverRequired, S as formatMigrationApplyCommandOutput, U as errorFileNotFound, X as errorPathUnreachable, _ as createTerminalUI, at as errorTargetMigrationNotSupported, ct as mapMigrationToolsError, f as targetSupportsMigrations, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, l as setCommandDescriptions, lt as mapRefResolutionError, n as collectDeclaredInvariants, nt as errorRuntime, o as resolveContractPath, q as errorMarkerMismatch, s as resolveMigrationPaths, st as errorUnexpected, t as addGlobalOptions, u as setCommandExamples, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-DK_5ItoJ.mjs";
3
+ import { t as createControlClient } from "../client-xeWpMlq1.mjs";
4
4
  import { t as toDeclaredExtensionsFromRaw } from "../extension-pack-inputs-IDvjRCi3.mjs";
5
- import { a as loadContractSpaceAggregateForCli, o as refuseContractSpaceIntegrity } from "../contract-space-aggregate-loader-DvZwdkrr.mjs";
6
- import { t as formatMigrationApplyCommandOutput } from "../migrations-Cv2jxNNK.mjs";
7
- import { i as readContractIR, r as executeRefAdvancement } from "../ref-advancement-DUZqsue6.mjs";
8
- import { t as mapContractAtError } from "../contract-at-errors-BxP-TOMl.mjs";
5
+ import { a as refuseContractSpaceIntegrity, i as loadContractSpaceAggregateForCli } from "../contract-space-aggregate-loader-Dbr3-jHF.mjs";
6
+ import { i as readContractIR, r as executeRefAdvancement } from "../ref-advancement-V1o-9LVK.mjs";
7
+ import { t as mapContractAtError } from "../contract-at-errors-DG3kjgoz.mjs";
9
8
  import { Command } from "commander";
10
9
  import { ifDefined } from "@prisma-next/utils/defined";
11
10
  import { notOk, ok } from "@prisma-next/utils/result";
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.mjs","names":[],"sources":["../../src/commands/migrate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { RefEntry } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type {\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n PerSpaceExecutionEntry,\n} from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorMarkerMismatch,\n errorPathUnreachable,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n collectDeclaredInvariants,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { mapContractAtError } from '../utils/contract-at-errors';\nimport {\n loadContractSpaceAggregateForCli,\n refuseContractSpaceIntegrity,\n} from '../utils/contract-space-aggregate-loader';\nimport { toDeclaredExtensionsFromRaw } from '../utils/extension-pack-inputs';\nimport { formatMigrationApplyCommandOutput } 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 { executeRefAdvancement, readContractIR } from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrateCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly to?: string;\n readonly advanceRef?: string;\n}\n\nexport interface MigrateResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName: string;\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n readonly pathDecision?: MigrationApplyPathDecision;\n readonly timings: {\n readonly total: number;\n };\n readonly advancedRef?: { readonly name: string; readonly hash: string } | null;\n}\n\nfunction mapApplyFailure(failure: MigrationApplyFailure): CliStructuredErrorType {\n if (failure.code === 'MIGRATION_PATH_NOT_FOUND') {\n return errorPathUnreachable(failure);\n }\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the issue and re-run `prisma-next migrate --to <contract>` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nasync function executeMigrateCommand(\n options: MigrateCommandOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrateResult, CliStructuredErrorType>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsRelative, refsDir } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migrate (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migrate',\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: 'Config.driver is required for migrate',\n }),\n );\n }\n\n if (!targetSupportsMigrations(config.target)) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n const toArg = options.to;\n\n // Construct the family instance up-front so the on-disk contract read\n // crosses the serializer seam (`familyInstance.deserializeContract`) at\n // the read site. The downstream `client.migrationApply({ contract })`\n // re-validates internally (no harm — validation is idempotent), but\n // closing the gap at the read site is what makes the cast-pattern\n // lint enforceable and matches the other CLI commands. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n const contractPathAbsolute = resolveContractPath(config);\n let contractRaw: Contract;\n let contractContent: string;\n try {\n contractContent = 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 a valid contract.json, then retry.',\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n try {\n contractRaw = familyInstance.deserializeContract(JSON.parse(contractContent) 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 loadedAggregate = await loadContractSpaceAggregateForCli({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: contractRaw,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json) => familyInstance.deserializeContract(json),\n });\n if (!loadedAggregate.ok) {\n return notOk(loadedAggregate.failure);\n }\n const aggregate = loadedAggregate.value;\n const integrityFailure = refuseContractSpaceIntegrity(aggregate, {\n declaredExtensions: toDeclaredExtensionsFromRaw(\n (config.extensionPacks ?? []) as ReadonlyArray<unknown>,\n ),\n checkContracts: true,\n });\n if (integrityFailure) {\n return notOk(integrityFailure);\n }\n\n let refEntry: RefEntry | undefined;\n let refName: string | undefined;\n if (toArg) {\n const refs = aggregate.app.refs;\n const refResult = parseContractRef(toArg, { graph: aggregate.app.graph(), refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n if (refResult.value.provenance.kind === 'ref') {\n refName = refResult.value.provenance.refName;\n const resolved = refs[refName];\n if (resolved) refEntry = resolved;\n } else {\n refEntry = { hash: refResult.value.hash, invariants: [] };\n }\n }\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({\n label: 'database',\n value: maskConnectionUrl(dbConnection),\n });\n }\n if (toArg) {\n details.push({ label: 'to', value: toArg });\n }\n const header = formatStyledHeader({\n command: 'migrate',\n description: 'Apply planned migrations to advance the database',\n url: 'https://pris.ly/migrate',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n const appGraph = aggregate.app.graph();\n\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\n try {\n await client.connect(dbConnection);\n\n const allMarkers = await client.readAllMarkers();\n const appMarker = allMarkers.get('app') ?? null;\n\n if (appMarker !== null && !isGraphNode(appMarker.storageHash, appGraph)) {\n return notOk(\n errorMarkerMismatch(\n appMarker.storageHash,\n [...appGraph.nodes].sort(),\n findLatestMigration(appGraph)?.to ?? null,\n ),\n );\n }\n\n if (refEntry && refEntry.invariants.length > 0) {\n const declared = collectDeclaredInvariants(appGraph);\n const known = new Set<string>(declared);\n for (const id of appMarker?.invariants ?? []) known.add(id);\n const unknown = refEntry.invariants.filter((id) => !known.has(id));\n if (unknown.length > 0) {\n return notOk(\n mapMigrationToolsError(\n errorUnknownInvariant({\n ...ifDefined('refName', toArg),\n unknown,\n declared: [...declared].sort(),\n }),\n ),\n );\n }\n }\n\n if (!flags.quiet && !flags.json) {\n ui.step('Loading contract spaces…');\n }\n\n // When `--to` resolves to an on-disk graph node with a matching bundle,\n // verify and apply against THAT bundle's destination contract via\n // `contractAt` — not the emitted `contract.json`. With `--to` omitted,\n // or a target with no matching bundle, the emitted contract stays the\n // apply contract (the only migrate-specific default). The same\n // `contractAt` artifacts feed the optional ref-advancement snapshot.\n let applyContract: Contract = contractRaw;\n let snapshotContractJson: Record<string, unknown> = JSON.parse(contractContent);\n let snapshotContractDts: string | undefined;\n if (toArg && refEntry) {\n const targetHash = refEntry.hash;\n const matchingBundle = aggregate.app.packages.find((p) => p.metadata.to === targetHash);\n if (matchingBundle) {\n try {\n const at = await aggregate.app.contractAt(\n targetHash,\n refName !== undefined ? { refName } : undefined,\n );\n applyContract = at.contract;\n snapshotContractJson = at.contractJson as Record<string, unknown>;\n snapshotContractDts = at.contractDts;\n } catch (error) {\n return mapContractAtError(error, { artifactRole: 'to' });\n }\n }\n }\n\n const applyResult = await client.migrationApply({\n contract: applyContract,\n migrationsDir,\n ...ifDefined('refHash', refEntry?.hash),\n ...(refEntry?.invariants ? { refInvariants: refEntry.invariants } : {}),\n ...(refEntry !== undefined ? ifDefined('refName', toArg) : {}),\n });\n\n if (!applyResult.ok) {\n return notOk(mapApplyFailure(applyResult.failure));\n }\n\n const { value } = applyResult;\n\n let advancedRef: { name: string; hash: string } | null = null;\n if (options.advanceRef !== undefined) {\n try {\n const contractIR =\n snapshotContractDts !== undefined\n ? { contract: snapshotContractJson, contractDts: snapshotContractDts }\n : await readContractIR(snapshotContractJson, contractPathAbsolute);\n advancedRef = await executeRefAdvancement(\n refsDir,\n options.advanceRef,\n value.markerHash,\n contractIR,\n );\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n return ok({\n ok: true,\n migrationsApplied: value.migrationsApplied,\n migrationsTotal: value.perSpace.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n perSpace: value.perSpace,\n ...ifDefined('pathDecision', value.pathDecision),\n timings: { total: Date.now() - startTime },\n advancedRef,\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\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: `Unexpected error during migrate: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrateCommand(): Command {\n const command = new Command('migrate');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to advance the database',\n 'Walks every contract space (app + extensions) and applies pending\\n' +\n 'on-disk migrations in canonical order (extensions alphabetically,\\n' +\n 'then app). Graph-walks the on-disk migration graph for every space.\\n' +\n 'Use --to to target a specific contract (hash, ref name, migration dir).',\n );\n setCommandExamples(command, [\n 'prisma-next migrate --db $DATABASE_URL',\n 'prisma-next migrate --to production --db $DATABASE_URL',\n 'prisma-next migrate --to sha256:abc123 --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .option('--advance-ref <name>', 'Advance the named ref to the post-apply marker after success')\n .action(async (options: MigrateCommandOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n const result = await executeMigrateCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (migrateResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(migrateResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationApplyCommandOutput(migrateResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"migrate.mjs","names":[],"sources":["../../src/commands/migrate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { RefEntry } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type {\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n PerSpaceExecutionEntry,\n} from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorMarkerMismatch,\n errorPathUnreachable,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n collectDeclaredInvariants,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { mapContractAtError } from '../utils/contract-at-errors';\nimport {\n loadContractSpaceAggregateForCli,\n refuseContractSpaceIntegrity,\n} from '../utils/contract-space-aggregate-loader';\nimport { toDeclaredExtensionsFromRaw } from '../utils/extension-pack-inputs';\nimport { formatMigrationApplyCommandOutput } 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 { executeRefAdvancement, readContractIR } from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrateCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly to?: string;\n readonly advanceRef?: string;\n}\n\nexport interface MigrateResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName: string;\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n readonly pathDecision?: MigrationApplyPathDecision;\n readonly timings: {\n readonly total: number;\n };\n readonly advancedRef?: { readonly name: string; readonly hash: string } | null;\n}\n\nfunction mapApplyFailure(failure: MigrationApplyFailure): CliStructuredErrorType {\n if (failure.code === 'MIGRATION_PATH_NOT_FOUND') {\n return errorPathUnreachable(failure);\n }\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the issue and re-run `prisma-next migrate --to <contract>` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nasync function executeMigrateCommand(\n options: MigrateCommandOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrateResult, CliStructuredErrorType>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsRelative, refsDir } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migrate (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migrate',\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: 'Config.driver is required for migrate',\n }),\n );\n }\n\n if (!targetSupportsMigrations(config.target)) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n const toArg = options.to;\n\n // Construct the family instance up-front so the on-disk contract read\n // crosses the serializer seam (`familyInstance.deserializeContract`) at\n // the read site. The downstream `client.migrationApply({ contract })`\n // re-validates internally (no harm — validation is idempotent), but\n // closing the gap at the read site is what makes the cast-pattern\n // lint enforceable and matches the other CLI commands. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n const contractPathAbsolute = resolveContractPath(config);\n let contractRaw: Contract;\n let contractContent: string;\n try {\n contractContent = 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 a valid contract.json, then retry.',\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n try {\n contractRaw = familyInstance.deserializeContract(JSON.parse(contractContent) 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 loadedAggregate = await loadContractSpaceAggregateForCli({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: contractRaw,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json) => familyInstance.deserializeContract(json),\n });\n if (!loadedAggregate.ok) {\n return notOk(loadedAggregate.failure);\n }\n const aggregate = loadedAggregate.value;\n const integrityFailure = refuseContractSpaceIntegrity(aggregate, {\n declaredExtensions: toDeclaredExtensionsFromRaw(\n (config.extensionPacks ?? []) as ReadonlyArray<unknown>,\n ),\n checkContracts: true,\n });\n if (integrityFailure) {\n return notOk(integrityFailure);\n }\n\n let refEntry: RefEntry | undefined;\n let refName: string | undefined;\n if (toArg) {\n const refs = aggregate.app.refs;\n const refResult = parseContractRef(toArg, { graph: aggregate.app.graph(), refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n if (refResult.value.provenance.kind === 'ref') {\n refName = refResult.value.provenance.refName;\n const resolved = refs[refName];\n if (resolved) refEntry = resolved;\n } else {\n refEntry = { hash: refResult.value.hash, invariants: [] };\n }\n }\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({\n label: 'database',\n value: maskConnectionUrl(dbConnection),\n });\n }\n if (toArg) {\n details.push({ label: 'to', value: toArg });\n }\n const header = formatStyledHeader({\n command: 'migrate',\n description: 'Apply planned migrations to advance the database',\n url: 'https://pris.ly/migrate',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n const appGraph = aggregate.app.graph();\n\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\n try {\n await client.connect(dbConnection);\n\n const allMarkers = await client.readAllMarkers();\n const appMarker = allMarkers.get('app') ?? null;\n\n if (appMarker !== null && !isGraphNode(appMarker.storageHash, appGraph)) {\n return notOk(\n errorMarkerMismatch(\n appMarker.storageHash,\n [...appGraph.nodes].sort(),\n findLatestMigration(appGraph)?.to ?? null,\n ),\n );\n }\n\n if (refEntry && refEntry.invariants.length > 0) {\n const declared = collectDeclaredInvariants(appGraph);\n const known = new Set<string>(declared);\n for (const id of appMarker?.invariants ?? []) known.add(id);\n const unknown = refEntry.invariants.filter((id) => !known.has(id));\n if (unknown.length > 0) {\n return notOk(\n mapMigrationToolsError(\n errorUnknownInvariant({\n ...ifDefined('refName', toArg),\n unknown,\n declared: [...declared].sort(),\n }),\n ),\n );\n }\n }\n\n if (!flags.quiet && !flags.json) {\n ui.step('Loading contract spaces…');\n }\n\n // When `--to` resolves to an on-disk graph node with a matching bundle,\n // verify and apply against THAT bundle's destination contract via\n // `contractAt` — not the emitted `contract.json`. With `--to` omitted,\n // or a target with no matching bundle, the emitted contract stays the\n // apply contract (the only migrate-specific default). The same\n // `contractAt` artifacts feed the optional ref-advancement snapshot.\n let applyContract: Contract = contractRaw;\n let snapshotContractJson: Record<string, unknown> = JSON.parse(contractContent);\n let snapshotContractDts: string | undefined;\n if (toArg && refEntry) {\n const targetHash = refEntry.hash;\n const matchingBundle = aggregate.app.packages.find((p) => p.metadata.to === targetHash);\n if (matchingBundle) {\n try {\n const at = await aggregate.app.contractAt(\n targetHash,\n refName !== undefined ? { refName } : undefined,\n );\n applyContract = at.contract;\n snapshotContractJson = at.contractJson as Record<string, unknown>;\n snapshotContractDts = at.contractDts;\n } catch (error) {\n return mapContractAtError(error, { artifactRole: 'to' });\n }\n }\n }\n\n const applyResult = await client.migrationApply({\n contract: applyContract,\n migrationsDir,\n ...ifDefined('refHash', refEntry?.hash),\n ...(refEntry?.invariants ? { refInvariants: refEntry.invariants } : {}),\n ...(refEntry !== undefined ? ifDefined('refName', toArg) : {}),\n });\n\n if (!applyResult.ok) {\n return notOk(mapApplyFailure(applyResult.failure));\n }\n\n const { value } = applyResult;\n\n let advancedRef: { name: string; hash: string } | null = null;\n if (options.advanceRef !== undefined) {\n try {\n const contractIR =\n snapshotContractDts !== undefined\n ? { contract: snapshotContractJson, contractDts: snapshotContractDts }\n : await readContractIR(snapshotContractJson, contractPathAbsolute);\n advancedRef = await executeRefAdvancement(\n refsDir,\n options.advanceRef,\n value.markerHash,\n contractIR,\n );\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n return ok({\n ok: true,\n migrationsApplied: value.migrationsApplied,\n migrationsTotal: value.perSpace.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n perSpace: value.perSpace,\n ...ifDefined('pathDecision', value.pathDecision),\n timings: { total: Date.now() - startTime },\n advancedRef,\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\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: `Unexpected error during migrate: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrateCommand(): Command {\n const command = new Command('migrate');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to advance the database',\n 'Walks every contract space (app + extensions) and applies pending\\n' +\n 'on-disk migrations in canonical order (extensions alphabetically,\\n' +\n 'then app). Graph-walks the on-disk migration graph for every space.\\n' +\n 'Use --to to target a specific contract (hash, ref name, migration dir).',\n );\n setCommandExamples(command, [\n 'prisma-next migrate --db $DATABASE_URL',\n 'prisma-next migrate --to production --db $DATABASE_URL',\n 'prisma-next migrate --to sha256:abc123 --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .option('--advance-ref <name>', 'Advance the named ref to the post-apply marker after success')\n .action(async (options: MigrateCommandOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n const result = await executeMigrateCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (migrateResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(migrateResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationApplyCommandOutput(migrateResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { t as createMigrationCheckCommand } from "../migration-check-BiBJoYYW.mjs";
1
+ import { t as createMigrationCheckCommand } from "../migration-check-Dc0cOhKH.mjs";
2
2
  export { createMigrationCheckCommand };
@@ -1,6 +1,5 @@
1
- import { N as CliStructuredError } from "../types-Dt_SfqFm.mjs";
2
- import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DEHjV8_s.mjs";
3
- import { n as StatusRef } from "../migration-types-D2FW63pr.mjs";
1
+ import { N as CliStructuredError } from "../types-Mh7mdPHM.mjs";
2
+ import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DG4uY5tV.mjs";
4
3
  import { t as TerminalUI } from "../terminal-ui-5Y6mrg93.mjs";
5
4
  import { Command } from "commander";
6
5
  import { Result } from "@prisma-next/utils/result";
@@ -10,18 +9,25 @@ import { MigrationGraph } from "@prisma-next/migration-tools/graph";
10
9
  interface MigrationGraphOptions extends CommonCommandOptions {
11
10
  readonly config?: string;
12
11
  readonly dot?: boolean;
13
- readonly tree?: boolean;
12
+ readonly space?: string;
14
13
  readonly ascii?: boolean;
14
+ readonly legend?: boolean;
15
+ }
16
+ interface MigrationGraphTreeSection {
17
+ readonly spaceId: string;
18
+ readonly tree: string;
19
+ readonly showHeading: boolean;
15
20
  }
16
21
  interface MigrationGraphResult {
17
22
  readonly ok: true;
23
+ /** App-space graph for `--json` / `--dot` (unchanged machine output). */
18
24
  readonly graph: MigrationGraph;
19
- readonly contractHash: string | null;
20
- readonly refs: readonly StatusRef[];
25
+ readonly treeSections: readonly MigrationGraphTreeSection[];
21
26
  readonly summary: string;
22
27
  }
28
+ declare function formatMigrationGraphHumanOutput(result: MigrationGraphResult): string;
23
29
  declare function executeMigrationGraphCommand(options: MigrationGraphOptions, flags: GlobalFlags, ui: TerminalUI): Promise<Result<MigrationGraphResult, CliStructuredError>>;
24
30
  declare function createMigrationGraphCommand(): Command;
25
31
  //#endregion
26
- export { MigrationGraphResult, createMigrationGraphCommand, executeMigrationGraphCommand };
32
+ export { MigrationGraphResult, MigrationGraphTreeSection, createMigrationGraphCommand, executeMigrationGraphCommand, formatMigrationGraphHumanOutput };
27
33
  //# sourceMappingURL=migration-graph.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration-graph.d.mts","names":[],"sources":["../../src/commands/migration-graph.ts"],"mappings":";;;;;;;;;UA0BU,qBAAA,SAA8B,oBAAoB;EAAA,SACjD,MAAA;EAAA,SACA,GAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;AAAA,UAGM,oBAAA;EAAA,SACN,EAAA;EAAA,SACA,KAAA,EAAO,cAAA;EAAA,SACP,YAAA;EAAA,SACA,IAAA,WAAe,SAAS;EAAA,SACxB,OAAA;AAAA;AAAA,iBAGW,4BAAA,CACpB,OAAA,EAAS,qBAAA,EACT,KAAA,EAAO,WAAA,EACP,EAAA,EAAI,UAAA,GACH,OAAA,CAAQ,MAAA,CAAO,oBAAA,EAAsB,kBAAA;AAAA,iBA0CxB,2BAAA,CAAA,GAA+B,OAAO"}
1
+ {"version":3,"file":"migration-graph.d.mts","names":[],"sources":["../../src/commands/migration-graph.ts"],"mappings":";;;;;;;;UAiCU,qBAAA,SAA8B,oBAAoB;EAAA,SACjD,MAAA;EAAA,SACA,GAAA;EAAA,SACA,KAAA;EAAA,SACA,KAAA;EAAA,SACA,MAAA;AAAA;AAAA,UAGM,yBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,WAAA;AAAA;AAAA,UAGM,oBAAA;EAAA,SACN,EAAA;EAP+B;EAAA,SAS/B,KAAA,EAAO,cAAA;EAAA,SACP,YAAA,WAAuB,yBAAyB;EAAA,SAChD,OAAA;AAAA;AAAA,iBAOK,+BAAA,CAAgC,MAA4B,EAApB,oBAAoB;AAAA,iBAiBtD,4BAAA,CACpB,OAAA,EAAS,qBAAA,EACT,KAAA,EAAO,WAAA,EACP,EAAA,EAAI,UAAA,GACH,OAAA,CAAQ,MAAA,CAAO,oBAAA,EAAsB,kBAAA;AAAA,iBAwGxB,2BAAA,CAAA,GAA+B,OAAO"}
@@ -1,2 +1,171 @@
1
- import { n as executeMigrationGraphCommand, t as createMigrationGraphCommand } from "../migration-graph-D7DVUElV.mjs";
2
- export { createMigrationGraphCommand, executeMigrationGraphCommand };
1
+ import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
2
+ import { A as formatStyledHeader, _ as createTerminalUI, d as setCommandSeeAlso, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, s as resolveMigrationPaths, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "../command-helpers-DK_5ItoJ.mjs";
3
+ import { n as buildReadAggregate } from "../contract-space-aggregate-loader-Dbr3-jHF.mjs";
4
+ import { a as renderMigrationGraphLegend, i as renderMigrationGraphSpaceTree, n as computeGlobalMaxEdgeTreePrefixWidth, r as indentMigrationGraphTreeBlock, t as computeGlobalMaxDirNameWidth } from "../migration-graph-space-render-dmLLWift.mjs";
5
+ import { c as validateLegendOptions, i as migrationSpaceListEntriesFromAggregate, o as runMigrationList, r as listRefsByContractHash, s as shouldShowLegend } from "../migration-list-C5sXrl0U.mjs";
6
+ import { Command } from "commander";
7
+ import { ifDefined } from "@prisma-next/utils/defined";
8
+ import { ok } from "@prisma-next/utils/result";
9
+ //#region src/commands/migration-graph.ts
10
+ function computeGraphSummary(graph) {
11
+ return `${graph.nodes.size} node(s), ${graph.migrationByHash.size} edge(s)`;
12
+ }
13
+ function formatMigrationGraphHumanOutput(result) {
14
+ const sections = [];
15
+ for (const section of result.treeSections) {
16
+ if (section.showHeading) sections.push(`${section.spaceId}:`);
17
+ if (section.tree.length > 0) sections.push(section.tree);
18
+ else sections.push("(no migrations)");
19
+ sections.push("");
20
+ }
21
+ sections.push(result.summary);
22
+ return sections.join("\n").trimEnd();
23
+ }
24
+ async function executeMigrationGraphCommand(options, flags, ui) {
25
+ const config = await loadConfig(options.config);
26
+ const { configPath, migrationsRelative, migrationsDir } = resolveMigrationPaths(options.config, config);
27
+ if (!flags.json && !flags.quiet) {
28
+ const header = formatStyledHeader({
29
+ command: "migration graph",
30
+ description: "Show the migration graph topology",
31
+ details: [
32
+ {
33
+ label: "config",
34
+ value: configPath
35
+ },
36
+ {
37
+ label: "migrations",
38
+ value: migrationsRelative
39
+ },
40
+ ...options.space !== void 0 ? [{
41
+ label: "space",
42
+ value: options.space
43
+ }] : []
44
+ ],
45
+ flags
46
+ });
47
+ ui.stderr(header);
48
+ if (shouldShowLegend(options, flags)) {
49
+ ui.stderr(renderMigrationGraphLegend({
50
+ colorize: flags.color !== false,
51
+ glyphMode: ui.resolveGlyphMode(options.ascii === true)
52
+ }));
53
+ ui.stderr("");
54
+ }
55
+ }
56
+ const loaded = await buildReadAggregate(config, { migrationsDir });
57
+ if (!loaded.ok) return loaded;
58
+ const { aggregate, contractHash: liveContractHash } = loaded.value;
59
+ const appGraph = aggregate.app.graph();
60
+ const listResult = runMigrationList({
61
+ spaces: await migrationSpaceListEntriesFromAggregate(aggregate, migrationsDir),
62
+ ...ifDefined("spaceFilter", options.space)
63
+ });
64
+ if (!listResult.ok) return listResult;
65
+ const scopedSpaces = listResult.value.spaces;
66
+ const showSpaceHeadings = scopedSpaces.length > 1;
67
+ const glyphMode = ui.resolveGlyphMode(options.ascii === true);
68
+ const colorize = flags.color !== false;
69
+ const globalLayoutInputs = showSpaceHeadings ? scopedSpaces.filter((spaceEntry) => spaceEntry.migrations.length > 0).map((spaceEntry) => ({
70
+ graph: aggregate.space(spaceEntry.spaceId).graph(),
71
+ liveContractHash
72
+ })) : [];
73
+ const globalMaxEdgeTreePrefixWidth = globalLayoutInputs.length > 0 ? computeGlobalMaxEdgeTreePrefixWidth(globalLayoutInputs) : void 0;
74
+ const globalMaxDirNameWidth = globalLayoutInputs.length > 0 ? computeGlobalMaxDirNameWidth(globalLayoutInputs) : void 0;
75
+ const treeSections = [];
76
+ for (const spaceEntry of scopedSpaces) {
77
+ const member = aggregate.space(spaceEntry.spaceId);
78
+ if (member === void 0) continue;
79
+ const graph = member.graph();
80
+ const tree = spaceEntry.migrations.length === 0 ? "" : renderMigrationGraphSpaceTree({
81
+ graph,
82
+ migrations: spaceEntry.migrations,
83
+ liveContractHash,
84
+ glyphMode,
85
+ colorize,
86
+ refsByHash: listRefsByContractHash(member),
87
+ ...globalMaxEdgeTreePrefixWidth !== void 0 ? { globalMaxEdgeTreePrefixWidth } : {},
88
+ ...globalMaxDirNameWidth !== void 0 ? { globalMaxDirNameWidth } : {}
89
+ });
90
+ const displayTree = showSpaceHeadings && tree.length > 0 ? indentMigrationGraphTreeBlock(tree, " ") : tree;
91
+ treeSections.push({
92
+ spaceId: spaceEntry.spaceId,
93
+ tree: displayTree,
94
+ showHeading: showSpaceHeadings
95
+ });
96
+ }
97
+ return ok({
98
+ ok: true,
99
+ graph: appGraph,
100
+ treeSections,
101
+ summary: computeGraphSummary(appGraph)
102
+ });
103
+ }
104
+ function createMigrationGraphCommand() {
105
+ const command = new Command("graph");
106
+ setCommandDescriptions(command, "Show the migration graph topology", "Renders the migration graph topology. Offline — does not consult\nthe database. --ascii swaps box-drawing for pipe-friendly ASCII glyphs.\nUse --json for machine-readable output, or --dot for Graphviz DOT\nformat.");
107
+ setCommandExamples(command, [
108
+ "prisma-next migration graph",
109
+ "prisma-next migration graph --json",
110
+ "prisma-next migration graph --dot",
111
+ "prisma-next migration graph --ascii",
112
+ "prisma-next migration graph --legend",
113
+ "prisma-next migration graph --space app"
114
+ ]);
115
+ setCommandSeeAlso(command, [
116
+ {
117
+ verb: "migration status",
118
+ oneLiner: "Show migration path and pending status"
119
+ },
120
+ {
121
+ verb: "migration log",
122
+ oneLiner: "Show executed migration history"
123
+ },
124
+ {
125
+ verb: "migration list",
126
+ oneLiner: "List on-disk migrations"
127
+ },
128
+ {
129
+ verb: "migration show",
130
+ oneLiner: "Display migration package contents"
131
+ }
132
+ ]);
133
+ addGlobalOptions(command).option("--config <path>", "Path to prisma-next.config.ts").option("--space <id>", "Narrow output to a single contract space").option("--dot", "Output in Graphviz DOT format").option("--ascii", "Use ASCII glyphs (pipe-friendly)").option("--legend", "Print a key for the tree glyphs and lane colors").action(async (options) => {
134
+ const flags = parseGlobalFlagsOrExit(options);
135
+ const ui = createTerminalUI(flags);
136
+ const legendValidation = validateLegendOptions(options, flags);
137
+ if (!legendValidation.ok) process.exit(handleResult(legendValidation, flags, ui));
138
+ const exitCode = handleResult(await executeMigrationGraphCommand(options, flags, ui), flags, ui, (graphResult) => {
139
+ if (options.dot) {
140
+ const lines = ["digraph migrations {"];
141
+ for (const edge of graphResult.graph.migrationByHash.values()) {
142
+ const from = edge.from.slice(0, 12);
143
+ const to = edge.to.slice(0, 12);
144
+ lines.push(` "${from}" -> "${to}" [label="${edge.dirName}"];`);
145
+ }
146
+ lines.push("}");
147
+ ui.output(lines.join("\n"));
148
+ } else if (flags.json) {
149
+ const nodes = [...graphResult.graph.nodes];
150
+ const edges = [...graphResult.graph.migrationByHash.values()].map((e) => ({
151
+ dirName: e.dirName,
152
+ from: e.from,
153
+ to: e.to,
154
+ migrationHash: e.migrationHash
155
+ }));
156
+ ui.output(JSON.stringify({
157
+ ok: true,
158
+ nodes,
159
+ edges,
160
+ summary: `${graphResult.graph.nodes.size} node(s), ${graphResult.graph.migrationByHash.size} edge(s)`
161
+ }, null, 2));
162
+ } else if (!flags.quiet) ui.output(formatMigrationGraphHumanOutput(graphResult));
163
+ });
164
+ process.exit(exitCode);
165
+ });
166
+ return command;
167
+ }
168
+ //#endregion
169
+ export { createMigrationGraphCommand, executeMigrationGraphCommand, formatMigrationGraphHumanOutput };
170
+
171
+ //# sourceMappingURL=migration-graph.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-graph.mjs","names":[],"sources":["../../src/commands/migration-graph.ts"],"sourcesContent":["import type { MigrationGraph } from '@prisma-next/migration-tools/graph';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport type { CliStructuredError } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n} from '../utils/command-helpers';\nimport { buildReadAggregate } from '../utils/contract-space-aggregate-loader';\nimport {\n computeGlobalMaxDirNameWidth,\n computeGlobalMaxEdgeTreePrefixWidth,\n indentMigrationGraphTreeBlock,\n renderMigrationGraphSpaceTree,\n} from '../utils/formatters/migration-graph-space-render';\nimport { renderMigrationGraphLegend } from '../utils/formatters/migration-graph-tree-render';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { shouldShowLegend, validateLegendOptions } from '../utils/legend';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\nimport {\n listRefsByContractHash,\n migrationSpaceListEntriesFromAggregate,\n runMigrationList,\n} from './migration-list';\n\ninterface MigrationGraphOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly dot?: boolean;\n readonly space?: string;\n readonly ascii?: boolean;\n readonly legend?: boolean;\n}\n\nexport interface MigrationGraphTreeSection {\n readonly spaceId: string;\n readonly tree: string;\n readonly showHeading: boolean;\n}\n\nexport interface MigrationGraphResult {\n readonly ok: true;\n /** App-space graph for `--json` / `--dot` (unchanged machine output). */\n readonly graph: MigrationGraph;\n readonly treeSections: readonly MigrationGraphTreeSection[];\n readonly summary: string;\n}\n\nfunction computeGraphSummary(graph: MigrationGraph): string {\n return `${graph.nodes.size} node(s), ${graph.migrationByHash.size} edge(s)`;\n}\n\nexport function formatMigrationGraphHumanOutput(result: MigrationGraphResult): string {\n const sections: string[] = [];\n for (const section of result.treeSections) {\n if (section.showHeading) {\n sections.push(`${section.spaceId}:`);\n }\n if (section.tree.length > 0) {\n sections.push(section.tree);\n } else {\n sections.push('(no migrations)');\n }\n sections.push('');\n }\n sections.push(result.summary);\n return sections.join('\\n').trimEnd();\n}\n\nexport async function executeMigrationGraphCommand(\n options: MigrationGraphOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationGraphResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsRelative, migrationsDir } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n if (!flags.json && !flags.quiet) {\n const header = formatStyledHeader({\n command: 'migration graph',\n description: 'Show the migration graph topology',\n details: [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ...(options.space !== undefined ? [{ label: 'space', value: options.space }] : []),\n ],\n flags,\n });\n ui.stderr(header);\n if (shouldShowLegend(options, flags)) {\n ui.stderr(\n renderMigrationGraphLegend({\n colorize: flags.color !== false,\n glyphMode: ui.resolveGlyphMode(options.ascii === true),\n }),\n );\n ui.stderr('');\n }\n }\n\n const loaded = await buildReadAggregate(config, { migrationsDir });\n if (!loaded.ok) {\n return loaded;\n }\n\n const { aggregate, contractHash: liveContractHash } = loaded.value;\n const appGraph = aggregate.app.graph();\n\n const listSpaces = await migrationSpaceListEntriesFromAggregate(aggregate, migrationsDir);\n const listResult = runMigrationList({\n spaces: listSpaces,\n ...ifDefined('spaceFilter', options.space),\n });\n if (!listResult.ok) {\n return listResult;\n }\n\n const scopedSpaces = listResult.value.spaces;\n const showSpaceHeadings = scopedSpaces.length > 1;\n const glyphMode = ui.resolveGlyphMode(options.ascii === true);\n const colorize = flags.color !== false;\n\n const globalLayoutInputs = showSpaceHeadings\n ? scopedSpaces\n .filter((spaceEntry) => spaceEntry.migrations.length > 0)\n .map((spaceEntry) => ({\n graph: aggregate.space(spaceEntry.spaceId)!.graph(),\n liveContractHash,\n }))\n : [];\n const globalMaxEdgeTreePrefixWidth =\n globalLayoutInputs.length > 0\n ? computeGlobalMaxEdgeTreePrefixWidth(globalLayoutInputs)\n : undefined;\n const globalMaxDirNameWidth =\n globalLayoutInputs.length > 0 ? computeGlobalMaxDirNameWidth(globalLayoutInputs) : undefined;\n\n const treeSections: MigrationGraphTreeSection[] = [];\n for (const spaceEntry of scopedSpaces) {\n const member = aggregate.space(spaceEntry.spaceId);\n if (member === undefined) {\n continue;\n }\n const graph = member.graph();\n const tree =\n spaceEntry.migrations.length === 0\n ? ''\n : renderMigrationGraphSpaceTree({\n graph,\n migrations: spaceEntry.migrations,\n liveContractHash,\n glyphMode,\n colorize,\n refsByHash: listRefsByContractHash(member),\n ...(globalMaxEdgeTreePrefixWidth !== undefined ? { globalMaxEdgeTreePrefixWidth } : {}),\n ...(globalMaxDirNameWidth !== undefined ? { globalMaxDirNameWidth } : {}),\n });\n const displayTree =\n showSpaceHeadings && tree.length > 0 ? indentMigrationGraphTreeBlock(tree, ' ') : tree;\n treeSections.push({\n spaceId: spaceEntry.spaceId,\n tree: displayTree,\n showHeading: showSpaceHeadings,\n });\n }\n\n return ok({\n ok: true,\n graph: appGraph,\n treeSections,\n summary: computeGraphSummary(appGraph),\n });\n}\n\nexport function createMigrationGraphCommand(): Command {\n const command = new Command('graph');\n setCommandDescriptions(\n command,\n 'Show the migration graph topology',\n 'Renders the migration graph topology. Offline — does not consult\\n' +\n 'the database. --ascii swaps box-drawing for pipe-friendly ASCII glyphs.\\n' +\n 'Use --json for machine-readable output, or --dot for Graphviz DOT\\n' +\n 'format.',\n );\n setCommandExamples(command, [\n 'prisma-next migration graph',\n 'prisma-next migration graph --json',\n 'prisma-next migration graph --dot',\n 'prisma-next migration graph --ascii',\n 'prisma-next migration graph --legend',\n 'prisma-next migration graph --space app',\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 show', oneLiner: 'Display migration package contents' },\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--space <id>', 'Narrow output to a single contract space')\n .option('--dot', 'Output in Graphviz DOT format')\n .option('--ascii', 'Use ASCII glyphs (pipe-friendly)')\n .option('--legend', 'Print a key for the tree glyphs and lane colors')\n .action(async (options: MigrationGraphOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n const legendValidation = validateLegendOptions(options, flags);\n if (!legendValidation.ok) {\n process.exit(handleResult(legendValidation, flags, ui));\n }\n const result = await executeMigrationGraphCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (graphResult) => {\n if (options.dot) {\n const lines = ['digraph migrations {'];\n for (const edge of graphResult.graph.migrationByHash.values()) {\n const from = edge.from.slice(0, 12);\n const to = edge.to.slice(0, 12);\n lines.push(` \"${from}\" -> \"${to}\" [label=\"${edge.dirName}\"];`);\n }\n lines.push('}');\n ui.output(lines.join('\\n'));\n } else if (flags.json) {\n const nodes = [...graphResult.graph.nodes];\n const edges = [...graphResult.graph.migrationByHash.values()].map((e) => ({\n dirName: e.dirName,\n from: e.from,\n to: e.to,\n migrationHash: e.migrationHash,\n }));\n ui.output(\n JSON.stringify(\n {\n ok: true,\n nodes,\n edges,\n summary: `${graphResult.graph.nodes.size} node(s), ${graphResult.graph.migrationByHash.size} edge(s)`,\n },\n null,\n 2,\n ),\n );\n } else if (!flags.quiet) {\n ui.output(formatMigrationGraphHumanOutput(graphResult));\n }\n });\n process.exit(exitCode);\n });\n return command;\n}\n"],"mappings":";;;;;;;;;AAuDA,SAAS,oBAAoB,OAA+B;CAC1D,OAAO,GAAG,MAAM,MAAM,KAAK,YAAY,MAAM,gBAAgB,KAAK;AACpE;AAEA,SAAgB,gCAAgC,QAAsC;CACpF,MAAM,WAAqB,CAAC;CAC5B,KAAK,MAAM,WAAW,OAAO,cAAc;EACzC,IAAI,QAAQ,aACV,SAAS,KAAK,GAAG,QAAQ,QAAQ,EAAE;EAErC,IAAI,QAAQ,KAAK,SAAS,GACxB,SAAS,KAAK,QAAQ,IAAI;OAE1B,SAAS,KAAK,iBAAiB;EAEjC,SAAS,KAAK,EAAE;CAClB;CACA,SAAS,KAAK,OAAO,OAAO;CAC5B,OAAO,SAAS,KAAK,IAAI,EAAE,QAAQ;AACrC;AAEA,eAAsB,6BACpB,SACA,OACA,IAC2D;CAC3D,MAAM,SAAS,MAAM,WAAW,QAAQ,MAAM;CAC9C,MAAM,EAAE,YAAY,oBAAoB,kBAAkB,sBACxD,QAAQ,QACR,MACF;CAEA,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OAAO;EAC/B,MAAM,SAAS,mBAAmB;GAChC,SAAS;GACT,aAAa;GACb,SAAS;IACP;KAAE,OAAO;KAAU,OAAO;IAAW;IACrC;KAAE,OAAO;KAAc,OAAO;IAAmB;IACjD,GAAI,QAAQ,UAAU,KAAA,IAAY,CAAC;KAAE,OAAO;KAAS,OAAO,QAAQ;IAAM,CAAC,IAAI,CAAC;GAClF;GACA;EACF,CAAC;EACD,GAAG,OAAO,MAAM;EAChB,IAAI,iBAAiB,SAAS,KAAK,GAAG;GACpC,GAAG,OACD,2BAA2B;IACzB,UAAU,MAAM,UAAU;IAC1B,WAAW,GAAG,iBAAiB,QAAQ,UAAU,IAAI;GACvD,CAAC,CACH;GACA,GAAG,OAAO,EAAE;EACd;CACF;CAEA,MAAM,SAAS,MAAM,mBAAmB,QAAQ,EAAE,cAAc,CAAC;CACjE,IAAI,CAAC,OAAO,IACV,OAAO;CAGT,MAAM,EAAE,WAAW,cAAc,qBAAqB,OAAO;CAC7D,MAAM,WAAW,UAAU,IAAI,MAAM;CAGrC,MAAM,aAAa,iBAAiB;EAClC,QAAQ,MAFe,uCAAuC,WAAW,aAAa;EAGtF,GAAG,UAAU,eAAe,QAAQ,KAAK;CAC3C,CAAC;CACD,IAAI,CAAC,WAAW,IACd,OAAO;CAGT,MAAM,eAAe,WAAW,MAAM;CACtC,MAAM,oBAAoB,aAAa,SAAS;CAChD,MAAM,YAAY,GAAG,iBAAiB,QAAQ,UAAU,IAAI;CAC5D,MAAM,WAAW,MAAM,UAAU;CAEjC,MAAM,qBAAqB,oBACvB,aACG,QAAQ,eAAe,WAAW,WAAW,SAAS,CAAC,EACvD,KAAK,gBAAgB;EACpB,OAAO,UAAU,MAAM,WAAW,OAAO,EAAG,MAAM;EAClD;CACF,EAAE,IACJ,CAAC;CACL,MAAM,+BACJ,mBAAmB,SAAS,IACxB,oCAAoC,kBAAkB,IACtD,KAAA;CACN,MAAM,wBACJ,mBAAmB,SAAS,IAAI,6BAA6B,kBAAkB,IAAI,KAAA;CAErF,MAAM,eAA4C,CAAC;CACnD,KAAK,MAAM,cAAc,cAAc;EACrC,MAAM,SAAS,UAAU,MAAM,WAAW,OAAO;EACjD,IAAI,WAAW,KAAA,GACb;EAEF,MAAM,QAAQ,OAAO,MAAM;EAC3B,MAAM,OACJ,WAAW,WAAW,WAAW,IAC7B,KACA,8BAA8B;GAC5B;GACA,YAAY,WAAW;GACvB;GACA;GACA;GACA,YAAY,uBAAuB,MAAM;GACzC,GAAI,iCAAiC,KAAA,IAAY,EAAE,6BAA6B,IAAI,CAAC;GACrF,GAAI,0BAA0B,KAAA,IAAY,EAAE,sBAAsB,IAAI,CAAC;EACzE,CAAC;EACP,MAAM,cACJ,qBAAqB,KAAK,SAAS,IAAI,8BAA8B,MAAM,IAAI,IAAI;EACrF,aAAa,KAAK;GAChB,SAAS,WAAW;GACpB,MAAM;GACN,aAAa;EACf,CAAC;CACH;CAEA,OAAO,GAAG;EACR,IAAI;EACJ,OAAO;EACP;EACA,SAAS,oBAAoB,QAAQ;CACvC,CAAC;AACH;AAEA,SAAgB,8BAAuC;CACrD,MAAM,UAAU,IAAI,QAAQ,OAAO;CACnC,uBACE,SACA,qCACA,uNAIF;CACA,mBAAmB,SAAS;EAC1B;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,kBAAkB,SAAS;EACzB;GAAE,MAAM;GAAoB,UAAU;EAAyC;EAC/E;GAAE,MAAM;GAAiB,UAAU;EAAkC;EACrE;GAAE,MAAM;GAAkB,UAAU;EAA0B;EAC9D;GAAE,MAAM;GAAkB,UAAU;EAAqC;CAC3E,CAAC;CACD,iBAAiB,OAAO,EACrB,OAAO,mBAAmB,+BAA+B,EACzD,OAAO,gBAAgB,0CAA0C,EACjE,OAAO,SAAS,+BAA+B,EAC/C,OAAO,WAAW,kCAAkC,EACpD,OAAO,YAAY,iDAAiD,EACpE,OAAO,OAAO,YAAmC;EAChD,MAAM,QAAQ,uBAAuB,OAAO;EAC5C,MAAM,KAAK,iBAAiB,KAAK;EACjC,MAAM,mBAAmB,sBAAsB,SAAS,KAAK;EAC7D,IAAI,CAAC,iBAAiB,IACpB,QAAQ,KAAK,aAAa,kBAAkB,OAAO,EAAE,CAAC;EAGxD,MAAM,WAAW,aAAa,MADT,6BAA6B,SAAS,OAAO,EAAE,GAC9B,OAAO,KAAK,gBAAgB;GAChE,IAAI,QAAQ,KAAK;IACf,MAAM,QAAQ,CAAC,sBAAsB;IACrC,KAAK,MAAM,QAAQ,YAAY,MAAM,gBAAgB,OAAO,GAAG;KAC7D,MAAM,OAAO,KAAK,KAAK,MAAM,GAAG,EAAE;KAClC,MAAM,KAAK,KAAK,GAAG,MAAM,GAAG,EAAE;KAC9B,MAAM,KAAK,MAAM,KAAK,QAAQ,GAAG,YAAY,KAAK,QAAQ,IAAI;IAChE;IACA,MAAM,KAAK,GAAG;IACd,GAAG,OAAO,MAAM,KAAK,IAAI,CAAC;GAC5B,OAAO,IAAI,MAAM,MAAM;IACrB,MAAM,QAAQ,CAAC,GAAG,YAAY,MAAM,KAAK;IACzC,MAAM,QAAQ,CAAC,GAAG,YAAY,MAAM,gBAAgB,OAAO,CAAC,EAAE,KAAK,OAAO;KACxE,SAAS,EAAE;KACX,MAAM,EAAE;KACR,IAAI,EAAE;KACN,eAAe,EAAE;IACnB,EAAE;IACF,GAAG,OACD,KAAK,UACH;KACE,IAAI;KACJ;KACA;KACA,SAAS,GAAG,YAAY,MAAM,MAAM,KAAK,YAAY,YAAY,MAAM,gBAAgB,KAAK;IAC9F,GACA,MACA,CACF,CACF;GACF,OAAO,IAAI,CAAC,MAAM,OAChB,GAAG,OAAO,gCAAgC,WAAW,CAAC;EAE1D,CAAC;EACD,QAAQ,KAAK,QAAQ;CACvB,CAAC;CACH,OAAO;AACT"}
@@ -1,32 +1,22 @@
1
- import { N as CliStructuredError } from "../types-Dt_SfqFm.mjs";
2
- import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DEHjV8_s.mjs";
1
+ import { N as CliStructuredError } from "../types-Mh7mdPHM.mjs";
2
+ import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DG4uY5tV.mjs";
3
3
  import { n as GlyphMode, t as TerminalUI } from "../terminal-ui-5Y6mrg93.mjs";
4
+ import { n as MigrationListResult, r as MigrationSpaceListEntry } from "../migration-list-types-DS63IdFd.mjs";
4
5
  import { Command } from "commander";
5
6
  import { Result } from "@prisma-next/utils/result";
6
- import { ContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
7
+ import { ContractSpaceAggregate, ContractSpaceMember } from "@prisma-next/migration-tools/aggregate";
8
+ import { MigrationGraph } from "@prisma-next/migration-tools/graph";
7
9
 
8
- //#region src/utils/formatters/migration-list-types.d.ts
9
- interface MigrationListEntry {
10
- readonly dirName: string;
11
- readonly from: string | null;
12
- readonly to: string;
13
- readonly migrationHash: string;
14
- readonly operationCount: number;
15
- readonly createdAt: string;
16
- readonly refs: readonly string[];
17
- readonly providedInvariants: readonly string[];
18
- }
19
- interface MigrationSpaceListEntry {
20
- readonly spaceId: string;
21
- readonly migrations: readonly MigrationListEntry[];
22
- }
23
- interface MigrationListResult {
24
- readonly ok: true;
25
- readonly spaces: readonly MigrationSpaceListEntry[];
26
- readonly summary: string;
27
- }
28
- //#endregion
29
10
  //#region src/commands/migration-list.d.ts
11
+ /**
12
+ * Ref names decorating a space's destination contract hashes. The
13
+ * tolerant `member.refs` deliberately omits the structural `head.json`;
14
+ * for extension spaces the old enumerator surfaced it as a `head`
15
+ * decoration on the tip migration, so fold `member.headRef` back in to
16
+ * keep that output. The app space synthesises its head, so it carries
17
+ * no on-disk `head` ref to restore.
18
+ */
19
+ declare function listRefsByContractHash(member: ContractSpaceMember): ReadonlyMap<string, readonly string[]>;
30
20
  /**
31
21
  * Project the loaded {@link ContractSpaceAggregate} into the render-ready
32
22
  * {@link MigrationSpaceListEntry} rows `migration list` displays.
@@ -40,10 +30,18 @@ interface MigrationListOptions extends CommonCommandOptions {
40
30
  readonly config?: string;
41
31
  readonly space?: string;
42
32
  readonly ascii?: boolean;
33
+ readonly legend?: boolean;
34
+ }
35
+ interface MigrationListExecuteResult {
36
+ readonly list: MigrationListResult;
37
+ readonly liveContractHash: string;
38
+ readonly aggregate: ContractSpaceAggregate;
43
39
  }
44
40
  interface MigrationListHumanRenderOptions {
45
41
  readonly glyphMode: GlyphMode;
46
42
  readonly useColor: boolean;
43
+ readonly liveContractHash: string;
44
+ readonly graphForSpace: (spaceId: string) => MigrationGraph | undefined;
47
45
  }
48
46
  declare function renderMigrationListHumanOutput(result: MigrationListResult, options: MigrationListHumanRenderOptions): string;
49
47
  /**
@@ -73,8 +71,8 @@ declare function runMigrationList(inputs: RunMigrationListInputs): Result<Migrat
73
71
  * stderr (interactive mode only), and delegates to {@link runMigrationList}.
74
72
  * Kept intentionally thin so the unit-testable surface lives in the core.
75
73
  */
76
- declare function executeMigrationListCommand(options: MigrationListOptions, flags: GlobalFlags, ui: TerminalUI): Promise<Result<MigrationListResult, CliStructuredError>>;
74
+ declare function executeMigrationListCommand(options: MigrationListOptions, flags: GlobalFlags, ui: TerminalUI): Promise<Result<MigrationListExecuteResult, CliStructuredError>>;
77
75
  declare function createMigrationListCommand(): Command;
78
76
  //#endregion
79
- export { MigrationListHumanRenderOptions, RunMigrationListInputs, createMigrationListCommand, executeMigrationListCommand, migrationSpaceListEntriesFromAggregate, renderMigrationListHumanOutput, runMigrationList };
77
+ export { MigrationListExecuteResult, MigrationListHumanRenderOptions, RunMigrationListInputs, createMigrationListCommand, executeMigrationListCommand, listRefsByContractHash, migrationSpaceListEntriesFromAggregate, renderMigrationListHumanOutput, runMigrationList };
80
78
  //# sourceMappingURL=migration-list.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration-list.d.mts","names":[],"sources":["../../src/utils/formatters/migration-list-types.ts","../../src/commands/migration-list.ts"],"mappings":";;;;;;;;UAAiB,kBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,cAAA;EAAA,SACA,SAAA;EAAA,SACA,IAAA;EAAA,SACA,kBAAA;AAAA;AAAA,UAGM,uBAAA;EAAA,SACN,OAAA;EAAA,SACA,UAAA,WAAqB,kBAAkB;AAAA;AAAA,UAGjC,mBAAA;EAAA,SACN,EAAA;EAAA,SACA,MAAA,WAAiB,uBAAuB;EAAA,SACxC,OAAA;AAAA;;;;;;;;;;;iBC8EW,sCAAA,CACpB,SAAA,EAAW,sBAAA,EACX,oBAAA,WACC,OAAA,UAAiB,uBAAA;AAAA,UA6BV,oBAAA,SAA6B,oBAAoB;EAAA,SAChD,MAAA;EAAA,SACA,KAAA;EAAA,SACA,KAAA;AAAA;AAAA,UAGM,+BAAA;EAAA,SACN,SAAA,EAAW,SAAS;EAAA,SACpB,QAAA;AAAA;AAAA,iBAGK,8BAAA,CACd,MAAA,EAAQ,mBAAA,EACR,OAAA,EAAS,+BAA+B;;;ADjIQ;AAGlD;;;;;UC6IiB,sBAAA;EAAA,SACN,MAAA,WAAiB,uBAAuB;EAAA,SACxC,WAAA;AAAA;AD5IO;;;;AC8ElB;;;;;AD9EkB,iBCgKF,gBAAA,CACd,MAAA,EAAQ,sBAAA,GACP,MAAA,CAAO,mBAAA,EAAqB,kBAAA;;;;;;iBA6BT,2BAAA,CACpB,OAAA,EAAS,oBAAA,EACT,KAAA,EAAO,WAAA,EACP,EAAA,EAAI,UAAA,GACH,OAAA,CAAQ,MAAA,CAAO,mBAAA,EAAqB,kBAAA;AAAA,iBAqCvB,0BAAA,CAAA,GAA8B,OAAO"}
1
+ {"version":3,"file":"migration-list.d.mts","names":[],"sources":["../../src/commands/migration-list.ts"],"mappings":";;;;;;;;;;AAmEA;;;;;;;;AAAA,iBAAgB,sBAAA,CACd,MAAA,EAAQ,mBAAA,GACP,WAAW;AA4Bd;;;;;;;;AAAA,iBAAsB,sCAAA,CACpB,SAAA,EAAW,sBAAA,EACX,oBAAA,WACC,OAAA,UAAiB,uBAAA;AAAA,UA6BV,oBAAA,SAA6B,oBAAoB;EAAA,SAChD,MAAA;EAAA,SACA,KAAA;EAAA,SACA,KAAA;EAAA,SACA,MAAA;AAAA;AAAA,UAGM,0BAAA;EAAA,SACN,IAAA,EAAM,mBAAA;EAAA,SACN,gBAAA;EAAA,SACA,SAAA,EAAW,sBAAsB;AAAA;AAAA,UAG3B,+BAAA;EAAA,SACN,SAAA,EAAW,SAAA;EAAA,SACX,QAAA;EAAA,SACA,gBAAA;EAAA,SACA,aAAA,GAAgB,OAAA,aAAoB,cAAc;AAAA;AAAA,iBAG7C,8BAAA,CACd,MAAA,EAAQ,mBAAA,EACR,OAAA,EAAS,+BAA+B;;;;;;;;;UAkBzB,sBAAA;EAAA,SACN,MAAA,WAAiB,uBAAuB;EAAA,SACxC,WAAA;AAAA;;;;;;;;;;iBAoBK,gBAAA,CACd,MAAA,EAAQ,sBAAA,GACP,MAAA,CAAO,mBAAA,EAAqB,kBAAA;AA/C8B;AAG7D;;;;AAH6D,iBA4EvC,2BAAA,CACpB,OAAA,EAAS,oBAAA,EACT,KAAA,EAAO,WAAA,EACP,EAAA,EAAI,UAAA,GACH,OAAA,CAAQ,MAAA,CAAO,0BAAA,EAA4B,kBAAA;AAAA,iBAiD9B,0BAAA,CAAA,GAA8B,OAAO"}