@prisma-next/cli 0.16.0-dev.3 → 0.16.0-dev.30

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 (162) hide show
  1. package/README.md +44 -45
  2. package/dist/cli.mjs +13 -13
  3. package/dist/{client-KuBQftxz.mjs → client-CMusjGV5.mjs} +24 -25
  4. package/dist/client-CMusjGV5.mjs.map +1 -0
  5. package/dist/{command-helpers-Cpq44aVa.mjs → command-helpers-CVn3U9Uz.mjs} +12 -4
  6. package/dist/command-helpers-CVn3U9Uz.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.d.mts.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-schema.mjs +3 -3
  13. package/dist/commands/db-sign.d.mts.map +1 -1
  14. package/dist/commands/db-sign.mjs +9 -11
  15. package/dist/commands/db-sign.mjs.map +1 -1
  16. package/dist/commands/db-update.d.mts.map +1 -1
  17. package/dist/commands/db-update.mjs +11 -13
  18. package/dist/commands/db-update.mjs.map +1 -1
  19. package/dist/commands/db-verify.mjs +1 -1
  20. package/dist/commands/migrate.d.mts +1 -1
  21. package/dist/commands/migrate.d.mts.map +1 -1
  22. package/dist/commands/migrate.mjs +13 -13
  23. package/dist/commands/migrate.mjs.map +1 -1
  24. package/dist/commands/migration-check.d.mts +4 -2
  25. package/dist/commands/migration-check.d.mts.map +1 -1
  26. package/dist/commands/migration-check.mjs +1 -1
  27. package/dist/commands/migration-graph.d.mts +1 -1
  28. package/dist/commands/migration-graph.mjs +4 -4
  29. package/dist/commands/migration-list.d.mts +1 -1
  30. package/dist/commands/migration-list.d.mts.map +1 -1
  31. package/dist/commands/migration-list.mjs +1 -1
  32. package/dist/commands/migration-log.d.mts +1 -1
  33. package/dist/commands/migration-log.mjs +1 -1
  34. package/dist/commands/migration-new.d.mts.map +1 -1
  35. package/dist/commands/migration-new.mjs +16 -40
  36. package/dist/commands/migration-new.mjs.map +1 -1
  37. package/dist/commands/migration-plan.d.mts +3 -4
  38. package/dist/commands/migration-plan.d.mts.map +1 -1
  39. package/dist/commands/migration-plan.mjs +1 -1
  40. package/dist/commands/migration-show.mjs +5 -5
  41. package/dist/commands/migration-show.mjs.map +1 -1
  42. package/dist/commands/migration-status.d.mts +1 -1
  43. package/dist/commands/migration-status.d.mts.map +1 -1
  44. package/dist/commands/migration-status.mjs +1 -1
  45. package/dist/commands/ref.d.mts +1 -1
  46. package/dist/commands/ref.d.mts.map +1 -1
  47. package/dist/commands/ref.mjs +13 -18
  48. package/dist/commands/ref.mjs.map +1 -1
  49. package/dist/commands/telemetry/index.mjs +1 -1
  50. package/dist/contract-at-errors-C-l4-JEY.mjs +36 -0
  51. package/dist/contract-at-errors-C-l4-JEY.mjs.map +1 -0
  52. package/dist/{contract-emit-cJQBlvGb.mjs → contract-emit-CfIbTnsR.mjs} +6 -7
  53. package/dist/{contract-emit-cJQBlvGb.mjs.map → contract-emit-CfIbTnsR.mjs.map} +1 -1
  54. package/dist/{contract-emit-CgnXSANN.mjs → contract-emit-PaY3qRdN.mjs} +3 -3
  55. package/dist/{contract-emit-CgnXSANN.mjs.map → contract-emit-PaY3qRdN.mjs.map} +1 -1
  56. package/dist/{contract-enrichment-gn9sWbPw.mjs → contract-enrichment-JUhLv-BX.mjs} +8 -8
  57. package/dist/{contract-enrichment-gn9sWbPw.mjs.map → contract-enrichment-JUhLv-BX.mjs.map} +1 -1
  58. package/dist/{contract-infer-Cg8evbeg.mjs → contract-infer-DCju2fTk.mjs} +3 -3
  59. package/dist/{contract-infer-Cg8evbeg.mjs.map → contract-infer-DCju2fTk.mjs.map} +1 -1
  60. package/dist/{contract-space-aggregate-loader-D_3VeHVb.mjs → contract-space-aggregate-loader-B6E9LGa6.mjs} +14 -14
  61. package/dist/contract-space-aggregate-loader-B6E9LGa6.mjs.map +1 -0
  62. package/dist/{db-verify-BEclUzki.mjs → db-verify-B_dKu6Yp.mjs} +5 -5
  63. package/dist/db-verify-B_dKu6Yp.mjs.map +1 -0
  64. package/dist/exports/control-api.d.mts +4 -4
  65. package/dist/exports/control-api.d.mts.map +1 -1
  66. package/dist/exports/control-api.mjs +3 -3
  67. package/dist/exports/index.mjs +2 -2
  68. package/dist/exports/init-output.d.mts.map +1 -1
  69. package/dist/exports/init-output.mjs +1 -1
  70. package/dist/{format-DAUAZqPt.mjs → format-cCyDfmRE.mjs} +8 -7
  71. package/dist/format-cCyDfmRE.mjs.map +1 -0
  72. package/dist/{framework-components-CnbUbiJw.mjs → framework-components-DUN-TYDg.mjs} +3 -3
  73. package/dist/framework-components-DUN-TYDg.mjs.map +1 -0
  74. package/dist/{init-C3JhkHg-.mjs → init-C9U3ffHH.mjs} +55 -47
  75. package/dist/init-C9U3ffHH.mjs.map +1 -0
  76. package/dist/{inspect-live-schema-CX7EA5C3.mjs → inspect-live-schema-DHXE7skX.mjs} +4 -4
  77. package/dist/{inspect-live-schema-CX7EA5C3.mjs.map → inspect-live-schema-DHXE7skX.mjs.map} +1 -1
  78. package/dist/{migration-check-MHT3w7_v.mjs → migration-check-W5XEx4d-.mjs} +58 -30
  79. package/dist/migration-check-W5XEx4d-.mjs.map +1 -0
  80. package/dist/{migration-command-scaffold-CRyYrHZ9.mjs → migration-command-scaffold-hI5cnoGe.mjs} +4 -4
  81. package/dist/{migration-command-scaffold-CRyYrHZ9.mjs.map → migration-command-scaffold-hI5cnoGe.mjs.map} +1 -1
  82. package/dist/{migration-graph-command-render-B83xrnNy.mjs → migration-graph-command-render-DgQg5App.mjs} +3 -3
  83. package/dist/migration-graph-command-render-DgQg5App.mjs.map +1 -0
  84. package/dist/{migration-list-BAKujUjh.mjs → migration-list-ClkEaoL8.mjs} +6 -6
  85. package/dist/migration-list-ClkEaoL8.mjs.map +1 -0
  86. package/dist/{migration-log-C_xam2HZ.mjs → migration-log-CjafbZ2Z.mjs} +5 -5
  87. package/dist/{migration-log-C_xam2HZ.mjs.map → migration-log-CjafbZ2Z.mjs.map} +1 -1
  88. package/dist/{migration-path-target-DpPTsRCg.mjs → migration-path-target-C0TQuV5n.mjs} +2 -2
  89. package/dist/{migration-path-target-DpPTsRCg.mjs.map → migration-path-target-C0TQuV5n.mjs.map} +1 -1
  90. package/dist/{migration-plan-CreSVtWZ.mjs → migration-plan-Pc4hCF1H.mjs} +64 -74
  91. package/dist/migration-plan-Pc4hCF1H.mjs.map +1 -0
  92. package/dist/{migration-status-YgEvXf-u.mjs → migration-status-CqAdRzs8.mjs} +13 -12
  93. package/dist/migration-status-CqAdRzs8.mjs.map +1 -0
  94. package/dist/{output-mEQ74_nd.mjs → output-DWNYqZGc.mjs} +5 -6
  95. package/dist/output-DWNYqZGc.mjs.map +1 -0
  96. package/dist/{ref-advancement-BkXlikCA.mjs → ref-advancement-BCz7X7qJ.mjs} +13 -6
  97. package/dist/ref-advancement-BCz7X7qJ.mjs.map +1 -0
  98. package/dist/{telemetry-DVr6RFnq.mjs → telemetry-BEyNMfco.mjs} +2 -2
  99. package/dist/{telemetry-DVr6RFnq.mjs.map → telemetry-BEyNMfco.mjs.map} +1 -1
  100. package/dist/{types-D4r_HI9-.d.mts → types-DgXprE3w.d.mts} +3 -3
  101. package/dist/types-DgXprE3w.d.mts.map +1 -0
  102. package/dist/{verify-CgDVZjhc.mjs → verify-C4RazDE1.mjs} +2 -2
  103. package/dist/{verify-CgDVZjhc.mjs.map → verify-C4RazDE1.mjs.map} +1 -1
  104. package/package.json +21 -21
  105. package/src/commands/db-init.ts +1 -0
  106. package/src/commands/db-sign.ts +7 -5
  107. package/src/commands/db-update.ts +14 -6
  108. package/src/commands/db-verify.ts +1 -1
  109. package/src/commands/format.ts +1 -1
  110. package/src/commands/init/hygiene-gitattributes.ts +37 -21
  111. package/src/commands/init/init.ts +6 -6
  112. package/src/commands/init/output.ts +4 -5
  113. package/src/commands/init/reinit-cleanup.ts +16 -17
  114. package/src/commands/inspect-live-schema.ts +1 -1
  115. package/src/commands/migrate.ts +6 -5
  116. package/src/commands/migration-check.ts +72 -34
  117. package/src/commands/migration-list.ts +1 -5
  118. package/src/commands/migration-log.ts +1 -1
  119. package/src/commands/migration-new.ts +17 -41
  120. package/src/commands/migration-plan.ts +64 -88
  121. package/src/commands/migration-show.ts +2 -2
  122. package/src/commands/migration-status.ts +6 -7
  123. package/src/commands/ref.ts +19 -14
  124. package/src/control-api/client.ts +7 -8
  125. package/src/control-api/contract-enrichment.ts +7 -7
  126. package/src/control-api/operations/contract-emit.ts +2 -3
  127. package/src/control-api/operations/db-init.ts +3 -3
  128. package/src/control-api/operations/db-run.ts +6 -6
  129. package/src/control-api/operations/db-update.ts +2 -2
  130. package/src/control-api/operations/db-verify.ts +4 -4
  131. package/src/control-api/operations/format.ts +5 -4
  132. package/src/control-api/operations/migrate.ts +3 -3
  133. package/src/control-api/types.ts +1 -1
  134. package/src/utils/cli-errors.ts +15 -7
  135. package/src/utils/contract-at-errors.ts +13 -22
  136. package/src/utils/contract-space-aggregate-loader.ts +8 -8
  137. package/src/utils/contract-space-seed-phase.ts +11 -9
  138. package/src/utils/extension-pack-inputs.ts +8 -8
  139. package/src/utils/formatters/migration-graph-labels.ts +1 -2
  140. package/src/utils/formatters/migration-list-data-column.ts +1 -2
  141. package/src/utils/framework-components.ts +9 -9
  142. package/src/utils/integrity-violation-to-check-failure.ts +3 -3
  143. package/src/utils/migration-command-scaffold.ts +1 -1
  144. package/src/utils/plan-resolution.ts +7 -10
  145. package/src/utils/ref-advancement.ts +22 -3
  146. package/dist/client-KuBQftxz.mjs.map +0 -1
  147. package/dist/command-helpers-Cpq44aVa.mjs.map +0 -1
  148. package/dist/contract-at-errors-D9gEjYtg.mjs +0 -42
  149. package/dist/contract-at-errors-D9gEjYtg.mjs.map +0 -1
  150. package/dist/contract-space-aggregate-loader-D_3VeHVb.mjs.map +0 -1
  151. package/dist/db-verify-BEclUzki.mjs.map +0 -1
  152. package/dist/format-DAUAZqPt.mjs.map +0 -1
  153. package/dist/framework-components-CnbUbiJw.mjs.map +0 -1
  154. package/dist/init-C3JhkHg-.mjs.map +0 -1
  155. package/dist/migration-check-MHT3w7_v.mjs.map +0 -1
  156. package/dist/migration-graph-command-render-B83xrnNy.mjs.map +0 -1
  157. package/dist/migration-list-BAKujUjh.mjs.map +0 -1
  158. package/dist/migration-plan-CreSVtWZ.mjs.map +0 -1
  159. package/dist/migration-status-YgEvXf-u.mjs.map +0 -1
  160. package/dist/output-mEQ74_nd.mjs.map +0 -1
  161. package/dist/ref-advancement-BkXlikCA.mjs.map +0 -1
  162. package/dist/types-D4r_HI9-.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"migration-log-C_xam2HZ.mjs","names":[],"sources":["../src/utils/formatters/migration-log-table.ts","../src/commands/migration-log.ts"],"sourcesContent":["import type { LedgerEntryRecord } from '@prisma-next/contract/types';\nimport stringWidth from 'string-width';\nimport type { GlyphMode } from '../glyph-mode';\nimport {\n abbreviateContractHash,\n migrationListEmptySource,\n migrationListForwardArrow,\n} from './migration-list-data-column';\nimport { IDENTITY_MIGRATION_LIST_STYLER, type MigrationListStyler } from './migration-list-render';\n\nexport type LedgerTimestampMode = 'local' | 'utc' | 'iso';\n\nexport interface RenderMigrationLogTableOptions {\n readonly utc?: boolean;\n readonly styler?: MigrationListStyler;\n readonly glyphMode?: GlyphMode;\n}\n\nexport interface SerializedLedgerEntryRecord {\n readonly space: string;\n readonly name: string;\n readonly hash: string;\n readonly fromContract: string | null;\n readonly toContract: string;\n readonly appliedAt: string;\n readonly operationCount: number;\n}\n\nconst HEADING_APPLIED_AT = 'Applied at';\nconst HEADING_SPACE = 'Space';\nconst HEADING_MIGRATION = 'Migration';\nconst HEADING_CHANGE = 'Change';\nconst HEADING_OPS = 'Ops';\nconst COLUMN_SEPARATOR = ' ';\nconst DIVIDER_CHAR = '─';\nconst ASCII_DIVIDER_CHAR = '-';\n\nexport function sortLedgerEntries(entries: readonly LedgerEntryRecord[]): LedgerEntryRecord[] {\n return [...entries].sort((left, right) => {\n const timeDiff = left.appliedAt.getTime() - right.appliedAt.getTime();\n if (timeDiff !== 0) {\n return timeDiff;\n }\n const spaceDiff = left.space.localeCompare(right.space);\n if (spaceDiff !== 0) {\n return spaceDiff;\n }\n return left.migrationName.localeCompare(right.migrationName);\n });\n}\n\nfunction pad2(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nexport function formatLedgerAppliedAt(date: Date, mode: LedgerTimestampMode): string {\n if (mode === 'iso') {\n return date.toISOString();\n }\n if (mode === 'utc') {\n return `${date.getUTCFullYear()}-${pad2(date.getUTCMonth() + 1)}-${pad2(date.getUTCDate())} ${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}:${pad2(date.getUTCSeconds())}Z`;\n }\n const offsetMinutes = -date.getTimezoneOffset();\n const sign = offsetMinutes >= 0 ? '+' : '-';\n const absoluteOffset = Math.abs(offsetMinutes);\n const offsetHours = pad2(Math.floor(absoluteOffset / 60));\n const offsetMins = pad2(absoluteOffset % 60);\n return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())} ${sign}${offsetHours}:${offsetMins}`;\n}\n\nexport function formatHashEndpoint(hash: string | null, glyphMode: GlyphMode = 'unicode'): string {\n if (hash === null) {\n return migrationListEmptySource(glyphMode);\n }\n return abbreviateContractHash(hash);\n}\n\nexport function formatHashTransition(\n from: string | null,\n to: string,\n glyphMode: GlyphMode = 'unicode',\n): string {\n return `${formatHashEndpoint(from, glyphMode)} ${migrationListForwardArrow(glyphMode)} ${abbreviateContractHash(to)}`;\n}\n\nexport function styleHashTransition(\n from: string | null,\n to: string,\n styler: MigrationListStyler,\n glyphMode: GlyphMode = 'unicode',\n): string {\n const fromPart =\n from === null\n ? styler.glyph(migrationListEmptySource(glyphMode))\n : styler.sourceHash(abbreviateContractHash(from));\n const arrow = styler.glyph(migrationListForwardArrow(glyphMode));\n const dest = styler.destHash(abbreviateContractHash(to));\n return `${fromPart} ${arrow} ${dest}`;\n}\n\nfunction padVisible(text: string, targetWidth: number): string {\n const padding = Math.max(0, targetWidth - stringWidth(text));\n return text + ' '.repeat(padding);\n}\n\nfunction columnWidth(values: readonly string[]): number {\n return values.reduce((max, value) => Math.max(max, stringWidth(value)), 0);\n}\n\nfunction padDividerCell(valueWidth: number, dividerChar: string): string {\n return dividerChar.repeat(valueWidth + 2);\n}\n\nfunction padTextCell(value: string, valueWidth: number): string {\n return ` ${padVisible(value, valueWidth)} `;\n}\n\nfunction padOpsCell(value: string, valueWidth: number): string {\n const padding = Math.max(0, valueWidth - stringWidth(value));\n return ` ${' '.repeat(padding)}${value} `;\n}\n\nexport function renderMigrationLogTable(\n entries: readonly LedgerEntryRecord[],\n options: RenderMigrationLogTableOptions = {},\n): string {\n const sorted = sortLedgerEntries(entries);\n if (sorted.length === 0) {\n return '';\n }\n\n const styler = options.styler ?? IDENTITY_MIGRATION_LIST_STYLER;\n const glyphMode = options.glyphMode ?? 'unicode';\n const dividerChar = glyphMode === 'ascii' ? ASCII_DIVIDER_CHAR : DIVIDER_CHAR;\n const showSpace = new Set(sorted.map((entry) => entry.space)).size > 1;\n const timestampMode: LedgerTimestampMode = options.utc ? 'utc' : 'local';\n const rows = sorted.map((entry) => ({\n appliedAt: formatLedgerAppliedAt(entry.appliedAt, timestampMode),\n space: entry.space,\n migrationName: entry.migrationName,\n transition: formatHashTransition(entry.from, entry.to, glyphMode),\n ops: `${entry.operationCount} ops`,\n from: entry.from,\n to: entry.to,\n }));\n\n const appliedAtWidth = columnWidth([HEADING_APPLIED_AT, ...rows.map((row) => row.appliedAt)]);\n const spaceWidth = showSpace ? columnWidth([HEADING_SPACE, ...rows.map((row) => row.space)]) : 0;\n const nameWidth = columnWidth([HEADING_MIGRATION, ...rows.map((row) => row.migrationName)]);\n const transitionWidth = columnWidth([HEADING_CHANGE, ...rows.map((row) => row.transition)]);\n const opsWidth = columnWidth([HEADING_OPS, ...rows.map((row) => row.ops)]);\n\n const headingParts = [padTextCell(HEADING_APPLIED_AT, appliedAtWidth)];\n if (showSpace) {\n headingParts.push(padTextCell(HEADING_SPACE, spaceWidth));\n }\n headingParts.push(\n padTextCell(HEADING_MIGRATION, nameWidth),\n padTextCell(HEADING_CHANGE, transitionWidth),\n padOpsCell(HEADING_OPS, opsWidth),\n );\n const heading = headingParts.join(COLUMN_SEPARATOR);\n\n const dividerParts = [padDividerCell(appliedAtWidth, dividerChar)];\n if (showSpace) {\n dividerParts.push(padDividerCell(spaceWidth, dividerChar));\n }\n dividerParts.push(\n padDividerCell(nameWidth, dividerChar),\n padDividerCell(transitionWidth, dividerChar),\n padDividerCell(opsWidth, dividerChar),\n );\n const divider = dividerParts.map((cell) => styler.summary(cell)).join(COLUMN_SEPARATOR);\n\n const dataRows = rows.map((row) => {\n const parts = [padTextCell(row.appliedAt, appliedAtWidth)];\n if (showSpace) {\n parts.push(padTextCell(row.space, spaceWidth));\n }\n parts.push(\n padTextCell(styler.dirName(row.migrationName), nameWidth),\n padTextCell(styleHashTransition(row.from, row.to, styler, glyphMode), transitionWidth),\n padOpsCell(row.ops, opsWidth),\n );\n return parts.join(COLUMN_SEPARATOR);\n });\n\n return [heading, divider, ...dataRows].join('\\n');\n}\n\nexport function serializeLedgerEntriesForJson(\n entries: readonly LedgerEntryRecord[],\n): SerializedLedgerEntryRecord[] {\n return sortLedgerEntries(entries).map((entry) => ({\n space: entry.space,\n name: entry.migrationName,\n hash: entry.migrationHash,\n fromContract: entry.from,\n toContract: entry.to,\n appliedAt: formatLedgerAppliedAt(entry.appliedAt, 'iso'),\n operationCount: entry.operationCount,\n }));\n}\n\nexport const MIGRATION_LOG_EMPTY_MESSAGE = 'No migrations have been applied to this database.';\n","import { loadConfig } from '@prisma-next/config-loader';\nimport type { LedgerEntryRecord } from '@prisma-next/contract/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { createControlClient } from '../control-api/client';\nimport {\n CliStructuredError,\n errorUnexpected,\n mapMigrationToolsError,\n requireLiveDatabase,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n maskConnectionUrl,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { createAnsiMigrationListStyler } from '../utils/formatters/migration-list-styler';\nimport {\n MIGRATION_LOG_EMPTY_MESSAGE,\n renderMigrationLogTable,\n serializeLedgerEntriesForJson,\n} from '../utils/formatters/migration-log-table';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\nimport type { MigrationLogResult } from './json/schemas';\n\nexport type { MigrationLogResult };\n\ninterface MigrationLogOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly utc?: boolean;\n readonly ascii?: boolean;\n}\n\nexport async function executeMigrationLogCommand(\n options: MigrationLogOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<readonly LedgerEntryRecord[], CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath } = resolveMigrationPaths(options.config, config);\n\n const dbConnection = options.db ?? config.db?.connection;\n const missingDb = requireLiveDatabase({\n dbConnection,\n hasDriver: !!config.driver,\n why: `migration log needs a database connection and driver to read the ledger (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migration log',\n });\n if (missingDb) {\n return notOk(missingDb);\n }\n if (!targetSupportsMigrations(config.target)) {\n return notOk(errorUnexpected('Target does not support migrations'));\n }\n\n if (!flags.json && !flags.quiet) {\n const header = formatStyledHeader({\n command: 'migration log',\n description: 'Show executed migration history from the database ledger',\n details: [\n { label: 'config', value: configPath },\n ...(typeof dbConnection === 'string'\n ? [{ label: 'database', value: maskConnectionUrl(dbConnection) }]\n : []),\n ],\n flags,\n });\n ui.stderr(header);\n }\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...ifDefined('driver', config.driver),\n extensionPacks: config.extensionPacks ?? [],\n });\n\n try {\n await client.connect(dbConnection);\n const ledger = await client.readLedger();\n return ok(ledger);\n } catch (error) {\n if (CliStructuredError.is(error)) return notOk(error);\n if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migration log: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrationLogCommand(): Command {\n const command = new Command('log');\n setCommandDescriptions(\n command,\n 'Show executed migration history',\n 'Reads the database ledger and displays every applied migration edge\\n' +\n 'in chronological order, including rollbacks and re-applies, merged\\n' +\n 'across all contract spaces. Requires a database connection.',\n );\n setCommandExamples(command, [\n 'prisma-next migration log --db $DATABASE_URL',\n 'prisma-next migration log --utc --db $DATABASE_URL',\n 'prisma-next migration log --json --db $DATABASE_URL',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n { verb: 'migration show', oneLiner: 'Display migration package contents' },\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--utc', 'Render human timestamps in UTC instead of local time')\n .option('--ascii', 'Use ASCII glyphs (pipe-friendly)')\n .action(async (options: MigrationLogOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n const result = await executeMigrationLogCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (entries) => {\n if (flags.json) {\n const records = serializeLedgerEntriesForJson(entries);\n const result: MigrationLogResult = {\n ok: true,\n records,\n summary: `${records.length} migration(s) applied`,\n };\n ui.output(JSON.stringify(result, null, 2));\n } else if (!flags.quiet) {\n if (entries.length === 0) {\n ui.output(MIGRATION_LOG_EMPTY_MESSAGE);\n } else {\n const styler = createAnsiMigrationListStyler({ useColor: ui.useColor });\n ui.output(\n renderMigrationLogTable(entries, {\n utc: options.utc === true,\n styler,\n glyphMode: ui.resolveGlyphMode(options.ascii === true),\n }),\n );\n }\n }\n });\n process.exit(exitCode);\n });\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"migration-log-CjafbZ2Z.mjs","names":[],"sources":["../src/utils/formatters/migration-log-table.ts","../src/commands/migration-log.ts"],"sourcesContent":["import type { LedgerEntryRecord } from '@prisma-next/contract/types';\nimport stringWidth from 'string-width';\nimport type { GlyphMode } from '../glyph-mode';\nimport {\n abbreviateContractHash,\n migrationListEmptySource,\n migrationListForwardArrow,\n} from './migration-list-data-column';\nimport { IDENTITY_MIGRATION_LIST_STYLER, type MigrationListStyler } from './migration-list-render';\n\nexport type LedgerTimestampMode = 'local' | 'utc' | 'iso';\n\nexport interface RenderMigrationLogTableOptions {\n readonly utc?: boolean;\n readonly styler?: MigrationListStyler;\n readonly glyphMode?: GlyphMode;\n}\n\nexport interface SerializedLedgerEntryRecord {\n readonly space: string;\n readonly name: string;\n readonly hash: string;\n readonly fromContract: string | null;\n readonly toContract: string;\n readonly appliedAt: string;\n readonly operationCount: number;\n}\n\nconst HEADING_APPLIED_AT = 'Applied at';\nconst HEADING_SPACE = 'Space';\nconst HEADING_MIGRATION = 'Migration';\nconst HEADING_CHANGE = 'Change';\nconst HEADING_OPS = 'Ops';\nconst COLUMN_SEPARATOR = ' ';\nconst DIVIDER_CHAR = '─';\nconst ASCII_DIVIDER_CHAR = '-';\n\nexport function sortLedgerEntries(entries: readonly LedgerEntryRecord[]): LedgerEntryRecord[] {\n return [...entries].sort((left, right) => {\n const timeDiff = left.appliedAt.getTime() - right.appliedAt.getTime();\n if (timeDiff !== 0) {\n return timeDiff;\n }\n const spaceDiff = left.space.localeCompare(right.space);\n if (spaceDiff !== 0) {\n return spaceDiff;\n }\n return left.migrationName.localeCompare(right.migrationName);\n });\n}\n\nfunction pad2(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nexport function formatLedgerAppliedAt(date: Date, mode: LedgerTimestampMode): string {\n if (mode === 'iso') {\n return date.toISOString();\n }\n if (mode === 'utc') {\n return `${date.getUTCFullYear()}-${pad2(date.getUTCMonth() + 1)}-${pad2(date.getUTCDate())} ${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}:${pad2(date.getUTCSeconds())}Z`;\n }\n const offsetMinutes = -date.getTimezoneOffset();\n const sign = offsetMinutes >= 0 ? '+' : '-';\n const absoluteOffset = Math.abs(offsetMinutes);\n const offsetHours = pad2(Math.floor(absoluteOffset / 60));\n const offsetMins = pad2(absoluteOffset % 60);\n return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())} ${sign}${offsetHours}:${offsetMins}`;\n}\n\nexport function formatHashEndpoint(hash: string | null, glyphMode: GlyphMode = 'unicode'): string {\n if (hash === null) {\n return migrationListEmptySource(glyphMode);\n }\n return abbreviateContractHash(hash);\n}\n\nexport function formatHashTransition(\n from: string | null,\n to: string,\n glyphMode: GlyphMode = 'unicode',\n): string {\n return `${formatHashEndpoint(from, glyphMode)} ${migrationListForwardArrow(glyphMode)} ${abbreviateContractHash(to)}`;\n}\n\nexport function styleHashTransition(\n from: string | null,\n to: string,\n styler: MigrationListStyler,\n glyphMode: GlyphMode = 'unicode',\n): string {\n const fromPart =\n from === null\n ? styler.glyph(migrationListEmptySource(glyphMode))\n : styler.sourceHash(abbreviateContractHash(from));\n const arrow = styler.glyph(migrationListForwardArrow(glyphMode));\n const dest = styler.destHash(abbreviateContractHash(to));\n return `${fromPart} ${arrow} ${dest}`;\n}\n\nfunction padVisible(text: string, targetWidth: number): string {\n const padding = Math.max(0, targetWidth - stringWidth(text));\n return text + ' '.repeat(padding);\n}\n\nfunction columnWidth(values: readonly string[]): number {\n return values.reduce((max, value) => Math.max(max, stringWidth(value)), 0);\n}\n\nfunction padDividerCell(valueWidth: number, dividerChar: string): string {\n return dividerChar.repeat(valueWidth + 2);\n}\n\nfunction padTextCell(value: string, valueWidth: number): string {\n return ` ${padVisible(value, valueWidth)} `;\n}\n\nfunction padOpsCell(value: string, valueWidth: number): string {\n const padding = Math.max(0, valueWidth - stringWidth(value));\n return ` ${' '.repeat(padding)}${value} `;\n}\n\nexport function renderMigrationLogTable(\n entries: readonly LedgerEntryRecord[],\n options: RenderMigrationLogTableOptions = {},\n): string {\n const sorted = sortLedgerEntries(entries);\n if (sorted.length === 0) {\n return '';\n }\n\n const styler = options.styler ?? IDENTITY_MIGRATION_LIST_STYLER;\n const glyphMode = options.glyphMode ?? 'unicode';\n const dividerChar = glyphMode === 'ascii' ? ASCII_DIVIDER_CHAR : DIVIDER_CHAR;\n const showSpace = new Set(sorted.map((entry) => entry.space)).size > 1;\n const timestampMode: LedgerTimestampMode = options.utc ? 'utc' : 'local';\n const rows = sorted.map((entry) => ({\n appliedAt: formatLedgerAppliedAt(entry.appliedAt, timestampMode),\n space: entry.space,\n migrationName: entry.migrationName,\n transition: formatHashTransition(entry.from, entry.to, glyphMode),\n ops: `${entry.operationCount} ops`,\n from: entry.from,\n to: entry.to,\n }));\n\n const appliedAtWidth = columnWidth([HEADING_APPLIED_AT, ...rows.map((row) => row.appliedAt)]);\n const spaceWidth = showSpace ? columnWidth([HEADING_SPACE, ...rows.map((row) => row.space)]) : 0;\n const nameWidth = columnWidth([HEADING_MIGRATION, ...rows.map((row) => row.migrationName)]);\n const transitionWidth = columnWidth([HEADING_CHANGE, ...rows.map((row) => row.transition)]);\n const opsWidth = columnWidth([HEADING_OPS, ...rows.map((row) => row.ops)]);\n\n const headingParts = [padTextCell(HEADING_APPLIED_AT, appliedAtWidth)];\n if (showSpace) {\n headingParts.push(padTextCell(HEADING_SPACE, spaceWidth));\n }\n headingParts.push(\n padTextCell(HEADING_MIGRATION, nameWidth),\n padTextCell(HEADING_CHANGE, transitionWidth),\n padOpsCell(HEADING_OPS, opsWidth),\n );\n const heading = headingParts.join(COLUMN_SEPARATOR);\n\n const dividerParts = [padDividerCell(appliedAtWidth, dividerChar)];\n if (showSpace) {\n dividerParts.push(padDividerCell(spaceWidth, dividerChar));\n }\n dividerParts.push(\n padDividerCell(nameWidth, dividerChar),\n padDividerCell(transitionWidth, dividerChar),\n padDividerCell(opsWidth, dividerChar),\n );\n const divider = dividerParts.map((cell) => styler.summary(cell)).join(COLUMN_SEPARATOR);\n\n const dataRows = rows.map((row) => {\n const parts = [padTextCell(row.appliedAt, appliedAtWidth)];\n if (showSpace) {\n parts.push(padTextCell(row.space, spaceWidth));\n }\n parts.push(\n padTextCell(styler.dirName(row.migrationName), nameWidth),\n padTextCell(styleHashTransition(row.from, row.to, styler, glyphMode), transitionWidth),\n padOpsCell(row.ops, opsWidth),\n );\n return parts.join(COLUMN_SEPARATOR);\n });\n\n return [heading, divider, ...dataRows].join('\\n');\n}\n\nexport function serializeLedgerEntriesForJson(\n entries: readonly LedgerEntryRecord[],\n): SerializedLedgerEntryRecord[] {\n return sortLedgerEntries(entries).map((entry) => ({\n space: entry.space,\n name: entry.migrationName,\n hash: entry.migrationHash,\n fromContract: entry.from,\n toContract: entry.to,\n appliedAt: formatLedgerAppliedAt(entry.appliedAt, 'iso'),\n operationCount: entry.operationCount,\n }));\n}\n\nexport const MIGRATION_LOG_EMPTY_MESSAGE = 'No migrations have been applied to this database.';\n","import { loadConfig } from '@prisma-next/config-loader';\nimport type { LedgerEntryRecord } from '@prisma-next/contract/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { createControlClient } from '../control-api/client';\nimport {\n CliStructuredError,\n errorUnexpected,\n mapMigrationToolsError,\n requireLiveDatabase,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n maskConnectionUrl,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { createAnsiMigrationListStyler } from '../utils/formatters/migration-list-styler';\nimport {\n MIGRATION_LOG_EMPTY_MESSAGE,\n renderMigrationLogTable,\n serializeLedgerEntriesForJson,\n} from '../utils/formatters/migration-log-table';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\nimport type { MigrationLogResult } from './json/schemas';\n\nexport type { MigrationLogResult };\n\ninterface MigrationLogOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly utc?: boolean;\n readonly ascii?: boolean;\n}\n\nexport async function executeMigrationLogCommand(\n options: MigrationLogOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<readonly LedgerEntryRecord[], CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath } = resolveMigrationPaths(options.config, config);\n\n const dbConnection = options.db ?? config.db?.connection;\n const missingDb = requireLiveDatabase({\n dbConnection,\n hasDriver: !!config.driver,\n why: `migration log needs a database connection and driver to read the ledger (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migration log',\n });\n if (missingDb) {\n return notOk(missingDb);\n }\n if (!targetSupportsMigrations(config.target)) {\n return notOk(errorUnexpected('Target does not support migrations'));\n }\n\n if (!flags.json && !flags.quiet) {\n const header = formatStyledHeader({\n command: 'migration log',\n description: 'Show executed migration history from the database ledger',\n details: [\n { label: 'config', value: configPath },\n ...(typeof dbConnection === 'string'\n ? [{ label: 'database', value: maskConnectionUrl(dbConnection) }]\n : []),\n ],\n flags,\n });\n ui.stderr(header);\n }\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...ifDefined('driver', config.driver),\n extensions: config.extensions ?? [],\n });\n\n try {\n await client.connect(dbConnection);\n const ledger = await client.readLedger();\n return ok(ledger);\n } catch (error) {\n if (CliStructuredError.is(error)) return notOk(error);\n if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migration log: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrationLogCommand(): Command {\n const command = new Command('log');\n setCommandDescriptions(\n command,\n 'Show executed migration history',\n 'Reads the database ledger and displays every applied migration edge\\n' +\n 'in chronological order, including rollbacks and re-applies, merged\\n' +\n 'across all contract spaces. Requires a database connection.',\n );\n setCommandExamples(command, [\n 'prisma-next migration log --db $DATABASE_URL',\n 'prisma-next migration log --utc --db $DATABASE_URL',\n 'prisma-next migration log --json --db $DATABASE_URL',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n { verb: 'migration show', oneLiner: 'Display migration package contents' },\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--utc', 'Render human timestamps in UTC instead of local time')\n .option('--ascii', 'Use ASCII glyphs (pipe-friendly)')\n .action(async (options: MigrationLogOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n const result = await executeMigrationLogCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (entries) => {\n if (flags.json) {\n const records = serializeLedgerEntriesForJson(entries);\n const result: MigrationLogResult = {\n ok: true,\n records,\n summary: `${records.length} migration(s) applied`,\n };\n ui.output(JSON.stringify(result, null, 2));\n } else if (!flags.quiet) {\n if (entries.length === 0) {\n ui.output(MIGRATION_LOG_EMPTY_MESSAGE);\n } else {\n const styler = createAnsiMigrationListStyler({ useColor: ui.useColor });\n ui.output(\n renderMigrationLogTable(entries, {\n utc: options.utc === true,\n styler,\n glyphMode: ui.resolveGlyphMode(options.ascii === true),\n }),\n );\n }\n }\n });\n process.exit(exitCode);\n });\n return command;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { rt as errorRuntime } from "./command-helpers-Cpq44aVa.mjs";
1
+ import { rt as errorRuntime } from "./command-helpers-CVn3U9Uz.mjs";
2
2
  import { notOk, ok } from "@prisma-next/utils/result";
3
3
  import { isAbsolute, relative, resolve } from "pathe";
4
4
  //#region src/utils/migration-path-target.ts
@@ -35,4 +35,4 @@ function findPackageByDirPath(packages, resolvedDirPath) {
35
35
  //#endregion
36
36
  export { resolveTargetPathAcrossSpaces as i, looksLikePath as n, resolveAppTargetPath as r, findPackageByDirPath as t };
37
37
 
38
- //# sourceMappingURL=migration-path-target-DpPTsRCg.mjs.map
38
+ //# sourceMappingURL=migration-path-target-C0TQuV5n.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration-path-target-DpPTsRCg.mjs","names":[],"sources":["../src/utils/migration-path-target.ts"],"sourcesContent":["import type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { isAbsolute, relative, resolve } from 'pathe';\nimport { type CliStructuredError, errorRuntime } from './cli-errors';\n\nexport function looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveAppTargetPath(\n target: string,\n appMigrationsDir: string,\n appMigrationsRelative: string,\n): Result<string, CliStructuredError> {\n const targetPath = resolve(target);\n const relativeToApp = relative(appMigrationsDir, targetPath);\n const isOutsideAppDir =\n relativeToApp === '' ||\n relativeToApp === '.' ||\n relativeToApp.startsWith('..') ||\n isAbsolute(relativeToApp);\n if (isOutsideAppDir) {\n return notOk(\n errorRuntime('Target must point to an app-space migration', {\n why: `Expected a path under ${appMigrationsRelative}, got ${target}`,\n fix: 'Pass an app-space migration directory or use a hash prefix.',\n }),\n );\n }\n return ok(targetPath);\n}\n\n/**\n * Resolve a filesystem-path target to the migration dir that contains it,\n * searching each in-scope space's `migrationsDir`. A path is explicit, so\n * it can belong to at most one space — returns the first match, or `null`\n * when the path falls outside every space dir.\n */\nexport function resolveTargetPathAcrossSpaces(\n target: string,\n spaces: ReadonlyArray<{ readonly migrationsDir: string }>,\n): string | null {\n const targetPath = resolve(target);\n for (const space of spaces) {\n const rel = relative(space.migrationsDir, targetPath);\n const isOutside = rel === '' || rel === '.' || rel.startsWith('..') || isAbsolute(rel);\n if (!isOutside) {\n return targetPath;\n }\n }\n return null;\n}\n\nexport function findPackageByDirPath(\n packages: readonly OnDiskMigrationPackage[],\n resolvedDirPath: string,\n): OnDiskMigrationPackage | undefined {\n const normalized = resolve(resolvedDirPath);\n return packages.find((p) => resolve(p.dirPath) === normalized);\n}\n"],"mappings":";;;;AAKA,SAAgB,cAAc,QAAyB;CACrD,OAAO,OAAO,SAAS,GAAG,KAAK,OAAO,SAAS,IAAI;AACrD;AAEA,SAAgB,qBACd,QACA,kBACA,uBACoC;CACpC,MAAM,aAAa,QAAQ,MAAM;CACjC,MAAM,gBAAgB,SAAS,kBAAkB,UAAU;CAM3D,IAJE,kBAAkB,MAClB,kBAAkB,OAClB,cAAc,WAAW,IAAI,KAC7B,WAAW,aAAa,GAExB,OAAO,MACL,aAAa,+CAA+C;EAC1D,KAAK,yBAAyB,sBAAsB,QAAQ;EAC5D,KAAK;CACP,CAAC,CACH;CAEF,OAAO,GAAG,UAAU;AACtB;;;;;;;AAQA,SAAgB,8BACd,QACA,QACe;CACf,MAAM,aAAa,QAAQ,MAAM;CACjC,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,MAAM,SAAS,MAAM,eAAe,UAAU;EAEpD,IAAI,EADc,QAAQ,MAAM,QAAQ,OAAO,IAAI,WAAW,IAAI,KAAK,WAAW,GAAG,IAEnF,OAAO;CAEX;CACA,OAAO;AACT;AAEA,SAAgB,qBACd,UACA,iBACoC;CACpC,MAAM,aAAa,QAAQ,eAAe;CAC1C,OAAO,SAAS,MAAM,MAAM,QAAQ,EAAE,OAAO,MAAM,UAAU;AAC/D"}
1
+ {"version":3,"file":"migration-path-target-C0TQuV5n.mjs","names":[],"sources":["../src/utils/migration-path-target.ts"],"sourcesContent":["import type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { isAbsolute, relative, resolve } from 'pathe';\nimport { type CliStructuredError, errorRuntime } from './cli-errors';\n\nexport function looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveAppTargetPath(\n target: string,\n appMigrationsDir: string,\n appMigrationsRelative: string,\n): Result<string, CliStructuredError> {\n const targetPath = resolve(target);\n const relativeToApp = relative(appMigrationsDir, targetPath);\n const isOutsideAppDir =\n relativeToApp === '' ||\n relativeToApp === '.' ||\n relativeToApp.startsWith('..') ||\n isAbsolute(relativeToApp);\n if (isOutsideAppDir) {\n return notOk(\n errorRuntime('Target must point to an app-space migration', {\n why: `Expected a path under ${appMigrationsRelative}, got ${target}`,\n fix: 'Pass an app-space migration directory or use a hash prefix.',\n }),\n );\n }\n return ok(targetPath);\n}\n\n/**\n * Resolve a filesystem-path target to the migration dir that contains it,\n * searching each in-scope space's `migrationsDir`. A path is explicit, so\n * it can belong to at most one space — returns the first match, or `null`\n * when the path falls outside every space dir.\n */\nexport function resolveTargetPathAcrossSpaces(\n target: string,\n spaces: ReadonlyArray<{ readonly migrationsDir: string }>,\n): string | null {\n const targetPath = resolve(target);\n for (const space of spaces) {\n const rel = relative(space.migrationsDir, targetPath);\n const isOutside = rel === '' || rel === '.' || rel.startsWith('..') || isAbsolute(rel);\n if (!isOutside) {\n return targetPath;\n }\n }\n return null;\n}\n\nexport function findPackageByDirPath(\n packages: readonly OnDiskMigrationPackage[],\n resolvedDirPath: string,\n): OnDiskMigrationPackage | undefined {\n const normalized = resolve(resolvedDirPath);\n return packages.find((p) => resolve(p.dirPath) === normalized);\n}\n"],"mappings":";;;;AAKA,SAAgB,cAAc,QAAyB;CACrD,OAAO,OAAO,SAAS,GAAG,KAAK,OAAO,SAAS,IAAI;AACrD;AAEA,SAAgB,qBACd,QACA,kBACA,uBACoC;CACpC,MAAM,aAAa,QAAQ,MAAM;CACjC,MAAM,gBAAgB,SAAS,kBAAkB,UAAU;CAM3D,IAJE,kBAAkB,MAClB,kBAAkB,OAClB,cAAc,WAAW,IAAI,KAC7B,WAAW,aAAa,GAExB,OAAO,MACL,aAAa,+CAA+C;EAC1D,KAAK,yBAAyB,sBAAsB,QAAQ;EAC5D,KAAK;CACP,CAAC,CACH;CAEF,OAAO,GAAG,UAAU;AACtB;;;;;;;AAQA,SAAgB,8BACd,QACA,QACe;CACf,MAAM,aAAa,QAAQ,MAAM;CACjC,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,MAAM,SAAS,MAAM,eAAe,UAAU;EAEpD,IAAI,EADc,QAAQ,MAAM,QAAQ,OAAO,IAAI,WAAW,IAAI,KAAK,WAAW,GAAG,IAEnF,OAAO;CAEX;CACA,OAAO;AACT;AAEA,SAAgB,qBACd,UACA,iBACoC;CACpC,MAAM,aAAa,QAAQ,eAAe;CAC1C,OAAO,SAAS,MAAM,MAAM,QAAQ,EAAE,OAAO,MAAM,UAAU;AAC/D"}
@@ -1,22 +1,22 @@
1
- import { A as formatStyledHeader, B as errorContractValidationFailed, F as CliStructuredError, Q as errorPlanForgotTheFlag, W as errorFileNotFound, X as errorMigrationPlanningFailed, _ as createTerminalUI, ct as errorUnexpected, g as parseGlobalFlagsOrExit, it as errorSnapshotMissing, l as setCommandDescriptions, lt as mapMigrationToolsError, o as resolveContractPath, ot as errorTargetMigrationNotSupported, r as getTargetMigrations, s as resolveMigrationPaths, t as addGlobalOptions, u as setCommandExamples, ut as mapRefResolutionError, y as handleResult } from "./command-helpers-Cpq44aVa.mjs";
2
- import { t as assertFrameworkComponentsCompatible } from "./framework-components-CnbUbiJw.mjs";
3
- import { c as toExtensionInputs, i as loadContractSpaceAggregateForCli, t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-D_3VeHVb.mjs";
4
- import { t as mapContractAtError } from "./contract-at-errors-D9gEjYtg.mjs";
1
+ import { A as formatStyledHeader, B as errorContractValidationFailed, F as CliStructuredError, Q as errorPlanForgotTheFlag, W as errorFileNotFound, X as errorMigrationPlanningFailed, _ as createTerminalUI, ct as errorUnexpected, g as parseGlobalFlagsOrExit, it as errorSnapshotMissing, l as setCommandDescriptions, lt as mapMigrationToolsError, o as resolveContractPath, ot as errorTargetMigrationNotSupported, r as getTargetMigrations, s as resolveMigrationPaths, t as addGlobalOptions, u as setCommandExamples, ut as mapRefResolutionError, y as handleResult } from "./command-helpers-CVn3U9Uz.mjs";
2
+ import { t as assertFrameworkComponentsCompatible } from "./framework-components-DUN-TYDg.mjs";
3
+ import { c as toExtensionInputs, i as loadContractSpaceAggregateForCli, t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-B6E9LGa6.mjs";
4
+ import { t as mapContractAtError } from "./contract-at-errors-C-l4-JEY.mjs";
5
5
  import { Command } from "commander";
6
6
  import { loadConfig } from "@prisma-next/config-loader";
7
7
  import { getEmittedArtifactPaths } from "@prisma-next/emitter";
8
8
  import { notOk, ok } from "@prisma-next/utils/result";
9
9
  import { join, relative } from "pathe";
10
- import { mkdir, readFile, writeFile } from "node:fs/promises";
10
+ import { readFile } from "node:fs/promises";
11
11
  import { createControlStack, hasOperationPreview } from "@prisma-next/framework-components/control";
12
- import { emitContractSpaceArtefacts, planAllSpaces, readContractSpaceHeadRef, spaceMigrationDirectory } from "@prisma-next/migration-tools/spaces";
12
+ import { emitContractSpaceArtifacts, planAllSpaces, readContractSpaceHeadRef, spaceMigrationDirectory } from "@prisma-next/migration-tools/spaces";
13
13
  import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
14
14
  import { assertHashIsGraphNode, findLatestMigration, isGraphNode } from "@prisma-next/migration-tools/migration-graph";
15
+ import { snapshotsImportPathFrom, writeContractSnapshot } from "@prisma-next/migration-tools/contract-snapshot-store";
15
16
  import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
16
17
  import { computeMigrationHash } from "@prisma-next/migration-tools/hash";
17
- import { copyFilesWithRename, formatMigrationDirName, materialiseExtensionMigrationPackageIfMissing, writeMigrationPackage } from "@prisma-next/migration-tools/io";
18
+ import { formatMigrationDirName, materialiseExtensionMigrationPackageIfMissing, writeMigrationPackage } from "@prisma-next/migration-tools/io";
18
19
  import { writeMigrationTs } from "@prisma-next/migration-tools/migration-ts";
19
- import { canonicalizeJson } from "@prisma-next/framework-components/utils";
20
20
  import { deriveProvidedInvariants } from "@prisma-next/migration-tools/invariants";
21
21
  //#region src/utils/contract-space-seed-phase.ts
22
22
  /**
@@ -25,9 +25,11 @@ import { deriveProvidedInvariants } from "@prisma-next/migration-tools/invariant
25
25
  * For every extension that exposes a `contractSpace`:
26
26
  *
27
27
  * 1. Read the on-disk head ref (returns `null` on first emit).
28
- * 2. Re-emit `contract.json` / `contract.d.ts` / `refs/head.json`
29
- * unconditionally via {@link emitContractSpaceArtefacts}. The
30
- * framework owns these files; re-emit is the contract.
28
+ * 2. Write the head contract into the migrations-root snapshot store
29
+ * (write-if-absent, keyed by hash) and unconditionally re-emit
30
+ * `refs/head.json`, via {@link emitContractSpaceArtifacts}. The
31
+ * framework owns `refs/head.json`; re-emit is the contract for that
32
+ * file. The snapshot itself is only written once per distinct hash.
31
33
  * 3. Materialise any descriptor-shipped migration packages not yet on
32
34
  * disk via {@link materialiseExtensionMigrationPackageIfMissing}.
33
35
  * Existing packages are left untouched (by-existence skip).
@@ -44,20 +46,20 @@ import { deriveProvidedInvariants } from "@prisma-next/migration-tools/invariant
44
46
  * surface (`migrate`, `migration status`, the runner).
45
47
  */
46
48
  async function runContractSpaceSeedPhase(inputs) {
47
- const planned = planAllSpaces(inputs.extensionPacks.filter((pack) => pack.contractSpace !== void 0).map((pack) => ({
49
+ const planned = planAllSpaces(inputs.extensions.filter((pack) => pack.contractSpace !== void 0).map((pack) => ({
48
50
  spaceId: pack.id,
49
51
  priorContract: null,
50
52
  newContract: pack.contractSpace.contractJson,
51
53
  __pack: pack.contractSpace
52
54
  })), (input) => input.__pack.migrations);
53
55
  const descriptorBySpace = /* @__PURE__ */ new Map();
54
- for (const pack of inputs.extensionPacks) if (pack.contractSpace !== void 0) descriptorBySpace.set(pack.id, pack.contractSpace);
56
+ for (const pack of inputs.extensions) if (pack.contractSpace !== void 0) descriptorBySpace.set(pack.id, pack.contractSpace);
55
57
  const seeded = [];
56
58
  for (const space of planned) {
57
59
  const descriptor = descriptorBySpace.get(space.spaceId);
58
60
  if (descriptor === void 0) continue;
59
61
  const priorHash = (await readContractSpaceHeadRef(inputs.migrationsDir, space.spaceId))?.hash ?? null;
60
- await emitContractSpaceArtefacts(inputs.migrationsDir, space.spaceId, {
62
+ await emitContractSpaceArtifacts(inputs.migrationsDir, space.spaceId, {
61
63
  contract: descriptor.contractJson,
62
64
  contractDts: buildPlaceholderContractDts(space.spaceId),
63
65
  headRef: {
@@ -109,7 +111,7 @@ function buildPlaceholderContractDts(spaceId) {
109
111
  }
110
112
  //#endregion
111
113
  //#region src/utils/plan-resolution.ts
112
- const FULL_HASH_PATTERN = /^sha256:([0-9a-f]{64}|empty)$/;
114
+ const FULL_HASH_PATTERN = /^([0-9a-f]{64}|empty)$/;
113
115
  function looksLikeFullHash(input) {
114
116
  return FULL_HASH_PATTERN.test(input);
115
117
  }
@@ -135,8 +137,8 @@ async function resolveContractRef(parsed, space, options) {
135
137
  const refName = provenance.kind === "ref" ? provenance.refName : void 0;
136
138
  try {
137
139
  const at = await space.contractAt(hash, refName !== void 0 ? { refName } : void 0);
138
- if (at.provenance === "snapshot") return ok({
139
- kind: "snapshot",
140
+ if (at.provenance === "ref") return ok({
141
+ kind: "ref",
140
142
  hash: at.hash,
141
143
  contract: at.contract,
142
144
  contractJson: at.contractJson,
@@ -147,8 +149,7 @@ async function resolveContractRef(parsed, space, options) {
147
149
  hash: at.hash,
148
150
  contract: at.contract,
149
151
  contractJson: at.contractJson,
150
- contractDts: at.contractDts,
151
- sourceDir: at.sourceDir
152
+ contractDts: at.contractDts
152
153
  });
153
154
  } catch (error) {
154
155
  return mapContractAtError(error, options?.artifactRole !== void 0 ? { artifactRole: options.artifactRole } : void 0);
@@ -163,8 +164,7 @@ async function resolveFromPolicy(parsed, input, refs, explicitFromLabel) {
163
164
  if (resolution.value.kind === "graph-node") return ok({
164
165
  kind: "graph-node",
165
166
  fromHash: resolution.value.hash,
166
- fromContract: resolution.value.contract,
167
- sourceDir: resolution.value.sourceDir
167
+ fromContract: resolution.value.contract
168
168
  });
169
169
  const { hash, contract, contractJson, contractDts } = resolution.value;
170
170
  if (graphIsEmpty(input.space)) return ok({
@@ -183,7 +183,7 @@ async function resolveFromPolicy(parsed, input, refs, explicitFromLabel) {
183
183
  throw error;
184
184
  }
185
185
  return ok({
186
- kind: "snapshot",
186
+ kind: "ref",
187
187
  fromHash: hash,
188
188
  fromContract: contract,
189
189
  contractDts,
@@ -248,17 +248,7 @@ async function resolveToForPlan(optionsTo, input) {
248
248
  }
249
249
  //#endregion
250
250
  //#region src/commands/migration-plan.ts
251
- async function writeSnapshotContractArtifacts(packageDir, contractJson, contractDts, artifactBasename) {
252
- await mkdir(packageDir, { recursive: true });
253
- const jsonContent = `${canonicalizeJson(contractJson)}\n`;
254
- const dtsContent = contractDts.endsWith("\n") ? contractDts : `${contractDts}\n`;
255
- await writeFile(join(packageDir, `${artifactBasename}.json`), jsonContent);
256
- await writeFile(join(packageDir, `${artifactBasename}.d.ts`), dtsContent);
257
- }
258
- async function writeSnapshotStartContract(packageDir, contractJson, contractDts) {
259
- await writeSnapshotContractArtifacts(packageDir, contractJson, contractDts, "start-contract");
260
- }
261
- async function runPlannerLeg(planner, migrations, frameworkComponents, contract, fromContract, spaceId, ownership) {
251
+ async function runPlannerLeg(planner, migrations, frameworkComponents, contract, fromContract, spaceId, ownership, snapshotsImportPath) {
262
252
  const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);
263
253
  const plannerResult = planner.plan({
264
254
  contract,
@@ -272,7 +262,8 @@ async function runPlannerLeg(planner, migrations, frameworkComponents, contract,
272
262
  fromContract,
273
263
  frameworkComponents,
274
264
  spaceId,
275
- ownership
265
+ ownership,
266
+ snapshotsImportPath
276
267
  });
277
268
  if (plannerResult.kind === "failure") return notOk(errorMigrationPlanningFailed({ conflicts: plannerResult.conflicts }));
278
269
  let plannedOps = [];
@@ -373,14 +364,13 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
373
364
  let toArtifacts = null;
374
365
  let fromContract = null;
375
366
  let fromHash = null;
376
- let fromContractSourceDir = null;
377
367
  let snapshotStartContract = null;
378
368
  let isAutoBaseline = false;
379
369
  const tolerantAggregateResult = await loadContractSpaceAggregateForCli({
380
370
  targetId: config.target.targetId,
381
371
  migrationsDir,
382
372
  appContract: toContract,
383
- extensionPacks: config.extensionPacks ?? [],
373
+ extensions: config.extensions ?? [],
384
374
  deserializeContract: (json) => familyInstance.deserializeContract(json)
385
375
  });
386
376
  if (!tolerantAggregateResult.ok) return notOk(tolerantAggregateResult.failure);
@@ -395,12 +385,12 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
395
385
  case "graph-node":
396
386
  fromHash = resolutionResult.value.fromHash;
397
387
  fromContract = resolutionResult.value.fromContract;
398
- fromContractSourceDir = resolutionResult.value.sourceDir;
399
388
  break;
400
- case "snapshot":
389
+ case "ref":
401
390
  fromHash = resolutionResult.value.fromHash;
402
391
  fromContract = resolutionResult.value.fromContract;
403
392
  snapshotStartContract = {
393
+ fromHash: resolutionResult.value.fromHash,
404
394
  contractJson: resolutionResult.value.contractJson,
405
395
  contractDts: resolutionResult.value.contractDts
406
396
  };
@@ -409,6 +399,7 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
409
399
  fromHash = resolutionResult.value.fromHash;
410
400
  fromContract = resolutionResult.value.fromContract;
411
401
  snapshotStartContract = {
402
+ fromHash: resolutionResult.value.fromHash,
412
403
  contractJson: resolutionResult.value.contractJson,
413
404
  contractDts: resolutionResult.value.contractDts
414
405
  };
@@ -427,7 +418,7 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
427
418
  }
428
419
  const seedResult = await runContractSpaceSeedPhase({
429
420
  migrationsDir,
430
- extensionPacks: toExtensionInputs(config.extensionPacks ?? [])
421
+ extensions: toExtensionInputs(config.extensions ?? [])
431
422
  });
432
423
  if (!flags.json && !flags.quiet) {
433
424
  for (const record of seedResult.seeded) if (record.action === "updated") {
@@ -455,7 +446,7 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
455
446
  targetId: config.target.targetId,
456
447
  migrationsDir,
457
448
  appContract: toContract,
458
- extensionPacks: config.extensionPacks ?? [],
449
+ extensions: config.extensions ?? [],
459
450
  deserializeContract: (json) => familyInstance.deserializeContract(json)
460
451
  });
461
452
  if (!aggregateResult.ok) return notOk(aggregateResult.failure);
@@ -463,21 +454,22 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
463
454
  const frameworkComponents = assertFrameworkComponentsCompatible(config.family.familyId, config.target.targetId, [
464
455
  config.target,
465
456
  config.adapter,
466
- ...config.extensionPacks ?? []
457
+ ...config.extensions ?? []
467
458
  ]);
468
- async function writeDestinationEndContract(packageDir) {
459
+ async function writeDestinationSnapshot(destHash) {
469
460
  if (toArtifacts !== null) {
470
- await writeSnapshotContractArtifacts(packageDir, toArtifacts.contractJson, toArtifacts.contractDts, "end-contract");
461
+ await writeContractSnapshot(migrationsDir, destHash, {
462
+ contractJson: toArtifacts.contractJson,
463
+ contractDts: toArtifacts.contractDts
464
+ });
471
465
  return;
472
466
  }
473
467
  const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);
474
- await copyFilesWithRename(packageDir, [{
475
- sourcePath: destinationArtifacts.jsonPath,
476
- destName: "end-contract.json"
477
- }, {
478
- sourcePath: destinationArtifacts.dtsPath,
479
- destName: "end-contract.d.ts"
480
- }]);
468
+ const [contractJsonRaw, contractDts] = await Promise.all([readFile(destinationArtifacts.jsonPath, "utf-8"), readFile(destinationArtifacts.dtsPath, "utf-8")]);
469
+ await writeContractSnapshot(migrationsDir, destHash, {
470
+ contractJson: JSON.parse(contractJsonRaw),
471
+ contractDts
472
+ });
481
473
  }
482
474
  try {
483
475
  const planner = migrations.createPlanner(controlAdapter);
@@ -488,10 +480,13 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
488
480
  const deltaDirName = formatMigrationDirName(deltaTimestamp, options.name ?? "migration");
489
481
  const baselinePackageDir = join(appMigrationsDir, baselineDirName);
490
482
  const deltaPackageDir = join(appMigrationsDir, deltaDirName);
491
- const baselineLeg = await runPlannerLeg(planner, migrations, frameworkComponents, fromContract, null, aggregate.app.spaceId, aggregate);
483
+ const baselineLeg = await runPlannerLeg(planner, migrations, frameworkComponents, fromContract, null, aggregate.app.spaceId, aggregate, snapshotsImportPathFrom(baselinePackageDir, migrationsDir));
492
484
  if (!baselineLeg.ok) return notOk(baselineLeg.failure);
493
485
  await writePlannedMigrationPackage(baselinePackageDir, null, fromHash, baselineTimestamp, baselineLeg.value);
494
- await writeSnapshotContractArtifacts(baselinePackageDir, snapshotStartContract.contractJson, snapshotStartContract.contractDts, "end-contract");
486
+ await writeContractSnapshot(migrationsDir, fromHash, {
487
+ contractJson: snapshotStartContract.contractJson,
488
+ contractDts: snapshotStartContract.contractDts
489
+ });
495
490
  if (fromHash === toStorageHash) {
496
491
  const baselineOps = baselineLeg.value.hasPlaceholders ? [] : baselineLeg.value.plannedOps;
497
492
  if (baselineLeg.value.hasPlaceholders) {
@@ -528,11 +523,14 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
528
523
  timings: { total: Date.now() - startTime }
529
524
  });
530
525
  }
531
- const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId, aggregate);
526
+ const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId, aggregate, snapshotsImportPathFrom(deltaPackageDir, migrationsDir));
532
527
  if (!deltaLeg.ok) return notOk(deltaLeg.failure);
533
528
  await writePlannedMigrationPackage(deltaPackageDir, fromHash, toStorageHash, deltaTimestamp, deltaLeg.value);
534
- await writeDestinationEndContract(deltaPackageDir);
535
- await writeSnapshotStartContract(deltaPackageDir, snapshotStartContract.contractJson, snapshotStartContract.contractDts);
529
+ await writeDestinationSnapshot(toStorageHash);
530
+ await writeContractSnapshot(migrationsDir, fromHash, {
531
+ contractJson: snapshotStartContract.contractJson,
532
+ contractDts: snapshotStartContract.contractDts
533
+ });
536
534
  const deltaOps = deltaLeg.value.hasPlaceholders ? [] : deltaLeg.value.plannedOps;
537
535
  if (deltaLeg.value.hasPlaceholders) return ok({
538
536
  ok: true,
@@ -568,20 +566,14 @@ async function executeMigrationPlanCommand(options, flags, ui, startTime) {
568
566
  }
569
567
  const timestamp = /* @__PURE__ */ new Date();
570
568
  const packageDir = join(appMigrationsDir, formatMigrationDirName(timestamp, options.name ?? "migration"));
571
- const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId, aggregate);
569
+ const deltaLeg = await runPlannerLeg(planner, migrations, frameworkComponents, aggregate.app.contract(), fromContract, aggregate.app.spaceId, aggregate, snapshotsImportPathFrom(packageDir, migrationsDir));
572
570
  if (!deltaLeg.ok) return notOk(deltaLeg.failure);
573
571
  await writePlannedMigrationPackage(packageDir, fromHash, toStorageHash, timestamp, deltaLeg.value);
574
- await writeDestinationEndContract(packageDir);
575
- if (fromContractSourceDir !== null) {
576
- const sourceArtifacts = getEmittedArtifactPaths(join(fromContractSourceDir, "end-contract.json"));
577
- await copyFilesWithRename(packageDir, [{
578
- sourcePath: sourceArtifacts.jsonPath,
579
- destName: "start-contract.json"
580
- }, {
581
- sourcePath: sourceArtifacts.dtsPath,
582
- destName: "start-contract.d.ts"
583
- }]);
584
- } else if (snapshotStartContract !== null) await writeSnapshotStartContract(packageDir, snapshotStartContract.contractJson, snapshotStartContract.contractDts);
572
+ await writeDestinationSnapshot(toStorageHash);
573
+ if (snapshotStartContract !== null) await writeContractSnapshot(migrationsDir, snapshotStartContract.fromHash, {
574
+ contractJson: snapshotStartContract.contractJson,
575
+ contractDts: snapshotStartContract.contractDts
576
+ });
585
577
  if (deltaLeg.value.hasPlaceholders) return ok({
586
578
  ok: true,
587
579
  noOp: false,
@@ -744,18 +736,16 @@ function formatMigrationPlanOutput(result, flags) {
744
736
  *
745
737
  * Note: matches `metadata.to` (the contract hash this migration produces),
746
738
  * not `metadata.migrationHash` (the package's content-addressed identity).
747
- * Tries exact match first, then prefix match (auto-prepending `sha256:` when
748
- * the needle omits the scheme). Returns the matched package on success, or a
749
- * discriminated failure indicating whether the prefix was ambiguous or simply
750
- * not found.
739
+ * Tries exact match first, then prefix match. Returns the matched package on
740
+ * success, or a discriminated failure indicating whether the prefix was
741
+ * ambiguous or simply not found.
751
742
  *
752
743
  * @internal Exported for testing only.
753
744
  */
754
745
  function resolveBundleByPrefix(bundles, needle) {
755
746
  const exact = bundles.find((p) => p.metadata.to === needle);
756
747
  if (exact) return ok(exact);
757
- const prefixWithScheme = needle.startsWith("sha256:") ? needle : `sha256:${needle}`;
758
- const candidates = bundles.filter((p) => p.metadata.to.startsWith(prefixWithScheme));
748
+ const candidates = bundles.filter((p) => p.metadata.to.startsWith(needle));
759
749
  if (candidates.length === 1) return ok(candidates[0]);
760
750
  if (candidates.length > 1) return notOk({
761
751
  reason: "ambiguous",
@@ -766,4 +756,4 @@ function resolveBundleByPrefix(bundles, needle) {
766
756
  //#endregion
767
757
  export { formatMigrationPlanOutput as n, resolveBundleByPrefix as r, createMigrationPlanCommand as t };
768
758
 
769
- //# sourceMappingURL=migration-plan-CreSVtWZ.mjs.map
759
+ //# sourceMappingURL=migration-plan-Pc4hCF1H.mjs.map