@prisma-next/cli 0.12.0-dev.5 → 0.12.0-dev.51

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 (174) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.mjs +180 -163
  3. package/dist/cli.mjs.map +1 -1
  4. package/dist/{client-KgJorIvG.mjs → client-DC-UlBLy.mjs} +83 -58
  5. package/dist/client-DC-UlBLy.mjs.map +1 -0
  6. package/dist/{command-helpers-Bbw1GbwL.mjs → command-helpers-esJGBD4W.mjs} +317 -23
  7. package/dist/command-helpers-esJGBD4W.mjs.map +1 -0
  8. package/dist/commands/contract-emit.mjs +1 -1
  9. package/dist/commands/contract-infer.mjs +1 -1
  10. package/dist/commands/db-init.mjs +4 -5
  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.mjs +4 -4
  14. package/dist/commands/db-update.d.mts.map +1 -1
  15. package/dist/commands/db-update.mjs +10 -7
  16. package/dist/commands/db-update.mjs.map +1 -1
  17. package/dist/commands/db-verify.mjs +1 -1
  18. package/dist/commands/migrate.d.mts +2 -2
  19. package/dist/commands/migrate.d.mts.map +1 -1
  20. package/dist/commands/migrate.mjs +6 -8
  21. package/dist/commands/migrate.mjs.map +1 -1
  22. package/dist/commands/migration-check.d.mts +55 -13
  23. package/dist/commands/migration-check.d.mts.map +1 -1
  24. package/dist/commands/migration-check.mjs +3 -2
  25. package/dist/commands/migration-graph.d.mts +17 -8
  26. package/dist/commands/migration-graph.d.mts.map +1 -1
  27. package/dist/commands/migration-graph.mjs +183 -2
  28. package/dist/commands/migration-graph.mjs.map +1 -0
  29. package/dist/commands/migration-list.d.mts +25 -27
  30. package/dist/commands/migration-list.d.mts.map +1 -1
  31. package/dist/commands/migration-list.mjs +2 -190
  32. package/dist/commands/migration-log.d.mts +9 -19
  33. package/dist/commands/migration-log.d.mts.map +1 -1
  34. package/dist/commands/migration-log.mjs +1 -137
  35. package/dist/commands/migration-new.mjs +3 -3
  36. package/dist/commands/migration-plan.d.mts +1 -1
  37. package/dist/commands/migration-plan.mjs +1 -1
  38. package/dist/commands/migration-show.d.mts +17 -21
  39. package/dist/commands/migration-show.d.mts.map +1 -1
  40. package/dist/commands/migration-show.mjs +23 -35
  41. package/dist/commands/migration-show.mjs.map +1 -1
  42. package/dist/commands/migration-status.d.mts +42 -144
  43. package/dist/commands/migration-status.d.mts.map +1 -1
  44. package/dist/commands/migration-status.mjs +3 -759
  45. package/dist/commands/ref.d.mts +1 -1
  46. package/dist/commands/ref.mjs +3 -3
  47. package/dist/commands/telemetry/index.d.mts +7 -0
  48. package/dist/commands/telemetry/index.d.mts.map +1 -0
  49. package/dist/commands/telemetry/index.mjs +2 -0
  50. package/dist/{contract-at-errors-BxP-TOMl.mjs → contract-at-errors-COZAemUl.mjs} +2 -2
  51. package/dist/{contract-at-errors-BxP-TOMl.mjs.map → contract-at-errors-COZAemUl.mjs.map} +1 -1
  52. package/dist/{contract-emit-DxcGl4Uq.mjs → contract-emit-Bv46RAIO.mjs} +3 -3
  53. package/dist/{contract-emit-DxcGl4Uq.mjs.map → contract-emit-Bv46RAIO.mjs.map} +1 -1
  54. package/dist/{contract-emit-D-4jrNve.mjs → contract-emit-DIWImLqS.mjs} +5 -5
  55. package/dist/{contract-emit-D-4jrNve.mjs.map → contract-emit-DIWImLqS.mjs.map} +1 -1
  56. package/dist/{contract-infer-D8uEbJuu.mjs → contract-infer-DpGN9SAj.mjs} +3 -3
  57. package/dist/{contract-infer-D8uEbJuu.mjs.map → contract-infer-DpGN9SAj.mjs.map} +1 -1
  58. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs → contract-space-aggregate-loader-CpNVrBqW.mjs} +63 -5
  59. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs.map → contract-space-aggregate-loader-CpNVrBqW.mjs.map} +1 -1
  60. package/dist/{db-verify-v_vUKXTU.mjs → db-verify-Cq16Obsw.mjs} +4 -4
  61. package/dist/{db-verify-v_vUKXTU.mjs.map → db-verify-Cq16Obsw.mjs.map} +1 -1
  62. package/dist/exports/control-api.d.mts +2 -2
  63. package/dist/exports/control-api.d.mts.map +1 -1
  64. package/dist/exports/control-api.mjs +2 -2
  65. package/dist/exports/index.mjs +1 -1
  66. package/dist/exports/init-output.mjs +1 -1
  67. package/dist/{framework-components-fYXjz_in.mjs → framework-components-BO9VO43s.mjs} +2 -2
  68. package/dist/{framework-components-fYXjz_in.mjs.map → framework-components-BO9VO43s.mjs.map} +1 -1
  69. package/dist/{global-flags-DEHjV8_s.d.mts → global-flags-CV5LhrFg.d.mts} +1 -1
  70. package/dist/{global-flags-DEHjV8_s.d.mts.map → global-flags-CV5LhrFg.d.mts.map} +1 -1
  71. package/dist/{init-Cv9UzWL5.mjs → init-C0rjiQ9I.mjs} +5 -58
  72. package/dist/init-C0rjiQ9I.mjs.map +1 -0
  73. package/dist/{inspect-live-schema-C6ohV_oQ.mjs → inspect-live-schema-CRDKTNcf.mjs} +3 -3
  74. package/dist/{inspect-live-schema-C6ohV_oQ.mjs.map → inspect-live-schema-CRDKTNcf.mjs.map} +1 -1
  75. package/dist/migration-check-BxWlQBOs.mjs +573 -0
  76. package/dist/migration-check-BxWlQBOs.mjs.map +1 -0
  77. package/dist/{migration-command-scaffold-CjvwO6at.mjs → migration-command-scaffold-BDd9abqW.mjs} +3 -3
  78. package/dist/{migration-command-scaffold-CjvwO6at.mjs.map → migration-command-scaffold-BDd9abqW.mjs.map} +1 -1
  79. package/dist/migration-graph-space-render-CeNXh_Wy.mjs +1966 -0
  80. package/dist/migration-graph-space-render-CeNXh_Wy.mjs.map +1 -0
  81. package/dist/migration-list-vJWFuXca.mjs +228 -0
  82. package/dist/migration-list-vJWFuXca.mjs.map +1 -0
  83. package/dist/migration-log-6rcHQSI4.mjs +222 -0
  84. package/dist/migration-log-6rcHQSI4.mjs.map +1 -0
  85. package/dist/migration-path-target-UkxkgXnv.mjs +38 -0
  86. package/dist/migration-path-target-UkxkgXnv.mjs.map +1 -0
  87. package/dist/{migration-plan-9DJ7q7_z.mjs → migration-plan-CHu_erQ5.mjs} +5 -6
  88. package/dist/{migration-plan-9DJ7q7_z.mjs.map → migration-plan-CHu_erQ5.mjs.map} +1 -1
  89. package/dist/migration-status-Bjv91dE7.mjs +444 -0
  90. package/dist/migration-status-Bjv91dE7.mjs.map +1 -0
  91. package/dist/{output-B60Gw5fu.mjs → output-BD61elic.mjs} +1 -1
  92. package/dist/{output-B60Gw5fu.mjs.map → output-BD61elic.mjs.map} +1 -1
  93. package/dist/{ref-advancement-DUZqsue6.mjs → ref-advancement-CJY9zOv7.mjs} +1 -1
  94. package/dist/{ref-advancement-DUZqsue6.mjs.map → ref-advancement-CJY9zOv7.mjs.map} +1 -1
  95. package/dist/schemas-BL33A3i-.d.mts +193 -0
  96. package/dist/schemas-BL33A3i-.d.mts.map +1 -0
  97. package/dist/schemas-DJY2O09F.mjs +112 -0
  98. package/dist/schemas-DJY2O09F.mjs.map +1 -0
  99. package/dist/telemetry-CZkgkR_O.mjs +122 -0
  100. package/dist/telemetry-CZkgkR_O.mjs.map +1 -0
  101. package/dist/{terminal-ui-5Y6mrg93.d.mts → terminal-ui-BgLiAOYi.d.mts} +1 -1
  102. package/dist/{terminal-ui-5Y6mrg93.d.mts.map → terminal-ui-BgLiAOYi.d.mts.map} +1 -1
  103. package/dist/{types-Dt_SfqFm.d.mts → types-qV41eEXH.d.mts} +44 -31
  104. package/dist/types-qV41eEXH.d.mts.map +1 -0
  105. package/dist/{verify-DCA9Sldu.mjs → verify-IilvIk_E.mjs} +2 -2
  106. package/dist/{verify-DCA9Sldu.mjs.map → verify-IilvIk_E.mjs.map} +1 -1
  107. package/package.json +22 -19
  108. package/src/cli.ts +5 -0
  109. package/src/commands/db-update.ts +7 -1
  110. package/src/commands/init/index.ts +6 -35
  111. package/src/commands/init/init.ts +1 -14
  112. package/src/commands/init/inputs.ts +0 -75
  113. package/src/commands/json/schemas.ts +195 -0
  114. package/src/commands/migrate.ts +6 -6
  115. package/src/commands/migration-check.ts +469 -134
  116. package/src/commands/migration-graph.ts +162 -91
  117. package/src/commands/migration-list.ts +69 -39
  118. package/src/commands/migration-log.ts +52 -102
  119. package/src/commands/migration-show.ts +31 -66
  120. package/src/commands/migration-status-overlay.ts +61 -0
  121. package/src/commands/migration-status.ts +453 -1067
  122. package/src/commands/telemetry/index.ts +107 -0
  123. package/src/commands/telemetry/status.ts +67 -0
  124. package/src/control-api/client.ts +20 -9
  125. package/src/control-api/operations/contract-emit.ts +2 -2
  126. package/src/control-api/operations/db-init.ts +3 -3
  127. package/src/control-api/operations/{db-apply.ts → db-run.ts} +37 -10
  128. package/src/control-api/operations/db-update.ts +4 -4
  129. package/src/control-api/operations/{migration-apply.ts → migrate.ts} +32 -24
  130. package/src/control-api/operations/{apply.ts → run-migration.ts} +33 -27
  131. package/src/control-api/types.ts +46 -29
  132. package/src/utils/cli-errors.ts +70 -2
  133. package/src/utils/formatters/errors.ts +11 -0
  134. package/src/utils/formatters/migration-graph-lane-colors.ts +194 -0
  135. package/src/utils/formatters/migration-graph-layout.ts +51 -7
  136. package/src/utils/formatters/migration-graph-rows.ts +128 -15
  137. package/src/utils/formatters/migration-graph-space-render.ts +138 -0
  138. package/src/utils/formatters/migration-graph-tree-render.ts +405 -77
  139. package/src/utils/formatters/migration-list-data-column.ts +4 -91
  140. package/src/utils/formatters/migration-list-graph-topology.ts +72 -94
  141. package/src/utils/formatters/migration-list-render.ts +123 -71
  142. package/src/utils/formatters/migration-list-styler.ts +48 -5
  143. package/src/utils/formatters/migration-list-types.ts +5 -21
  144. package/src/utils/formatters/migration-log-table.ts +205 -0
  145. package/src/utils/formatters/migrations.ts +33 -11
  146. package/src/utils/global-flags.ts +35 -0
  147. package/src/utils/integrity-violation-to-check-failure.ts +28 -19
  148. package/src/utils/legend.ts +38 -0
  149. package/src/utils/migration-path-target.ts +60 -0
  150. package/src/utils/telemetry.ts +68 -32
  151. package/dist/client-KgJorIvG.mjs.map +0 -1
  152. package/dist/command-helpers-Bbw1GbwL.mjs.map +0 -1
  153. package/dist/commands/migration-list.mjs.map +0 -1
  154. package/dist/commands/migration-log.mjs.map +0 -1
  155. package/dist/commands/migration-status.mjs.map +0 -1
  156. package/dist/extension-pack-inputs-IDvjRCi3.mjs +0 -62
  157. package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +0 -1
  158. package/dist/graph-render-rFAqZujX.mjs +0 -1081
  159. package/dist/graph-render-rFAqZujX.mjs.map +0 -1
  160. package/dist/init-Cv9UzWL5.mjs.map +0 -1
  161. package/dist/migration-check-BiBJoYYW.mjs +0 -341
  162. package/dist/migration-check-BiBJoYYW.mjs.map +0 -1
  163. package/dist/migration-graph-D7DVUElV.mjs +0 -1232
  164. package/dist/migration-graph-D7DVUElV.mjs.map +0 -1
  165. package/dist/migration-list-styler-BRwF4-gy.mjs +0 -399
  166. package/dist/migration-list-styler-BRwF4-gy.mjs.map +0 -1
  167. package/dist/migration-types-D2FW63pr.d.mts +0 -15
  168. package/dist/migration-types-D2FW63pr.d.mts.map +0 -1
  169. package/dist/migrations-Cv2jxNNK.mjs +0 -228
  170. package/dist/migrations-Cv2jxNNK.mjs.map +0 -1
  171. package/dist/types-Dt_SfqFm.d.mts.map +0 -1
  172. package/src/utils/formatters/graph-migration-mapper.ts +0 -235
  173. package/src/utils/formatters/graph-render.ts +0 -1323
  174. package/src/utils/formatters/graph-types.ts +0 -120
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":["CLI_VERSION","packageJson.version"],"sources":["../package.json","../src/utils/telemetry.ts","../src/commands/init/templates/code-templates.ts","../src/commands/init/index.ts","../src/utils/suggest-command.ts","../src/cli.ts"],"sourcesContent":["","import { fileURLToPath } from 'node:url';\nimport {\n type CommanderOptionShape,\n type CommanderResultShape,\n readUserConfig,\n resolveGating,\n runTelemetry,\n type TelemetryRunOutcome,\n type UserConfig,\n} from '@prisma-next/cli-telemetry';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Command } from 'commander';\nimport { version as CLI_VERSION } from '../../package.json' with { type: 'json' };\nimport { isCI } from './is-ci';\n\ntype TelemetryGate =\n | { readonly enabled: true; readonly userConfig: UserConfig }\n | { readonly enabled: false; readonly outcome: TelemetryRunOutcome };\n\n/**\n * Resolve the commander command path from a leaf `Command`, walking up\n * the parent chain. Result is rooted at the program name and ends at\n * the leaf — `['prisma-next', 'migration', 'new']` for\n * `prisma-next migration new …`.\n */\nfunction commandPathFor(actionCommand: Command): string[] {\n const path: string[] = [];\n let cursor: Command | null = actionCommand;\n while (cursor !== null) {\n path.unshift(cursor.name());\n cursor = cursor.parent;\n }\n return path;\n}\n\nfunction commanderOptionSnapshots(actionCommand: Command): CommanderOptionShape[] {\n return actionCommand.options.map((option) => {\n const attributeName = option.attributeName();\n return {\n attributeName,\n longName: option.long ?? null,\n source: actionCommand.getOptionValueSource(attributeName) ?? null,\n };\n });\n}\n\n/**\n * Project commander's leaf `Command` into the wire-shape snapshot the\n * telemetry sanitiser consumes. Pure projection — no env, no I/O.\n */\nexport function commanderSnapshotForTelemetry(actionCommand: Command): CommanderResultShape {\n return {\n commandPath: commandPathFor(actionCommand),\n positionalArgs: actionCommand.args,\n options: commanderOptionSnapshots(actionCommand),\n };\n}\n\nfunction resolveTelemetryGate(): TelemetryGate {\n if (isCI()) {\n return { enabled: false, outcome: { spawned: false, reason: 'ci' } };\n }\n const userConfig = readUserConfig();\n const gating = resolveGating({ env: process.env, config: userConfig });\n if (!gating.enabled) {\n return { enabled: false, outcome: { spawned: false, reason: 'gated-off' } };\n }\n return { enabled: true, userConfig };\n}\n\n/**\n * Path to the compiled sender script inside `@prisma-next/cli-telemetry`'s\n * `dist/`. Resolved off this module's `import.meta.url` via the package\n * specifier `@prisma-next/cli-telemetry/sender`, so the consumer pays\n * no attention to internal package layout.\n */\nfunction senderPath(): string {\n return fileURLToPath(new URL(import.meta.resolve('@prisma-next/cli-telemetry/sender')));\n}\n\nfunction fireTelemetry(\n actionCommand: Command,\n userConfig: UserConfig,\n overrides: { readonly databaseTarget?: string } = {},\n): TelemetryRunOutcome {\n return runTelemetry({\n command: commanderSnapshotForTelemetry(actionCommand),\n version: CLI_VERSION,\n projectRoot: process.cwd(),\n senderPath: senderPath(),\n isCI: isCI(),\n env: process.env,\n userConfig,\n ...ifDefined('databaseTarget', overrides.databaseTarget),\n });\n}\n\n/**\n * preAction-stage entry point. Synchronous by construction: resolve\n * env/CI/user-consent gates (cheap, all in-memory and a single tiny\n * user-config read), then — only when enabled — `fork()` the detached\n * sender script. The forked child loads `prisma-next.config.*` via\n * c12 on its own (see `loadProjectConfig` in cli-telemetry); the\n * parent does no project-config I/O on the command's hot path.\n *\n * Privacy invariant: gate resolution always happens before any project\n * config touches disk. The child loading user TS code is acceptable\n * only because it's gated behind the same resolved-enabled signal.\n */\nexport function fireTelemetryFromPreAction(actionCommand: Command): TelemetryRunOutcome {\n const gate = resolveTelemetryGate();\n if (!gate.enabled) {\n return gate.outcome;\n }\n return fireTelemetry(actionCommand, gate.userConfig);\n}\n\n/**\n * Manual one-shot telemetry path for the first `init` run where the user\n * explicitly answers Yes to the consent prompt. The preAction hook for\n * that same run has already resolved before consent existed, so it is\n * default-off. After consent is persisted, `runInit` calls this helper\n * exactly for that first affirmative answer; subsequent init runs skip\n * it because the prompt is not shown again.\n *\n * The child's c12 load would return `databaseTarget: null` for this\n * specific invocation because `prisma-next.config.*` is not yet on\n * disk (init writes it later in the same run). To preserve the\n * prompt-chosen target in the first-init telemetry event, this\n * helper forwards the value as a parent-side IPC override on\n * `ParentToSenderPayload.databaseTarget` — the child consults the\n * override first and falls back to its c12 result when absent.\n */\nexport function fireTelemetryAfterInitConsent(\n actionCommand: Command,\n inputs: { readonly databaseTarget: string },\n): TelemetryRunOutcome {\n return fireTelemetry(actionCommand, readUserConfig(), {\n databaseTarget: inputs.databaseTarget,\n });\n}\n","import { DEFAULT_CONTRACT_SOURCE_DIR } from '@prisma-next/config/config-types';\n\nexport type TargetId = 'postgres' | 'mongo';\nexport type AuthoringId = 'psl' | 'typescript';\n\nexport function targetPackageName(target: TargetId): string {\n return target === 'postgres' ? '@prisma-next/postgres' : '@prisma-next/mongo';\n}\n\nexport function targetLabel(target: TargetId): string {\n return target === 'postgres' ? 'PostgreSQL' : 'MongoDB';\n}\n\nexport function defaultSchemaPath(authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.ts`;\n }\n return `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.prisma`;\n}\n\nexport function starterSchema(target: TargetId, authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return target === 'mongo' ? starterSchemaTsMongo() : starterSchemaTsPostgres();\n }\n return target === 'mongo' ? starterSchemaPslMongo() : starterSchemaPslPostgres();\n}\n\n/**\n * Renders a short authoring-appropriate schema sample (FR5.1) for embedding\n * in `prisma-next.md`. Returns a complete fenced markdown code block.\n *\n * The sample intentionally shows just one model: it's illustrative, not\n * a substitute for the full scaffolded contract file. The TS samples use\n * the same outer shape as `starterSchemaTs*` (FR5.3) so a user reading\n * the doc and the file side-by-side sees the same structure.\n */\nexport function schemaSample(target: TargetId, authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return target === 'mongo' ? schemaSampleTsMongo() : schemaSampleTsPostgres();\n }\n return target === 'mongo' ? schemaSamplePslMongo() : schemaSamplePslPostgres();\n}\n\nfunction schemaSamplePslPostgres(): string {\n return `\\`\\`\\`prisma\nmodel User {\n id Int @id @default(autoincrement())\n email String @unique\n username String?\n name String?\n}\n\\`\\`\\``;\n}\n\nfunction schemaSamplePslMongo(): string {\n return `\\`\\`\\`prisma\nmodel User {\n id ObjectId @id @map(\"_id\")\n email String @unique\n username String?\n name String?\n @@map(\"users\")\n}\n\\`\\`\\``;\n}\n\nfunction schemaSampleTsPostgres(): string {\n return `\\`\\`\\`typescript\nimport { defineContract } from '@prisma-next/postgres/contract-builder';\n\nexport const contract = defineContract(\n {},\n ({ field, model }) => ({\n models: {\n User: model('User', {\n fields: {\n id: field.id.uuidv7(),\n email: field.text().unique(),\n username: field.text().optional(),\n name: field.text().optional(),\n },\n }),\n },\n }),\n);\n\\`\\`\\``;\n}\n\nfunction schemaSampleTsMongo(): string {\n return `\\`\\`\\`typescript\nimport { defineContract } from '@prisma-next/mongo/contract-builder';\n\nexport const contract = defineContract(\n {},\n ({ field, model }) => ({\n models: {\n User: model('User', {\n collection: 'users',\n fields: {\n _id: field.objectId(),\n email: field.string(),\n username: field.string().optional(),\n name: field.string().optional(),\n },\n }),\n },\n }),\n);\n\\`\\`\\``;\n}\n\nfunction starterSchemaPslPostgres(): string {\n return `// use prisma-next\n\nmodel User {\n id Int @id @default(autoincrement())\n email String @unique\n username String?\n name String?\n posts Post[]\n createdAt DateTime @default(now())\n updatedAt temporal.updatedAt()\n}\n\nmodel Post {\n id Int @id @default(autoincrement())\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId Int\n createdAt DateTime @default(now())\n updatedAt temporal.updatedAt()\n}\n`;\n}\n\nfunction starterSchemaPslMongo(): string {\n return `// use prisma-next\n\nmodel User {\n id ObjectId @id @map(\"_id\")\n email String @unique\n username String?\n name String?\n posts Post[]\n @@map(\"users\")\n}\n\nmodel Post {\n id ObjectId @id @map(\"_id\")\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId ObjectId\n @@map(\"posts\")\n}\n`;\n}\n\nfunction starterSchemaTsPostgres(): string {\n return `import { defineContract } from '@prisma-next/postgres/contract-builder';\n\nexport const contract = defineContract(\n {},\n ({ field, model, rel }) => ({\n models: {\n User: model('User', {\n fields: {\n id: field.id.uuidv7(),\n email: field.text().unique(),\n username: field.text().optional(),\n name: field.text().optional(),\n createdAt: field.temporal.createdAt(),\n updatedAt: field.temporal.updatedAt(),\n },\n relations: {\n posts: rel.hasMany('Post', { by: 'authorId' }),\n },\n }),\n\n Post: model('Post', {\n fields: {\n id: field.id.uuidv7(),\n title: field.text(),\n content: field.text().optional(),\n authorId: field.uuid(),\n createdAt: field.temporal.createdAt(),\n updatedAt: field.temporal.updatedAt(),\n },\n relations: {\n author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),\n },\n }),\n },\n }),\n);\n`;\n}\n\nfunction starterSchemaTsMongo(): string {\n return `import { defineContract } from '@prisma-next/mongo/contract-builder';\n\nexport const contract = defineContract(\n {},\n ({ field, model, rel }) => ({\n models: {\n User: model('User', {\n collection: 'users',\n fields: {\n _id: field.objectId(),\n email: field.string(),\n username: field.string().optional(),\n name: field.string().optional(),\n },\n relations: {\n posts: rel.hasMany('Post', { from: '_id', to: 'authorId' }),\n },\n }),\n\n Post: model('Post', {\n collection: 'posts',\n fields: {\n _id: field.objectId(),\n title: field.string(),\n content: field.string().optional(),\n authorId: field.objectId(),\n },\n relations: {\n author: rel.belongsTo('User', { from: 'authorId', to: '_id' }),\n },\n }),\n },\n }),\n);\n`;\n}\n\nexport function configFile(target: TargetId, contractPath: string): string {\n const pkg = targetPackageName(target);\n return `import 'dotenv/config';\nimport { defineConfig } from '${pkg}/config';\n\nexport default defineConfig({\n contract: ${JSON.stringify(contractPath)},\n db: {\n connection: process.env['DATABASE_URL']!,\n },\n});\n`;\n}\n\nexport function dbFile(target: TargetId): string {\n if (target === 'postgres') {\n return `import postgres from '@prisma-next/postgres/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = postgres<Contract>({\n contractJson,\n url: process.env['DATABASE_URL']!,\n});\n`;\n }\n\n return `import mongo from '@prisma-next/mongo/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = mongo<Contract>({\n contractJson,\n url: process.env['DATABASE_URL']!,\n});\n`;\n}\n","import { Command } from 'commander';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../../utils/command-helpers';\nimport { type CommonCommandOptions, parseGlobalFlagsOrExit } from '../../utils/global-flags';\nimport { fireTelemetryAfterInitConsent } from '../../utils/telemetry';\nimport {\n INIT_EXIT_EMIT_FAILED,\n INIT_EXIT_INSTALL_FAILED,\n INIT_EXIT_INTERNAL_ERROR,\n INIT_EXIT_OK,\n INIT_EXIT_PRECONDITION,\n INIT_EXIT_SKILL_INSTALL_FAILED,\n INIT_EXIT_USER_ABORTED,\n} from './exit-codes';\nimport { defaultSchemaPath } from './templates/code-templates';\n\n/**\n * Commander.js parsed options for `init`. The init-specific options live\n * alongside the inherited `CommonCommandOptions` global flags.\n *\n * `target` and `authoring` are typed as plain `string` here because\n * Commander.js does not enforce enums at parse time — the validation /\n * normalisation happens in `inputs.ts::resolveInitInputs`, which can\n * raise a structured `errorInitInvalidFlagValue` with the full set of\n * allowed values.\n */\ninterface InitCommandOptions extends CommonCommandOptions {\n readonly target?: string;\n readonly authoring?: string;\n readonly schemaPath?: string;\n readonly force?: boolean;\n readonly writeEnv?: boolean;\n readonly probeDb?: boolean;\n readonly strictProbe?: boolean;\n readonly install?: boolean;\n readonly skill?: boolean;\n}\n\nexport function createInitCommand(): Command {\n const command = new Command('init');\n setCommandDescriptions(\n command,\n 'Initialize a new Prisma Next project',\n 'Scaffolds config, schema, and runtime files, installs dependencies,\\n' +\n 'and emits the contract. Gets you from zero to typed queries in one step.\\n' +\n '\\n' +\n 'Run interactively for a guided experience, or supply --target / --authoring\\n' +\n 'and --yes for a fully scriptable run (CI, AI coding agents, automation).\\n' +\n '\\n' +\n 'Exit codes (see CLI Style Guide § Exit Codes):\\n' +\n ` ${INIT_EXIT_OK} OK Init succeeded.\\n` +\n ` ${INIT_EXIT_INTERNAL_ERROR} INTERNAL_ERROR Unexpected bug in prisma-next (please report).\\n` +\n ` ${INIT_EXIT_PRECONDITION} PRECONDITION Bad flags / missing prerequisite (e.g. no package.json).\\n` +\n ` ${INIT_EXIT_USER_ABORTED} USER_ABORTED User cancelled an interactive prompt.\\n` +\n ` ${INIT_EXIT_INSTALL_FAILED} INSTALL_FAILED Dependency installation failed (init-specific).\\n` +\n ` ${INIT_EXIT_EMIT_FAILED} EMIT_FAILED \\`contract emit\\` failed after install (init-specific).\\n` +\n ` ${INIT_EXIT_SKILL_INSTALL_FAILED} SKILL_INSTALL_FAILED Agent-skill install failed (re-run with --no-skill to skip).`,\n );\n setCommandExamples(command, [\n 'prisma-next init',\n 'prisma-next init --yes --target postgres --authoring psl',\n 'prisma-next init --yes --target mongodb --authoring typescript --json',\n 'prisma-next init --yes --force --target postgres --authoring psl # overwrite an existing scaffold',\n 'prisma-next init --no-install # skip pnpm/npm install + emit',\n 'prisma-next init --no-skill # skip the skills install (air-gapped / restricted env)',\n ]);\n\n return addGlobalOptions(command)\n .option('--target <db>', 'Database target: postgres or mongodb')\n .option('--authoring <style>', 'Schema authoring style: psl or typescript')\n .option(\n '--schema-path <path>',\n `Where to write the starter schema (default: ${defaultSchemaPath('psl')})`,\n )\n .option('--force', 'Overwrite an existing scaffold without prompting')\n .option(\n '--write-env',\n 'Write a .env file from .env.example (gitignored; default: only .env.example)',\n )\n .option(\n '--probe-db',\n 'Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)',\n )\n .option(\n '--strict-probe',\n 'Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)',\n )\n .option('--no-install', 'Skip dependency installation and contract emission')\n .option(\n '--no-skill',\n 'Skip Prisma Next skills install (air-gapped CI, restricted registries, etc.)',\n )\n .action(async (options: InitCommandOptions, actionCommand: Command) => {\n const { runInit } = await import('./init');\n const flags = parseGlobalFlagsOrExit(options);\n const canPrompt = deriveCanPrompt({\n flagsInteractive: flags.interactive,\n optionInteractive: options.interactive,\n stdinIsTTY: Boolean(process.stdin.isTTY),\n });\n const exitCode = await runInit(process.cwd(), {\n options,\n flags,\n canPrompt,\n afterFirstTelemetryConsent: (inputs) => {\n fireTelemetryAfterInitConsent(actionCommand, { databaseTarget: inputs.target });\n },\n });\n process.exit(exitCode);\n });\n}\n\n/**\n * Bridges the action handler's two TTY checks (stdout via `flags`, stdin\n * via `process.stdin.isTTY`) into the `canPrompt` boolean `runInit`\n * consumes.\n *\n * Per the [Style Guide § Interactivity](../../../../../../../docs/CLI%20Style%20Guide.md#interactivity):\n *\n * - `flags.interactive` governs *decoration* (TerminalUI, intro/outro,\n * spinners) and is derived from stdout-TTY by `parseGlobalFlags`,\n * honouring `--interactive` / `--no-interactive`.\n * - Prompting additionally requires a stdin TTY — closing stdin is a\n * common signal in CI / agent environments even when stdout stays\n * attached.\n * - `--interactive` is the explicit override: when the user passes it,\n * we honour it (e.g. testing flows where stdin is stubbed).\n *\n * Exported so callers and tests can derive the same value without\n * touching `process` globals.\n */\nexport function deriveCanPrompt(opts: {\n readonly flagsInteractive: boolean | undefined;\n readonly optionInteractive: boolean | undefined;\n readonly stdinIsTTY: boolean;\n}): boolean {\n if (opts.optionInteractive === true) return true;\n if (opts.flagsInteractive === false) return false;\n return opts.stdinIsTTY;\n}\n","import { distance } from 'closest-match';\n\n/**\n * Suggests similar command names for a mistyped input.\n *\n * Uses Levenshtein distance to find close matches. Only suggests commands\n * within a reasonable distance threshold (40% of the input length, minimum 2).\n * Returns up to 3 suggestions in case of ties.\n *\n * @returns Array of suggested command names (empty if nothing is close enough).\n */\nexport function suggestCommands(input: string, candidates: readonly string[]): string[] {\n if (candidates.length === 0) return [];\n\n // Threshold: at most 40% of the input length (min 2) to avoid absurd suggestions\n const maxDistance = Math.max(2, Math.ceil(input.length * 0.4));\n\n const scored = candidates\n .map((name) => ({ name, dist: distance(input, name) }))\n .filter((entry) => entry.dist <= maxDistance)\n .sort((a, b) => a.dist - b.dist);\n\n if (scored.length === 0) return [];\n\n // Take the best distance, then include ties (up to 3)\n const bestDist = scored[0]!.dist;\n return scored\n .filter((entry) => entry.dist === bestDist)\n .slice(0, 3)\n .map((entry) => entry.name);\n}\n","import { Command } from 'commander';\nimport packageJson from '../package.json' with { type: 'json' };\nimport { createContractEmitCommand } from './commands/contract-emit';\nimport { createContractInferCommand } from './commands/contract-infer';\nimport { createInitCommand } from './commands/init';\nimport { installShutdownHandlers } from './utils/shutdown';\n\n// Install SIGINT/SIGTERM handlers before anything else\ninstallShutdownHandlers();\n\nimport { createDbInitCommand } from './commands/db-init';\nimport { createDbSchemaCommand } from './commands/db-schema';\nimport { createDbSignCommand } from './commands/db-sign';\nimport { createDbUpdateCommand } from './commands/db-update';\nimport { createDbVerifyCommand } from './commands/db-verify';\nimport { createMigrateCommand } from './commands/migrate';\nimport { createMigrationCheckCommand } from './commands/migration-check';\nimport { createMigrationGraphCommand } from './commands/migration-graph';\nimport { createMigrationListCommand } from './commands/migration-list';\nimport { createMigrationLogCommand } from './commands/migration-log';\nimport { createMigrationNewCommand } from './commands/migration-new';\nimport { createMigrationPlanCommand } from './commands/migration-plan';\nimport { createMigrationShowCommand } from './commands/migration-show';\nimport { createMigrationStatusCommand } from './commands/migration-status';\nimport { createRefCommand } from './commands/ref';\nimport { setCommandDescriptions } from './utils/command-helpers';\nimport { formatCommandHelp, formatRootHelp } from './utils/formatters/help';\nimport { parseGlobalFlags } from './utils/global-flags';\nimport { suggestCommands } from './utils/suggest-command';\nimport { fireTelemetryFromPreAction } from './utils/telemetry';\n\n/**\n * Lookup table mapping removed subcommands to their replacement verbs.\n * Keyed by `<parent>:<subcommand>` (e.g. `migration:apply`).\n * The handler consults this before falling back to the fuzzy suggest engine.\n */\nconst removedVerbRedirects: Record<string, string> = {\n 'migration:apply': 'Use `prisma-next migrate --to <contract>` instead.',\n 'migration:ref': 'Use `prisma-next ref set|list|delete` instead.',\n};\n\n/**\n * Removed flags on specific subcommands. Keyed by `<parent>:<sub>:<flag>`.\n * Checked during the pre-parse argv scan before commander sees the flags.\n */\nconst removedFlagRedirects: Record<string, string> = {\n 'migration:status:graph': 'Use `prisma-next migration graph` to view the migration graph.',\n 'migration:status:all':\n 'Use `prisma-next migration log --db <url>` to view the full execution history.',\n 'migration:status:limit':\n 'Use `prisma-next migration log --db <url>` to view the full execution history.',\n 'migration:status:ref': 'Use `--to <contract>` instead of `--ref`.',\n};\n\n/**\n * Formats the \"Did you mean ...?\" hint for an unknown command.\n */\nfunction formatSuggestion(input: string, candidates: readonly string[]): string {\n const suggestions = suggestCommands(\n input,\n candidates.map((c) => c),\n );\n if (suggestions.length === 0) return '';\n if (suggestions.length === 1) return `\\nDid you mean ${suggestions[0]}?\\n`;\n return `\\nDid you mean one of these?\\n${suggestions.map((s) => ` ${s}`).join('\\n')}\\n`;\n}\n\nconst program = new Command();\n\nprogram.name('prisma-next').description('Prisma Next CLI').version(packageJson.version);\n\n// Telemetry hook — fires at command start, before the action body\n// runs. Synchronous by construction: `fireTelemetryFromPreAction`\n// resolves gates (cheap), then `fork()`s the detached sender. The\n// fork is enqueued before the action body runs at all, so the child\n// survives even when the action throws synchronously. The try/catch\n// is defence-in-depth — `runTelemetry` already swallows every failure\n// mode internally and returns an outcome instead of throwing.\nprogram.hook('preAction', (_thisCommand, actionCommand) => {\n try {\n fireTelemetryFromPreAction(actionCommand);\n } catch {\n // defence-in-depth — runTelemetry already swallows internally.\n }\n});\n\n// Override version option description to match capitalization style\nconst versionOption = program.options.find((opt) => opt.flags.includes('--version'));\nif (versionOption) {\n versionOption.description = 'Output the version number';\n}\n\nprogram.configureOutput({\n writeErr: () => {\n // Suppress all default error output - we handle errors in exitOverride\n },\n writeOut: (str) => {\n // Commander routes explicitly-requested `--help` (success-path help)\n // through writeOut; per the Style Guide § Output Conventions rule 8,\n // user-requested help is data and goes to stdout. Error-path help\n // (e.g. usage shown after an unknown command) goes through writeErr,\n // which stays suppressed because we render that ourselves with the\n // matching error envelope.\n //\n // Explicit `--version` is short-circuited before `program.parse()`\n // (see the argv pre-scan at the bottom of this file), so it does not\n // reach this writer.\n process.stdout.write(str);\n },\n});\n\n// Customize root help output to use our styled format\nconst rootHelpFormatter = (cmd: Command) => {\n const flags = parseGlobalFlags({});\n return formatRootHelp({ program: cmd, flags });\n};\n\nprogram.configureHelp({\n formatHelp: rootHelpFormatter,\n subcommandDescription: () => '',\n});\n\n// Override exit to handle unhandled errors (fail fast cases)\n// Commands handle structured errors themselves via process.exit()\nprogram.exitOverride((err) => {\n if (err) {\n const errorCode = (err as { code?: string }).code;\n const errorMessage = String(err.message ?? '');\n const errorName = err.name ?? '';\n\n // Unknown command/argument → exit 2 (CLI usage error)\n const isUnknownCommandError =\n errorCode === 'commander.unknownCommand' ||\n errorCode === 'commander.unknownArgument' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('unknown command') || errorMessage.includes('unknown argument')));\n if (isUnknownCommandError) {\n const flags = parseGlobalFlags({});\n const match = errorMessage.match(/unknown command ['\"]([^'\"]+)['\"]/);\n const commandName = match ? match[1] : process.argv[3] || process.argv[2] || 'unknown';\n\n const firstArg = process.argv[2];\n const parentCommand = firstArg\n ? program.commands.find((cmd) => cmd.name() === firstArg)\n : undefined;\n\n if (parentCommand && commandName !== firstArg) {\n const subNames = parentCommand.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, subNames)}\\n`,\n );\n const helpText = formatCommandHelp({ command: parentCommand, flags });\n process.stderr.write(`${helpText}\\n`);\n } else {\n const topNames = program.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, topNames)}\\n`,\n );\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n }\n process.exit(2);\n return;\n }\n\n // Help requests → exit 0\n const isHelpError =\n errorCode === 'commander.help' ||\n errorCode === 'commander.helpDisplayed' ||\n errorCode === 'outputHelp' ||\n errorMessage === '(outputHelp)' ||\n errorMessage.includes('outputHelp') ||\n (errorName === 'CommanderError' && errorMessage.includes('outputHelp'));\n if (isHelpError) {\n process.exit(0);\n return;\n }\n\n // Missing required arguments → exit 2 (CLI usage error)\n const isMissingArgumentError =\n errorCode === 'commander.missingArgument' ||\n errorCode === 'commander.missingMandatoryOptionValue' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('missing') || errorMessage.includes('required')));\n if (isMissingArgumentError) {\n process.exit(2);\n return;\n }\n\n // Unhandled error → exit 1\n process.stderr.write(`Unhandled error: ${err.message}\\n`);\n if (err.stack) {\n process.stderr.write(`${err.stack}\\n`);\n }\n process.exit(1);\n }\n process.exit(0);\n});\n\n// Register contract subcommand\nconst contractCommand = new Command('contract');\nsetCommandDescriptions(\n contractCommand,\n 'Contract management commands',\n 'Define and emit your application data contract. The contract describes your schema as a\\n' +\n 'declarative data structure that can be signed and verified against your database.',\n);\ncontractCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add emit subcommand to contract\nconst contractEmitCommand = createContractEmitCommand();\ncontractCommand.addCommand(contractEmitCommand);\n\n// Add infer subcommand to contract\nconst contractInferCommand = createContractInferCommand();\ncontractCommand.addCommand(contractInferCommand);\n\n// Register db subcommand\nconst dbCommand = new Command('db');\nsetCommandDescriptions(\n dbCommand,\n 'Database management commands',\n 'Verify and sign your database with your contract. Ensure your database schema matches\\n' +\n 'your contract, and sign it to record the contract hash for future verification.',\n);\ndbCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add verify subcommand to db\nconst dbVerifyCommand = createDbVerifyCommand();\ndbCommand.addCommand(dbVerifyCommand);\n\n// Add init subcommand to db\nconst dbInitCommand = createDbInitCommand();\ndbCommand.addCommand(dbInitCommand);\n\n// Add update subcommand to db\nconst dbUpdateCommand = createDbUpdateCommand();\ndbCommand.addCommand(dbUpdateCommand);\n\n// Add schema subcommand to db\nconst dbSchemaCommand = createDbSchemaCommand();\ndbCommand.addCommand(dbSchemaCommand);\n\n// Add sign subcommand to db\nconst dbSignCommand = createDbSignCommand();\ndbCommand.addCommand(dbSignCommand);\n\n// Register migration subcommand\nconst migrationCommand = new Command('migration');\nsetCommandDescriptions(\n migrationCommand,\n 'On-disk migration management commands',\n 'Plan, apply, and scaffold on-disk migration packages. Migrations are\\n' +\n 'contract-to-contract edges stored as versioned directories under migrations/.',\n);\nmigrationCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\nconst migrationPlanCommand = createMigrationPlanCommand();\nmigrationCommand.addCommand(migrationPlanCommand);\n\nconst migrationNewCommand = createMigrationNewCommand();\nmigrationCommand.addCommand(migrationNewCommand);\n\nconst migrationShowCommand = createMigrationShowCommand();\nmigrationCommand.addCommand(migrationShowCommand);\n\nconst migrationStatusCommand = createMigrationStatusCommand();\nmigrationCommand.addCommand(migrationStatusCommand);\n\nconst migrationLogCommand = createMigrationLogCommand();\nmigrationCommand.addCommand(migrationLogCommand);\n\nconst migrationListCommand = createMigrationListCommand();\nmigrationCommand.addCommand(migrationListCommand);\n\nconst migrationGraphCommand = createMigrationGraphCommand();\nmigrationCommand.addCommand(migrationGraphCommand);\n\nconst migrationCheckCommand = createMigrationCheckCommand();\nmigrationCommand.addCommand(migrationCheckCommand);\n\n// Top-level migrate command\nconst migrateCommand = createMigrateCommand();\n\n// Top-level ref command (replaces `migration ref`)\nconst refCommand = createRefCommand();\n\n// Top-level init command\nconst initCommand = createInitCommand();\n\n// Register top-level commands in the order the spec's intended-surface\n// diagram lists them: verbs (init, migrate) first, then subject\n// namespaces (contract, db, migration, ref). The order shows up in\n// `prisma-next --help` and is the first thing a new user sees, so it\n// matches the order spec.md uses to introduce the surface.\nprogram.addCommand(initCommand);\nprogram.addCommand(migrateCommand);\nprogram.addCommand(contractCommand);\nprogram.addCommand(dbCommand);\nprogram.addCommand(migrationCommand);\nprogram.addCommand(refCommand);\n\n// Test-only hidden command used by `cli-telemetry`'s `cli-e2e.test.ts`\n// to verify that telemetry still lands when a CLI command crashes\n// mid-execution. The preAction hook is synchronous and `fork()`s the\n// detached sender before this action body runs; the small sleep\n// gives the IPC `child.send()` a tick to flush before the throw\n// triggers commander's `exitOverride` and `process.exit(1)`. Hidden\n// from help; underscore prefix marks it as internal. Doesn't depend\n// on any project state, so it runs in any tempdir.\n//\n// Gated behind `PRISMA_NEXT_ENABLE_TEST_COMMANDS=1` so the command is\n// not even registered (and therefore not invocable) in shipped\n// binaries. `hidden: true` only filters the help output; without this\n// env gate the command would still be callable from production. The\n// e2e suite sets the env var when it spawns the CLI.\nconst TELEMETRY_CRASH_TEST_SLEEP_MS = 200;\nif (process.env['PRISMA_NEXT_ENABLE_TEST_COMMANDS'] === '1') {\n const telemetryCrashTestCommand = new Command('__telemetry-crash-test')\n .description('Internal: deliberately throw for the telemetry e2e suite.')\n .action(async () => {\n await new Promise((settle) => setTimeout(settle, TELEMETRY_CRASH_TEST_SLEEP_MS));\n throw new Error('__telemetry-crash-test: intentional crash for e2e coverage');\n });\n telemetryCrashTestCommand.configureHelp({ visibleCommands: () => [] });\n program.addCommand(telemetryCrashTestCommand, { hidden: true });\n}\n\n// Create help command\nconst helpCommand = new Command('help')\n .description('Show usage instructions')\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n // The `help` command was invoked explicitly: help is the data the\n // caller asked for. Per Style Guide § Output Conventions rule 8,\n // explicit help goes to stdout with exit code 0.\n process.stdout.write(`${helpText}\\n`);\n process.exit(0);\n });\n\nprogram.addCommand(helpCommand);\n\n// Set help as the default action when no command is provided. The user\n// did not invoke `--help`; we are voluntarily showing usage to help them\n// recover from an underspecified invocation, so the help text is\n// decoration around an implicit \"what did you want me to do?\" and goes\n// to stderr (Style Guide § Output Conventions rule 8).\n//\n// FOLLOW-UP: the exit code here is 0 today, but a no-arg invocation is\n// arguably a usage error (PRECONDITION → exit 2) for consistency with\n// the unknown-command path. Out of scope for the explicit-help routing\n// work; revisit when tightening exit-code semantics across the CLI.\nprogram.action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(0);\n});\n\n// Check if a command was invoked with no arguments (just the command name)\n// or if an unrecognized command was provided\nconst args = process.argv.slice(2);\nif (args.length > 0) {\n const commandName = args[0];\n // Handle version option explicitly since we suppress default output\n if (commandName === '--version' || commandName === '-V') {\n // Version is data → stdout\n process.stdout.write(`${program.version()}\\n`);\n process.exit(0);\n }\n // Skip command check for global options like --help, -h\n const isGlobalOption = commandName === '--help' || commandName === '-h';\n if (!isGlobalOption) {\n // Check if this is a recognized command\n const command = program.commands.find((cmd) => cmd.name() === commandName);\n\n if (!command) {\n // Unrecognized command → exit 2 (CLI usage error)\n const flags = parseGlobalFlags({});\n const topNames = program.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, topNames)}\\n`,\n );\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(2);\n } else if (command.commands.length > 0 && args.length >= 2) {\n const subcommandName = args[1];\n const redirectKey = `${commandName}:${subcommandName}`;\n const redirect = removedVerbRedirects[redirectKey];\n if (redirect) {\n process.stderr.write(`Unknown command: ${subcommandName}\\n${redirect}\\n`);\n process.exit(2);\n }\n for (let i = 2; i < args.length; i++) {\n const arg = args[i]!;\n if (!arg.startsWith('--')) continue;\n const flagName = arg.slice(2);\n const flagKey = `${commandName}:${subcommandName}:${flagName}`;\n const flagRedirect = removedFlagRedirects[flagKey];\n if (flagRedirect) {\n process.stderr.write(`Unknown option: ${arg}\\n${flagRedirect}\\n`);\n process.exit(2);\n }\n }\n }\n\n if (command.commands.length > 0 && args.length === 1) {\n // Parent command called with no subcommand. Same shape as the\n // no-args case above: the user did not request help, we are\n // voluntarily rendering it as decoration around an underspecified\n // invocation, so it goes to stderr per Style Guide § Output\n // Conventions rule 8. Exit code 0 today; the FOLLOW-UP note on\n // `program.action` applies here too (arguably should be 2).\n const flags = parseGlobalFlags({});\n const helpText = formatCommandHelp({ command, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(0);\n }\n }\n}\n\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":["CLI_VERSION","packageJson.version"],"sources":["../package.json","../src/commands/init/templates/code-templates.ts","../src/commands/init/index.ts","../src/utils/suggest-command.ts","../src/utils/telemetry.ts","../src/cli.ts"],"sourcesContent":["","import { DEFAULT_CONTRACT_SOURCE_DIR } from '@prisma-next/config/config-types';\n\nexport type TargetId = 'postgres' | 'mongo';\nexport type AuthoringId = 'psl' | 'typescript';\n\nexport function targetPackageName(target: TargetId): string {\n return target === 'postgres' ? '@prisma-next/postgres' : '@prisma-next/mongo';\n}\n\nexport function targetLabel(target: TargetId): string {\n return target === 'postgres' ? 'PostgreSQL' : 'MongoDB';\n}\n\nexport function defaultSchemaPath(authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.ts`;\n }\n return `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.prisma`;\n}\n\nexport function starterSchema(target: TargetId, authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return target === 'mongo' ? starterSchemaTsMongo() : starterSchemaTsPostgres();\n }\n return target === 'mongo' ? starterSchemaPslMongo() : starterSchemaPslPostgres();\n}\n\n/**\n * Renders a short authoring-appropriate schema sample (FR5.1) for embedding\n * in `prisma-next.md`. Returns a complete fenced markdown code block.\n *\n * The sample intentionally shows just one model: it's illustrative, not\n * a substitute for the full scaffolded contract file. The TS samples use\n * the same outer shape as `starterSchemaTs*` (FR5.3) so a user reading\n * the doc and the file side-by-side sees the same structure.\n */\nexport function schemaSample(target: TargetId, authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return target === 'mongo' ? schemaSampleTsMongo() : schemaSampleTsPostgres();\n }\n return target === 'mongo' ? schemaSamplePslMongo() : schemaSamplePslPostgres();\n}\n\nfunction schemaSamplePslPostgres(): string {\n return `\\`\\`\\`prisma\nmodel User {\n id Int @id @default(autoincrement())\n email String @unique\n username String?\n name String?\n}\n\\`\\`\\``;\n}\n\nfunction schemaSamplePslMongo(): string {\n return `\\`\\`\\`prisma\nmodel User {\n id ObjectId @id @map(\"_id\")\n email String @unique\n username String?\n name String?\n @@map(\"users\")\n}\n\\`\\`\\``;\n}\n\nfunction schemaSampleTsPostgres(): string {\n return `\\`\\`\\`typescript\nimport { defineContract } from '@prisma-next/postgres/contract-builder';\n\nexport const contract = defineContract(\n {},\n ({ field, model }) => ({\n models: {\n User: model('User', {\n fields: {\n id: field.id.uuidv7(),\n email: field.text().unique(),\n username: field.text().optional(),\n name: field.text().optional(),\n },\n }),\n },\n }),\n);\n\\`\\`\\``;\n}\n\nfunction schemaSampleTsMongo(): string {\n return `\\`\\`\\`typescript\nimport { defineContract } from '@prisma-next/mongo/contract-builder';\n\nexport const contract = defineContract(\n {},\n ({ field, model }) => ({\n models: {\n User: model('User', {\n collection: 'users',\n fields: {\n _id: field.objectId(),\n email: field.string(),\n username: field.string().optional(),\n name: field.string().optional(),\n },\n }),\n },\n }),\n);\n\\`\\`\\``;\n}\n\nfunction starterSchemaPslPostgres(): string {\n return `// use prisma-next\n\nmodel User {\n id Int @id @default(autoincrement())\n email String @unique\n username String?\n name String?\n posts Post[]\n createdAt DateTime @default(now())\n updatedAt temporal.updatedAt()\n}\n\nmodel Post {\n id Int @id @default(autoincrement())\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId Int\n createdAt DateTime @default(now())\n updatedAt temporal.updatedAt()\n}\n`;\n}\n\nfunction starterSchemaPslMongo(): string {\n return `// use prisma-next\n\nmodel User {\n id ObjectId @id @map(\"_id\")\n email String @unique\n username String?\n name String?\n posts Post[]\n @@map(\"users\")\n}\n\nmodel Post {\n id ObjectId @id @map(\"_id\")\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId ObjectId\n @@map(\"posts\")\n}\n`;\n}\n\nfunction starterSchemaTsPostgres(): string {\n return `import { defineContract } from '@prisma-next/postgres/contract-builder';\n\nexport const contract = defineContract(\n {},\n ({ field, model, rel }) => ({\n models: {\n User: model('User', {\n fields: {\n id: field.id.uuidv7(),\n email: field.text().unique(),\n username: field.text().optional(),\n name: field.text().optional(),\n createdAt: field.temporal.createdAt(),\n updatedAt: field.temporal.updatedAt(),\n },\n relations: {\n posts: rel.hasMany('Post', { by: 'authorId' }),\n },\n }),\n\n Post: model('Post', {\n fields: {\n id: field.id.uuidv7(),\n title: field.text(),\n content: field.text().optional(),\n authorId: field.uuid(),\n createdAt: field.temporal.createdAt(),\n updatedAt: field.temporal.updatedAt(),\n },\n relations: {\n author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),\n },\n }),\n },\n }),\n);\n`;\n}\n\nfunction starterSchemaTsMongo(): string {\n return `import { defineContract } from '@prisma-next/mongo/contract-builder';\n\nexport const contract = defineContract(\n {},\n ({ field, model, rel }) => ({\n models: {\n User: model('User', {\n collection: 'users',\n fields: {\n _id: field.objectId(),\n email: field.string(),\n username: field.string().optional(),\n name: field.string().optional(),\n },\n relations: {\n posts: rel.hasMany('Post', { from: '_id', to: 'authorId' }),\n },\n }),\n\n Post: model('Post', {\n collection: 'posts',\n fields: {\n _id: field.objectId(),\n title: field.string(),\n content: field.string().optional(),\n authorId: field.objectId(),\n },\n relations: {\n author: rel.belongsTo('User', { from: 'authorId', to: '_id' }),\n },\n }),\n },\n }),\n);\n`;\n}\n\nexport function configFile(target: TargetId, contractPath: string): string {\n const pkg = targetPackageName(target);\n return `import 'dotenv/config';\nimport { defineConfig } from '${pkg}/config';\n\nexport default defineConfig({\n contract: ${JSON.stringify(contractPath)},\n db: {\n connection: process.env['DATABASE_URL']!,\n },\n});\n`;\n}\n\nexport function dbFile(target: TargetId): string {\n if (target === 'postgres') {\n return `import postgres from '@prisma-next/postgres/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = postgres<Contract>({\n contractJson,\n url: process.env['DATABASE_URL']!,\n});\n`;\n }\n\n return `import mongo from '@prisma-next/mongo/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = mongo<Contract>({\n contractJson,\n url: process.env['DATABASE_URL']!,\n});\n`;\n}\n","import { Command } from 'commander';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../../utils/command-helpers';\nimport {\n type CommonCommandOptions,\n deriveCanPrompt,\n parseGlobalFlagsOrExit,\n} from '../../utils/global-flags';\nimport {\n INIT_EXIT_EMIT_FAILED,\n INIT_EXIT_INSTALL_FAILED,\n INIT_EXIT_INTERNAL_ERROR,\n INIT_EXIT_OK,\n INIT_EXIT_PRECONDITION,\n INIT_EXIT_SKILL_INSTALL_FAILED,\n INIT_EXIT_USER_ABORTED,\n} from './exit-codes';\nimport { defaultSchemaPath } from './templates/code-templates';\n\n/**\n * Commander.js parsed options for `init`. The init-specific options live\n * alongside the inherited `CommonCommandOptions` global flags.\n *\n * `target` and `authoring` are typed as plain `string` here because\n * Commander.js does not enforce enums at parse time — the validation /\n * normalisation happens in `inputs.ts::resolveInitInputs`, which can\n * raise a structured `errorInitInvalidFlagValue` with the full set of\n * allowed values.\n */\ninterface InitCommandOptions extends CommonCommandOptions {\n readonly target?: string;\n readonly authoring?: string;\n readonly schemaPath?: string;\n readonly force?: boolean;\n readonly writeEnv?: boolean;\n readonly probeDb?: boolean;\n readonly strictProbe?: boolean;\n readonly install?: boolean;\n readonly skill?: boolean;\n}\n\nexport function createInitCommand(): Command {\n const command = new Command('init');\n setCommandDescriptions(\n command,\n 'Initialize a new Prisma Next project',\n 'Scaffolds config, schema, and runtime files, installs dependencies,\\n' +\n 'and emits the contract. Gets you from zero to typed queries in one step.\\n' +\n '\\n' +\n 'Run interactively for a guided experience, or supply --target / --authoring\\n' +\n 'and --yes for a fully scriptable run (CI, AI coding agents, automation).\\n' +\n '\\n' +\n 'Exit codes (see CLI Style Guide § Exit Codes):\\n' +\n ` ${INIT_EXIT_OK} OK Init succeeded.\\n` +\n ` ${INIT_EXIT_INTERNAL_ERROR} INTERNAL_ERROR Unexpected bug in prisma-next (please report).\\n` +\n ` ${INIT_EXIT_PRECONDITION} PRECONDITION Bad flags / missing prerequisite (e.g. no package.json).\\n` +\n ` ${INIT_EXIT_USER_ABORTED} USER_ABORTED User cancelled an interactive prompt.\\n` +\n ` ${INIT_EXIT_INSTALL_FAILED} INSTALL_FAILED Dependency installation failed (init-specific).\\n` +\n ` ${INIT_EXIT_EMIT_FAILED} EMIT_FAILED \\`contract emit\\` failed after install (init-specific).\\n` +\n ` ${INIT_EXIT_SKILL_INSTALL_FAILED} SKILL_INSTALL_FAILED Agent-skill install failed (re-run with --no-skill to skip).`,\n );\n setCommandExamples(command, [\n 'prisma-next init',\n 'prisma-next init --yes --target postgres --authoring psl',\n 'prisma-next init --yes --target mongodb --authoring typescript --json',\n 'prisma-next init --yes --force --target postgres --authoring psl # overwrite an existing scaffold',\n 'prisma-next init --no-install # skip pnpm/npm install + emit',\n 'prisma-next init --no-skill # skip the skills install (air-gapped / restricted env)',\n ]);\n\n return addGlobalOptions(command)\n .option('--target <db>', 'Database target: postgres or mongodb')\n .option('--authoring <style>', 'Schema authoring style: psl or typescript')\n .option(\n '--schema-path <path>',\n `Where to write the starter schema (default: ${defaultSchemaPath('psl')})`,\n )\n .option('--force', 'Overwrite an existing scaffold without prompting')\n .option(\n '--write-env',\n 'Write a .env file from .env.example (gitignored; default: only .env.example)',\n )\n .option(\n '--probe-db',\n 'Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)',\n )\n .option(\n '--strict-probe',\n 'Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)',\n )\n .option('--no-install', 'Skip dependency installation and contract emission')\n .option(\n '--no-skill',\n 'Skip Prisma Next skills install (air-gapped CI, restricted registries, etc.)',\n )\n .action(async (options: InitCommandOptions) => {\n const { runInit } = await import('./init');\n const flags = parseGlobalFlagsOrExit(options);\n const canPrompt = deriveCanPrompt({\n flagsInteractive: flags.interactive,\n optionInteractive: options.interactive,\n stdinIsTTY: Boolean(process.stdin.isTTY),\n });\n const exitCode = await runInit(process.cwd(), {\n options,\n flags,\n canPrompt,\n });\n process.exit(exitCode);\n });\n}\n","import { distance } from 'closest-match';\n\n/**\n * Suggests similar command names for a mistyped input.\n *\n * Uses Levenshtein distance to find close matches. Only suggests commands\n * within a reasonable distance threshold (40% of the input length, minimum 2).\n * Returns up to 3 suggestions in case of ties.\n *\n * @returns Array of suggested command names (empty if nothing is close enough).\n */\nexport function suggestCommands(input: string, candidates: readonly string[]): string[] {\n if (candidates.length === 0) return [];\n\n // Threshold: at most 40% of the input length (min 2) to avoid absurd suggestions\n const maxDistance = Math.max(2, Math.ceil(input.length * 0.4));\n\n const scored = candidates\n .map((name) => ({ name, dist: distance(input, name) }))\n .filter((entry) => entry.dist <= maxDistance)\n .sort((a, b) => a.dist - b.dist);\n\n if (scored.length === 0) return [];\n\n // Take the best distance, then include ties (up to 3)\n const bestDist = scored[0]!.dist;\n return scored\n .filter((entry) => entry.dist === bestDist)\n .slice(0, 3)\n .map((entry) => entry.name);\n}\n","import { fileURLToPath } from 'node:url';\nimport {\n type CommanderOptionShape,\n type CommanderResultShape,\n ensureInstallationId,\n readUserConfig,\n resolveGating,\n runTelemetry,\n type TelemetryRunOutcome,\n type UserConfig,\n userConfigPath,\n} from '@prisma-next/cli-telemetry';\nimport type { Command } from 'commander';\nimport { version as CLI_VERSION } from '../../package.json' with { type: 'json' };\nimport { isCI } from './is-ci';\n\ntype TelemetryGate =\n | { readonly enabled: true; readonly userConfig: UserConfig }\n | { readonly enabled: false; readonly outcome: TelemetryRunOutcome };\n\n/**\n * Resolve the commander command path from a leaf `Command`, walking up\n * the parent chain. Result is rooted at the program name and ends at\n * the leaf — `['prisma-next', 'migration', 'new']` for\n * `prisma-next migration new …`.\n */\nfunction commandPathFor(actionCommand: Command): string[] {\n const path: string[] = [];\n let cursor: Command | null = actionCommand;\n while (cursor !== null) {\n path.unshift(cursor.name());\n cursor = cursor.parent;\n }\n return path;\n}\n\nfunction commanderOptionSnapshots(actionCommand: Command): CommanderOptionShape[] {\n return actionCommand.options.map((option) => {\n const attributeName = option.attributeName();\n return {\n attributeName,\n longName: option.long ?? null,\n source: actionCommand.getOptionValueSource(attributeName) ?? null,\n };\n });\n}\n\n/**\n * Project commander's leaf `Command` into the wire-shape snapshot the\n * telemetry sanitiser consumes. Pure projection — no env, no I/O.\n */\nexport function commanderSnapshotForTelemetry(actionCommand: Command): CommanderResultShape {\n return {\n commandPath: commandPathFor(actionCommand),\n positionalArgs: actionCommand.args,\n options: commanderOptionSnapshots(actionCommand),\n };\n}\n\nfunction resolveTelemetryGate(): TelemetryGate {\n if (isCI()) {\n return { enabled: false, outcome: { spawned: false, reason: 'ci' } };\n }\n const userConfig = readUserConfig();\n const gating = resolveGating({ env: process.env, config: userConfig });\n if (!gating.enabled) {\n return { enabled: false, outcome: { spawned: false, reason: 'gated-off' } };\n }\n return { enabled: true, userConfig };\n}\n\n/**\n * Path to the compiled sender script inside `@prisma-next/cli-telemetry`'s\n * `dist/`. Resolved off this module's `import.meta.url` via the package\n * specifier `@prisma-next/cli-telemetry/sender`, so the consumer pays\n * no attention to internal package layout.\n */\nfunction senderPath(): string {\n return fileURLToPath(new URL(import.meta.resolve('@prisma-next/cli-telemetry/sender')));\n}\n\nfunction fireTelemetry(actionCommand: Command, userConfig: UserConfig): TelemetryRunOutcome {\n return runTelemetry({\n command: commanderSnapshotForTelemetry(actionCommand),\n version: CLI_VERSION,\n projectRoot: process.cwd(),\n senderPath: senderPath(),\n isCI: isCI(),\n env: process.env,\n userConfig,\n });\n}\n\n/**\n * preAction-stage entry point. Synchronous by construction: resolve\n * env/CI/user-consent gates (cheap, all in-memory and a single tiny\n * user-config read), then — only when enabled — `fork()` the detached\n * sender script. The forked child loads `prisma-next.config.*` via\n * c12 on its own (see `loadProjectConfig` in cli-telemetry); the\n * parent does no project-config I/O on the command's hot path.\n *\n * Privacy invariant: gate resolution always happens before any project\n * config touches disk. The child loading user TS code is acceptable\n * only because it's gated behind the same resolved-enabled signal.\n */\n/**\n * Builds the one-time first-run disclosure. The resolved absolute path to\n * the user-level config file is substituted in so the user can see exactly\n * which file to edit (it must not be confused with `prisma-next.config.ts`).\n * `prisma-next telemetry disable` is named as the primary, friendliest\n * opt-out, alongside the env vars and the config edit.\n */\nfunction firstRunNotice(configPath: string): string {\n return [\n 'Prisma Next collects anonymous CLI usage data, enabled by default.',\n \"What's collected and why: https://prisma-next.dev/docs/cli/telemetry.\",\n 'Opt out: run \"prisma-next telemetry disable\", set DO_NOT_TRACK=1 or',\n `PRISMA_NEXT_DISABLE_TELEMETRY=1, or set \"enableTelemetry\": false in ${configPath}.`,\n ].join(' ');\n}\n\n/**\n * Best-effort first-run disclosure + installationId mint. Runs only on the\n * gating-enabled path. Prints the notice to stderr (never stdout) and mints\n * a persistent id without touching `enableTelemetry`, so the opt-out default\n * stays intact and no unasked-for consent is recorded.\n *\n * Every step is wrapped so an un-writable config dir (or any other failure)\n * never throws and never blocks the command. Returns the minted (or\n * pre-existing) id so the caller can forward it to `runTelemetry` without a\n * redundant disk read. On mint failure it returns `undefined`: the notice may\n * reprint next run, and `runTelemetry` no-ops on the missing id.\n */\nfunction discloseAndMintOnFirstRun(): string | undefined {\n try {\n process.stderr.write(`${firstRunNotice(userConfigPath())}\\n`);\n } catch {}\n try {\n return ensureInstallationId();\n } catch {}\n return undefined;\n}\n\n/**\n * True when the run is the `telemetry` command (or one of its\n * subcommands). The usage-telemetry preAction fire is exempted for it:\n * it would be absurd for `telemetry disable` to send a usage event before\n * disabling, or for `telemetry status` to mint an id + send while merely\n * reporting state. This is the only command-specific exemption.\n *\n * The check is rooted at the program: the path must be\n * `['prisma-next', 'telemetry', …]`, so it matches the top-level\n * `telemetry` command and its subcommands without matching a hypothetical\n * nested `… telemetry` elsewhere.\n */\nfunction isTelemetryCommand(actionCommand: Command): boolean {\n return commandPathFor(actionCommand)[1] === 'telemetry';\n}\n\nexport function fireTelemetryFromPreAction(actionCommand: Command): TelemetryRunOutcome {\n if (isTelemetryCommand(actionCommand)) {\n return { spawned: false, reason: 'gated-off' };\n }\n const gate = resolveTelemetryGate();\n if (!gate.enabled) {\n return gate.outcome;\n }\n const storedId = gate.userConfig.installationId;\n if (typeof storedId !== 'string' || storedId.length === 0) {\n const installationId = discloseAndMintOnFirstRun();\n return fireTelemetry(\n actionCommand,\n installationId === undefined ? gate.userConfig : { ...gate.userConfig, installationId },\n );\n }\n return fireTelemetry(actionCommand, gate.userConfig);\n}\n","import { Command } from 'commander';\nimport packageJson from '../package.json' with { type: 'json' };\nimport { createContractEmitCommand } from './commands/contract-emit';\nimport { createContractInferCommand } from './commands/contract-infer';\nimport { createInitCommand } from './commands/init';\nimport { installShutdownHandlers } from './utils/shutdown';\n\n// Install SIGINT/SIGTERM handlers before anything else\ninstallShutdownHandlers();\n\nimport { createDbInitCommand } from './commands/db-init';\nimport { createDbSchemaCommand } from './commands/db-schema';\nimport { createDbSignCommand } from './commands/db-sign';\nimport { createDbUpdateCommand } from './commands/db-update';\nimport { createDbVerifyCommand } from './commands/db-verify';\nimport { createMigrateCommand } from './commands/migrate';\nimport { createMigrationCheckCommand } from './commands/migration-check';\nimport { createMigrationGraphCommand } from './commands/migration-graph';\nimport { createMigrationListCommand } from './commands/migration-list';\nimport { createMigrationLogCommand } from './commands/migration-log';\nimport { createMigrationNewCommand } from './commands/migration-new';\nimport { createMigrationPlanCommand } from './commands/migration-plan';\nimport { createMigrationShowCommand } from './commands/migration-show';\nimport { createMigrationStatusCommand } from './commands/migration-status';\nimport { createRefCommand } from './commands/ref';\nimport { createTelemetryCommand } from './commands/telemetry';\nimport { setCommandDescriptions } from './utils/command-helpers';\nimport { formatCommandHelp, formatRootHelp } from './utils/formatters/help';\nimport { parseGlobalFlags } from './utils/global-flags';\nimport { suggestCommands } from './utils/suggest-command';\nimport { fireTelemetryFromPreAction } from './utils/telemetry';\n\n/**\n * Lookup table mapping removed subcommands to their replacement verbs.\n * Keyed by `<parent>:<subcommand>` (e.g. `migration:apply`).\n * The handler consults this before falling back to the fuzzy suggest engine.\n */\nconst removedVerbRedirects: Record<string, string> = {\n 'migration:apply': 'Use `prisma-next migrate --to <contract>` instead.',\n 'migration:ref': 'Use `prisma-next ref set|list|delete` instead.',\n};\n\n/**\n * Removed flags on specific subcommands. Keyed by `<parent>:<sub>:<flag>`.\n * Checked during the pre-parse argv scan before commander sees the flags.\n */\nconst removedFlagRedirects: Record<string, string> = {\n 'migration:status:graph': 'Use `prisma-next migration graph` to view the migration graph.',\n 'migration:status:all':\n 'Use `prisma-next migration log --db <url>` to view the full execution history.',\n 'migration:status:limit':\n 'Use `prisma-next migration log --db <url>` to view the full execution history.',\n 'migration:status:ref': 'Use `--to <contract>` instead of `--ref`.',\n};\n\n/**\n * Formats the \"Did you mean ...?\" hint for an unknown command.\n */\nfunction formatSuggestion(input: string, candidates: readonly string[]): string {\n const suggestions = suggestCommands(\n input,\n candidates.map((c) => c),\n );\n if (suggestions.length === 0) return '';\n if (suggestions.length === 1) return `\\nDid you mean ${suggestions[0]}?\\n`;\n return `\\nDid you mean one of these?\\n${suggestions.map((s) => ` ${s}`).join('\\n')}\\n`;\n}\n\nconst program = new Command();\n\nprogram.name('prisma-next').description('Prisma Next CLI').version(packageJson.version);\n\n// Telemetry hook — fires at command start, before the action body\n// runs. Synchronous by construction: `fireTelemetryFromPreAction`\n// resolves gates (cheap), then `fork()`s the detached sender. The\n// fork is enqueued before the action body runs at all, so the child\n// survives even when the action throws synchronously. The try/catch\n// is defence-in-depth — `runTelemetry` already swallows every failure\n// mode internally and returns an outcome instead of throwing.\nprogram.hook('preAction', (_thisCommand, actionCommand) => {\n try {\n fireTelemetryFromPreAction(actionCommand);\n } catch {\n // defence-in-depth — runTelemetry already swallows internally.\n }\n});\n\n// Override version option description to match capitalization style\nconst versionOption = program.options.find((opt) => opt.flags.includes('--version'));\nif (versionOption) {\n versionOption.description = 'Output the version number';\n}\n\nprogram.configureOutput({\n writeErr: () => {\n // Suppress all default error output - we handle errors in exitOverride\n },\n writeOut: (str) => {\n // Commander routes explicitly-requested `--help` (success-path help)\n // through writeOut; per the Style Guide § Output Conventions rule 8,\n // user-requested help is data and goes to stdout. Error-path help\n // (e.g. usage shown after an unknown command) goes through writeErr,\n // which stays suppressed because we render that ourselves with the\n // matching error envelope.\n //\n // Explicit `--version` is short-circuited before `program.parse()`\n // (see the argv pre-scan at the bottom of this file), so it does not\n // reach this writer.\n process.stdout.write(str);\n },\n});\n\n// Customize root help output to use our styled format\nconst rootHelpFormatter = (cmd: Command) => {\n const flags = parseGlobalFlags({});\n return formatRootHelp({ program: cmd, flags });\n};\n\nprogram.configureHelp({\n formatHelp: rootHelpFormatter,\n subcommandDescription: () => '',\n});\n\n// Override exit to handle unhandled errors (fail fast cases)\n// Commands handle structured errors themselves via process.exit()\nprogram.exitOverride((err) => {\n if (err) {\n const errorCode = (err as { code?: string }).code;\n const errorMessage = String(err.message ?? '');\n const errorName = err.name ?? '';\n\n // Unknown command/argument → exit 2 (CLI usage error)\n const isUnknownCommandError =\n errorCode === 'commander.unknownCommand' ||\n errorCode === 'commander.unknownArgument' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('unknown command') || errorMessage.includes('unknown argument')));\n if (isUnknownCommandError) {\n const flags = parseGlobalFlags({});\n const match = errorMessage.match(/unknown command ['\"]([^'\"]+)['\"]/);\n const commandName = match ? match[1] : process.argv[3] || process.argv[2] || 'unknown';\n\n const firstArg = process.argv[2];\n const parentCommand = firstArg\n ? program.commands.find((cmd) => cmd.name() === firstArg)\n : undefined;\n\n if (parentCommand && commandName !== firstArg) {\n const subNames = parentCommand.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, subNames)}\\n`,\n );\n const helpText = formatCommandHelp({ command: parentCommand, flags });\n process.stderr.write(`${helpText}\\n`);\n } else {\n const topNames = program.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, topNames)}\\n`,\n );\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n }\n process.exit(2);\n return;\n }\n\n // Help requests → exit 0\n const isHelpError =\n errorCode === 'commander.help' ||\n errorCode === 'commander.helpDisplayed' ||\n errorCode === 'outputHelp' ||\n errorMessage === '(outputHelp)' ||\n errorMessage.includes('outputHelp') ||\n (errorName === 'CommanderError' && errorMessage.includes('outputHelp'));\n if (isHelpError) {\n process.exit(0);\n return;\n }\n\n // Missing required arguments → exit 2 (CLI usage error)\n const isMissingArgumentError =\n errorCode === 'commander.missingArgument' ||\n errorCode === 'commander.missingMandatoryOptionValue' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('missing') || errorMessage.includes('required')));\n if (isMissingArgumentError) {\n process.exit(2);\n return;\n }\n\n // Unhandled error → exit 1\n process.stderr.write(`Unhandled error: ${err.message}\\n`);\n if (err.stack) {\n process.stderr.write(`${err.stack}\\n`);\n }\n process.exit(1);\n }\n process.exit(0);\n});\n\n// Register contract subcommand\nconst contractCommand = new Command('contract');\nsetCommandDescriptions(\n contractCommand,\n 'Contract management commands',\n 'Define and emit your application data contract. The contract describes your schema as a\\n' +\n 'declarative data structure that can be signed and verified against your database.',\n);\ncontractCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add emit subcommand to contract\nconst contractEmitCommand = createContractEmitCommand();\ncontractCommand.addCommand(contractEmitCommand);\n\n// Add infer subcommand to contract\nconst contractInferCommand = createContractInferCommand();\ncontractCommand.addCommand(contractInferCommand);\n\n// Register db subcommand\nconst dbCommand = new Command('db');\nsetCommandDescriptions(\n dbCommand,\n 'Database management commands',\n 'Verify and sign your database with your contract. Ensure your database schema matches\\n' +\n 'your contract, and sign it to record the contract hash for future verification.',\n);\ndbCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add verify subcommand to db\nconst dbVerifyCommand = createDbVerifyCommand();\ndbCommand.addCommand(dbVerifyCommand);\n\n// Add init subcommand to db\nconst dbInitCommand = createDbInitCommand();\ndbCommand.addCommand(dbInitCommand);\n\n// Add update subcommand to db\nconst dbUpdateCommand = createDbUpdateCommand();\ndbCommand.addCommand(dbUpdateCommand);\n\n// Add schema subcommand to db\nconst dbSchemaCommand = createDbSchemaCommand();\ndbCommand.addCommand(dbSchemaCommand);\n\n// Add sign subcommand to db\nconst dbSignCommand = createDbSignCommand();\ndbCommand.addCommand(dbSignCommand);\n\n// Register migration subcommand\nconst migrationCommand = new Command('migration');\nsetCommandDescriptions(\n migrationCommand,\n 'On-disk migration management commands',\n 'Plan, apply, and scaffold on-disk migration packages. Migrations are\\n' +\n 'contract-to-contract edges stored as versioned directories under migrations/.',\n);\nmigrationCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\nconst migrationPlanCommand = createMigrationPlanCommand();\nmigrationCommand.addCommand(migrationPlanCommand);\n\nconst migrationNewCommand = createMigrationNewCommand();\nmigrationCommand.addCommand(migrationNewCommand);\n\nconst migrationShowCommand = createMigrationShowCommand();\nmigrationCommand.addCommand(migrationShowCommand);\n\nconst migrationStatusCommand = createMigrationStatusCommand();\nmigrationCommand.addCommand(migrationStatusCommand);\n\nconst migrationLogCommand = createMigrationLogCommand();\nmigrationCommand.addCommand(migrationLogCommand);\n\nconst migrationListCommand = createMigrationListCommand();\nmigrationCommand.addCommand(migrationListCommand);\n\nconst migrationGraphCommand = createMigrationGraphCommand();\nmigrationCommand.addCommand(migrationGraphCommand);\n\nconst migrationCheckCommand = createMigrationCheckCommand();\nmigrationCommand.addCommand(migrationCheckCommand);\n\n// Top-level migrate command\nconst migrateCommand = createMigrateCommand();\n\n// Top-level ref command (replaces `migration ref`)\nconst refCommand = createRefCommand();\n\n// Top-level telemetry command\nconst telemetryCommand = createTelemetryCommand();\n\n// Top-level init command\nconst initCommand = createInitCommand();\n\n// Register top-level commands in the order the spec's intended-surface\n// diagram lists them: verbs (init, migrate) first, then subject\n// namespaces (contract, db, migration, ref). The order shows up in\n// `prisma-next --help` and is the first thing a new user sees, so it\n// matches the order spec.md uses to introduce the surface.\nprogram.addCommand(initCommand);\nprogram.addCommand(migrateCommand);\nprogram.addCommand(contractCommand);\nprogram.addCommand(dbCommand);\nprogram.addCommand(migrationCommand);\nprogram.addCommand(refCommand);\nprogram.addCommand(telemetryCommand);\n\n// Test-only hidden command used by `cli-telemetry`'s `cli-e2e.test.ts`\n// to verify that telemetry still lands when a CLI command crashes\n// mid-execution. The preAction hook is synchronous and `fork()`s the\n// detached sender before this action body runs; the small sleep\n// gives the IPC `child.send()` a tick to flush before the throw\n// triggers commander's `exitOverride` and `process.exit(1)`. Hidden\n// from help; underscore prefix marks it as internal. Doesn't depend\n// on any project state, so it runs in any tempdir.\n//\n// Gated behind `PRISMA_NEXT_ENABLE_TEST_COMMANDS=1` so the command is\n// not even registered (and therefore not invocable) in shipped\n// binaries. `hidden: true` only filters the help output; without this\n// env gate the command would still be callable from production. The\n// e2e suite sets the env var when it spawns the CLI.\nconst TELEMETRY_CRASH_TEST_SLEEP_MS = 200;\nif (process.env['PRISMA_NEXT_ENABLE_TEST_COMMANDS'] === '1') {\n const telemetryCrashTestCommand = new Command('__telemetry-crash-test')\n .description('Internal: deliberately throw for the telemetry e2e suite.')\n .action(async () => {\n await new Promise((settle) => setTimeout(settle, TELEMETRY_CRASH_TEST_SLEEP_MS));\n throw new Error('__telemetry-crash-test: intentional crash for e2e coverage');\n });\n telemetryCrashTestCommand.configureHelp({ visibleCommands: () => [] });\n program.addCommand(telemetryCrashTestCommand, { hidden: true });\n}\n\n// Create help command\nconst helpCommand = new Command('help')\n .description('Show usage instructions')\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n // The `help` command was invoked explicitly: help is the data the\n // caller asked for. Per Style Guide § Output Conventions rule 8,\n // explicit help goes to stdout with exit code 0.\n process.stdout.write(`${helpText}\\n`);\n process.exit(0);\n });\n\nprogram.addCommand(helpCommand);\n\n// Set help as the default action when no command is provided. The user\n// did not invoke `--help`; we are voluntarily showing usage to help them\n// recover from an underspecified invocation, so the help text is\n// decoration around an implicit \"what did you want me to do?\" and goes\n// to stderr (Style Guide § Output Conventions rule 8).\n//\n// FOLLOW-UP: the exit code here is 0 today, but a no-arg invocation is\n// arguably a usage error (PRECONDITION → exit 2) for consistency with\n// the unknown-command path. Out of scope for the explicit-help routing\n// work; revisit when tightening exit-code semantics across the CLI.\nprogram.action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(0);\n});\n\n// Check if a command was invoked with no arguments (just the command name)\n// or if an unrecognized command was provided\nconst args = process.argv.slice(2);\nif (args.length > 0) {\n const commandName = args[0];\n // Handle version option explicitly since we suppress default output\n if (commandName === '--version' || commandName === '-V') {\n // Version is data → stdout\n process.stdout.write(`${program.version()}\\n`);\n process.exit(0);\n }\n // Skip command check for global options like --help, -h\n const isGlobalOption = commandName === '--help' || commandName === '-h';\n if (!isGlobalOption) {\n // Check if this is a recognized command\n const command = program.commands.find((cmd) => cmd.name() === commandName);\n\n if (!command) {\n // Unrecognized command → exit 2 (CLI usage error)\n const flags = parseGlobalFlags({});\n const topNames = program.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, topNames)}\\n`,\n );\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(2);\n } else if (command.commands.length > 0 && args.length >= 2) {\n const subcommandName = args[1];\n const redirectKey = `${commandName}:${subcommandName}`;\n const redirect = removedVerbRedirects[redirectKey];\n if (redirect) {\n process.stderr.write(`Unknown command: ${subcommandName}\\n${redirect}\\n`);\n process.exit(2);\n }\n for (let i = 2; i < args.length; i++) {\n const arg = args[i]!;\n if (!arg.startsWith('--')) continue;\n const flagName = arg.slice(2);\n const flagKey = `${commandName}:${subcommandName}:${flagName}`;\n const flagRedirect = removedFlagRedirects[flagKey];\n if (flagRedirect) {\n process.stderr.write(`Unknown option: ${arg}\\n${flagRedirect}\\n`);\n process.exit(2);\n }\n }\n }\n\n if (command.commands.length > 0 && args.length === 1) {\n // Parent command called with no subcommand. Same shape as the\n // no-args case above: the user did not request help, we are\n // voluntarily rendering it as decoration around an underspecified\n // invocation, so it goes to stderr per Style Guide § Output\n // Conventions rule 8. Exit code 0 today; the FOLLOW-UP note on\n // `program.action` applies here too (arguably should be 2).\n const flags = parseGlobalFlags({});\n const helpText = formatCommandHelp({ command, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(0);\n }\n }\n}\n\nprogram.parse();\n"],"mappings":"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"}
@@ -1,15 +1,15 @@
1
- import { A as CliStructuredError } from "./command-helpers-Bbw1GbwL.mjs";
2
- import { t as assertFrameworkComponentsCompatible } from "./framework-components-fYXjz_in.mjs";
1
+ import { F as CliStructuredError } from "./command-helpers-esJGBD4W.mjs";
2
+ import { t as assertFrameworkComponentsCompatible } from "./framework-components-BO9VO43s.mjs";
3
3
  import { t as enrichContract } from "./contract-enrichment-a0V5Y_mL.mjs";
4
- import { n as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-DvZwdkrr.mjs";
4
+ import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-CpNVrBqW.mjs";
5
5
  import { emit } from "@prisma-next/emitter";
6
6
  import { ifDefined } from "@prisma-next/utils/defined";
7
7
  import { notOk, ok } from "@prisma-next/utils/result";
8
8
  import { APP_SPACE_ID, createControlStack, hasMigrations, hasOperationPreview, hasPslContractInfer, hasSchemaView } from "@prisma-next/framework-components/control";
9
- import { graphWalkStrategy, planMigration, requireHeadRef, verifyMigration } from "@prisma-next/migration-tools/aggregate";
9
+ import { castAs } from "@prisma-next/utils/casts";
10
+ import { buildSynthMigrationEdge, graphWalkStrategy, planMigration, requireHeadRef, verifyMigration } from "@prisma-next/migration-tools/aggregate";
10
11
  import { EMPTY_CONTRACT_HASH } from "@prisma-next/migration-tools/constants";
11
12
  import { errorNoInvariantPath } from "@prisma-next/migration-tools/errors";
12
- import { castAs } from "@prisma-next/utils/casts";
13
13
  import { findPathWithDecision } from "@prisma-next/migration-tools/migration-graph";
14
14
  //#region src/control-api/errors.ts
15
15
  var ContractValidationError = class extends Error {
@@ -21,14 +21,27 @@ var ContractValidationError = class extends Error {
21
21
  }
22
22
  };
23
23
  //#endregion
24
- //#region src/control-api/operations/apply.ts
24
+ //#region src/control-api/operations/migration-helpers.ts
25
25
  /**
26
- * Span id emitted via `onProgress` for the apply phase. Stable
26
+ * Strips operation objects to their public shape (id, label, operationClass).
27
+ * Used at the API boundary to avoid leaking internal fields (precheck, execute, postcheck, etc.).
28
+ */
29
+ function stripOperations(operations) {
30
+ return operations.map((op) => ({
31
+ id: op.id,
32
+ label: op.label,
33
+ operationClass: op.operationClass
34
+ }));
35
+ }
36
+ //#endregion
37
+ //#region src/control-api/operations/run-migration.ts
38
+ /**
39
+ * Span id emitted via `onProgress` for the run phase. Stable
27
40
  * identifier consumed by the structured-output renderer and by tests.
28
41
  */
29
- const APPLY_SPAN_ID = "apply";
42
+ const RUN_SPAN_ID = "apply";
30
43
  /**
31
- * Runner-driving tail shared by every apply caller — `db init`,
44
+ * Runner-driving tail shared by every run caller — `db init`,
32
45
  * `db update`, and `migrate`. Consumes already-resolved per-space
33
46
  * plans (the planner-vs-replay distinction is owned by the caller) and
34
47
  * dispatches them to the runner in canonical order.
@@ -43,14 +56,14 @@ const APPLY_SPAN_ID = "apply";
43
56
  * so callers don't have to duplicate it; the `action` field on each
44
57
  * progress event is taken from the caller's `action` argument.
45
58
  */
46
- async function applyMigration(inputs) {
59
+ async function runMigration(inputs) {
47
60
  const { aggregate, perSpacePlans, applyOrder, driver, familyInstance, migrations, frameworkComponents, policy, action, onProgress } = inputs;
48
61
  const orderedResolutions = collectOrdered(applyOrder, perSpacePlans);
49
62
  const runner = migrations.createRunner(familyInstance);
50
63
  onProgress?.({
51
64
  action,
52
65
  kind: "spanStart",
53
- spanId: APPLY_SPAN_ID,
66
+ spanId: RUN_SPAN_ID,
54
67
  label: progressLabelForAction(action)
55
68
  });
56
69
  const perSpaceOptions = orderedResolutions.map((r) => ({
@@ -60,6 +73,7 @@ async function applyMigration(inputs) {
60
73
  destinationContract: r.entry.destinationContract,
61
74
  policy,
62
75
  frameworkComponents,
76
+ migrationEdges: r.entry.migrationEdges,
63
77
  strictVerification: false
64
78
  }));
65
79
  const runnerResult = await runner.execute({
@@ -70,7 +84,7 @@ async function applyMigration(inputs) {
70
84
  onProgress?.({
71
85
  action,
72
86
  kind: "spanEnd",
73
- spanId: APPLY_SPAN_ID,
87
+ spanId: RUN_SPAN_ID,
74
88
  outcome: "error"
75
89
  });
76
90
  return notOk({
@@ -86,7 +100,7 @@ async function applyMigration(inputs) {
86
100
  onProgress?.({
87
101
  action,
88
102
  kind: "spanEnd",
89
- spanId: APPLY_SPAN_ID,
103
+ spanId: RUN_SPAN_ID,
90
104
  outcome: "ok"
91
105
  });
92
106
  return ok({
@@ -105,7 +119,7 @@ async function applyMigration(inputs) {
105
119
  * advances as the last step of each space's transaction) and `false`
106
120
  * for plan-mode (no marker has been written yet).
107
121
  *
108
- * Exported alongside {@link applyMigration} so plan-mode callers can
122
+ * Exported alongside {@link runMigration} so plan-mode callers can
109
123
  * assemble the same per-space block without going through the runner.
110
124
  */
111
125
  function buildPerSpaceBreakdown(orderedResolutions, appSpaceId, options) {
@@ -146,8 +160,8 @@ function collectOrdered(applyOrder, perSpace) {
146
160
  });
147
161
  }
148
162
  /**
149
- * Action-appropriate label for the `spanStart` event the apply
150
- * primitive emits. `applyMigration` is shared by `db init`, `db update`,
163
+ * Action-appropriate label for the `spanStart` event the run
164
+ * primitive emits. `runMigration` is shared by `db init`, `db update`,
151
165
  * and `migrate`; the span label tracks the user-visible action
152
166
  * so structured-progress output reads naturally for each surface.
153
167
  */
@@ -155,29 +169,16 @@ function progressLabelForAction(action) {
155
169
  switch (action) {
156
170
  case "dbInit": return "Initialising database across spaces";
157
171
  case "dbUpdate": return "Updating database across spaces";
158
- case "migrationApply": return "Applying migration plan across spaces";
172
+ case "migrate": return "Running migration plan across spaces";
159
173
  }
160
174
  }
161
175
  //#endregion
162
- //#region src/control-api/operations/migration-helpers.ts
163
- /**
164
- * Strips operation objects to their public shape (id, label, operationClass).
165
- * Used at the API boundary to avoid leaking internal fields (precheck, execute, postcheck, etc.).
166
- */
167
- function stripOperations(operations) {
168
- return operations.map((op) => ({
169
- id: op.id,
170
- label: op.label,
171
- operationClass: op.operationClass
172
- }));
173
- }
174
- //#endregion
175
- //#region src/control-api/operations/db-apply.ts
176
+ //#region src/control-api/operations/db-run.ts
176
177
  /**
177
- * Span IDs emitted via `onProgress` during the apply flow.
178
+ * Span IDs emitted via `onProgress` during the run flow.
178
179
  * Stable identifiers consumed by the structured-output renderer and by
179
180
  * tests asserting on span ids. The `apply` span itself is owned by
180
- * the {@link applyMigration} primitive — only the introspect / plan
181
+ * the {@link runMigration} primitive — only the introspect / plan
181
182
  * spans are emitted directly here.
182
183
  */
183
184
  const SPAN_IDS$1 = {
@@ -203,7 +204,7 @@ const SPAN_IDS$1 = {
203
204
  * transaction across every space; failure on any space rolls back
204
205
  * every space's writes.
205
206
  */
206
- async function executeApply(options) {
207
+ async function executeRun(options) {
207
208
  const { driver, familyInstance, contract, mode, migrations, frameworkComponents, migrationsDir, extensionPacks, targetId, policy, action, onProgress } = options;
208
209
  const loaded = await buildContractSpaceAggregate({
209
210
  targetId,
@@ -266,6 +267,7 @@ async function executeApply(options) {
266
267
  outcome: "ok"
267
268
  });
268
269
  const orderedResolutions = collectOrdered(planResult.value.applyOrder, planResult.value.perSpace);
270
+ const plannerWarnings = aggregatePlannerWarnings(orderedResolutions);
269
271
  const appResolution = orderedResolutions.find((r) => r.spaceId === aggregate.app.spaceId);
270
272
  if (!appResolution) throw new Error("Aggregate planner returned no plan for the app member — the planner is supposed to always emit one.");
271
273
  const appPlan = appResolution.entry.plan;
@@ -279,10 +281,11 @@ async function executeApply(options) {
279
281
  destination: appPlan.destination,
280
282
  preview,
281
283
  perSpace,
282
- summary
284
+ summary,
285
+ ...ifDefined("warnings", plannerWarnings)
283
286
  });
284
287
  }
285
- const applied = await applyMigration({
288
+ const applied = await runMigration({
286
289
  aggregate,
287
290
  perSpacePlans: planResult.value.perSpace,
288
291
  applyOrder: planResult.value.applyOrder,
@@ -297,7 +300,8 @@ async function executeApply(options) {
297
300
  if (!applied.ok) return buildRunnerFailure({
298
301
  summary: applied.failure.summary,
299
302
  ...ifDefined("why", applied.failure.why),
300
- meta: applied.failure.meta
303
+ meta: applied.failure.meta,
304
+ ...ifDefined("warnings", plannerWarnings)
301
305
  });
302
306
  const aggregateOps = applied.value.orderedResolutions.flatMap((r) => r.entry.displayOps);
303
307
  const summary = action === "dbInit" ? `Applied ${applied.value.totalOpsExecuted} operation(s) across ${applied.value.orderedResolutions.length} space(s), database signed` : applied.value.totalOpsExecuted === 0 ? `Database already matches contract across ${applied.value.orderedResolutions.length} space(s), signature updated` : `Applied ${applied.value.totalOpsExecuted} operation(s) across ${applied.value.orderedResolutions.length} space(s), signature updated`;
@@ -307,9 +311,14 @@ async function executeApply(options) {
307
311
  operationsPlanned: applied.value.totalOpsPlanned,
308
312
  operationsExecuted: applied.value.totalOpsExecuted,
309
313
  perSpace: applied.value.perSpace,
310
- summary
314
+ summary,
315
+ ...ifDefined("warnings", plannerWarnings)
311
316
  });
312
317
  }
318
+ function aggregatePlannerWarnings(orderedResolutions) {
319
+ const warnings = orderedResolutions.flatMap((r) => r.entry.warnings ?? []);
320
+ return warnings.length > 0 ? warnings : void 0;
321
+ }
313
322
  /**
314
323
  * Compare the live `_prisma_marker` rows against the aggregate's
315
324
  * declared members. Any marker row whose `space` is not a member of
@@ -383,7 +392,8 @@ function wrapPlanResult(args) {
383
392
  ...ifDefined("profileHash", args.destination.profileHash)
384
393
  },
385
394
  perSpace: args.perSpace,
386
- summary: args.summary
395
+ summary: args.summary,
396
+ ...ifDefined("warnings", args.warnings)
387
397
  });
388
398
  }
389
399
  function wrapApplyResult(args) {
@@ -403,7 +413,8 @@ function wrapApplyResult(args) {
403
413
  profileHash: args.destination.profileHash
404
414
  } : { storageHash: args.destination.storageHash },
405
415
  perSpace: args.perSpace,
406
- summary: args.summary
416
+ summary: args.summary,
417
+ ...ifDefined("warnings", args.warnings)
407
418
  });
408
419
  }
409
420
  function buildRunnerFailure(args) {
@@ -412,7 +423,8 @@ function buildRunnerFailure(args) {
412
423
  summary: args.summary,
413
424
  why: args.why,
414
425
  meta: args.meta,
415
- conflicts: void 0
426
+ conflicts: void 0,
427
+ ...ifDefined("warnings", args.warnings)
416
428
  });
417
429
  }
418
430
  //#endregion
@@ -425,7 +437,7 @@ function buildRunnerFailure(args) {
425
437
  * changes belong to `db update`.
426
438
  */
427
439
  async function executeDbInit(options) {
428
- return await executeApply({
440
+ return await executeRun({
429
441
  driver: options.driver,
430
442
  familyInstance: options.familyInstance,
431
443
  contract: options.contract,
@@ -474,7 +486,7 @@ async function executeDbUpdate(options) {
474
486
  const gate = await guardDestructiveChanges(sharedInputs);
475
487
  if (gate !== null) return gate;
476
488
  }
477
- return await executeApply({
489
+ return await executeRun({
478
490
  ...sharedInputs,
479
491
  mode: options.mode
480
492
  });
@@ -487,7 +499,7 @@ async function executeDbUpdate(options) {
487
499
  * run.
488
500
  */
489
501
  async function guardDestructiveChanges(sharedInputs) {
490
- const planResult = await executeApply({
502
+ const planResult = await executeRun({
491
503
  ...sharedInputs,
492
504
  mode: "plan"
493
505
  });
@@ -730,7 +742,7 @@ function mapMarkerCheckFailures(appSpaceId, section) {
730
742
  });
731
743
  }
732
744
  //#endregion
733
- //#region src/control-api/operations/migration-apply.ts
745
+ //#region src/control-api/operations/migrate.ts
734
746
  /**
735
747
  * Apply pending migrations across every contract space (app +
736
748
  * extensions). Replay-only: graph-walk against the on-disk graph for
@@ -745,14 +757,14 @@ function mapMarkerCheckFailures(appSpaceId, section) {
745
757
  * marker to `member.headRef.hash` (or `refHash` for the app
746
758
  * member when provided). Empty-graph members fail loudly — a
747
759
  * "never planned" space is a user-error condition for replay.
748
- * 4. Hand off to {@link applyMigration} (the runner-driving tail
760
+ * 4. Hand off to {@link runMigration} (the runner-driving tail
749
761
  * shared with `db init` / `db update`). Marker advancement is
750
762
  * inside the per-space transaction.
751
763
  *
752
764
  * Encodes the replay-only contract: every contract space must have an
753
765
  * authored migration graph on disk before this operation can advance it.
754
766
  */
755
- async function executeMigrationApply(options) {
767
+ async function executeMigrate(options) {
756
768
  const { driver, familyInstance, contract, migrations, frameworkComponents, migrationsDir, extensionPacks, targetId, refHash, refInvariants, refName, onProgress } = options;
757
769
  const loaded = await buildContractSpaceAggregate({
758
770
  targetId,
@@ -840,7 +852,7 @@ async function executeMigrationApply(options) {
840
852
  summary: totalSpaces === 0 ? "Already up to date — no contract spaces are loaded" : totalSpaces === 1 ? "Already up to date" : `Already up to date across ${totalSpaces} space(s)`
841
853
  }));
842
854
  }
843
- const applied = await applyMigration({
855
+ const applied = await runMigration({
844
856
  aggregate,
845
857
  perSpacePlans,
846
858
  applyOrder,
@@ -854,7 +866,7 @@ async function executeMigrationApply(options) {
854
866
  "destructive",
855
867
  "data"
856
868
  ] },
857
- action: "migrationApply",
869
+ action: "migrate",
858
870
  ...ifDefined("onProgress", onProgress)
859
871
  });
860
872
  if (!applied.ok) return notOk({
@@ -876,7 +888,7 @@ async function executeMigrationApply(options) {
876
888
  };
877
889
  });
878
890
  const perSpaceAll = buildPerSpaceBreakdown(orderedAll, aggregate.app.spaceId, { includeMarkers: true });
879
- const summary = `Applied ${applied.value.orderedResolutions.reduce((sum, r) => sum + (r.entry.migrationEdges?.length ?? 0), 0)} migration(s) (${applied.value.totalOpsExecuted} operation(s)) across ${orderedAll.length} contract space(s)`;
891
+ const summary = `Applied ${applied.value.orderedResolutions.reduce((sum, r) => sum + r.entry.migrationEdges.length, 0)} migration(s) (${applied.value.totalOpsExecuted} operation(s)) across ${orderedAll.length} contract space(s)`;
880
892
  return ok(buildSuccess({
881
893
  aggregate,
882
894
  orderedResolutions: orderedAll,
@@ -906,7 +918,11 @@ function buildAtHeadResolution(args) {
906
918
  displayOps: [],
907
919
  destinationContract: member.contract(),
908
920
  strategy: "graph-walk",
909
- migrationEdges: []
921
+ migrationEdges: [buildSynthMigrationEdge({
922
+ currentMarkerStorageHash: liveMarker?.storageHash,
923
+ destinationStorageHash: targetHash,
924
+ operationCount: 0
925
+ })]
910
926
  };
911
927
  }
912
928
  function sumPlannedOps(applyOrder, perSpacePlans) {
@@ -922,7 +938,7 @@ function buildSuccess(args) {
922
938
  const appResolution = args.orderedResolutions.find((r) => r.spaceId === args.aggregate.app.spaceId);
923
939
  const appMarkerHash = appResolution?.entry.plan.destination.storageHash ?? requireHeadRef(args.aggregate.app).hash;
924
940
  const applied = args.orderedResolutions.flatMap((r) => {
925
- return (r.entry.migrationEdges ?? []).map((edge) => ({
941
+ return r.entry.migrationEdges.map((edge) => ({
926
942
  spaceId: r.spaceId,
927
943
  dirName: edge.dirName,
928
944
  migrationHash: edge.migrationHash,
@@ -1302,9 +1318,17 @@ var ControlClientImpl = class {
1302
1318
  const { driver, familyInstance } = await this.ensureConnected();
1303
1319
  return familyInstance.readAllMarkers({ driver });
1304
1320
  }
1305
- async migrationApply(options) {
1321
+ /** Reads the per-migration journal; omit `space` to return every space. */
1322
+ async readLedger(space) {
1323
+ const { driver, familyInstance } = await this.ensureConnected();
1324
+ return familyInstance.readLedger({
1325
+ driver,
1326
+ ...ifDefined("space", space)
1327
+ });
1328
+ }
1329
+ async migrate(options) {
1306
1330
  const { onProgress } = options;
1307
- await this.connectWithProgress(options.connection, "migrationApply", onProgress);
1331
+ await this.connectWithProgress(options.connection, "migrate", onProgress);
1308
1332
  const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();
1309
1333
  if (!hasMigrations(this.options.target)) throw new Error(`Target "${this.options.target.targetId}" does not support migrations`);
1310
1334
  let contract;
@@ -1313,7 +1337,7 @@ var ControlClientImpl = class {
1313
1337
  } catch (error) {
1314
1338
  throw new ContractValidationError(error instanceof Error ? error.message : String(error), error);
1315
1339
  }
1316
- return executeMigrationApply({
1340
+ return executeMigrate({
1317
1341
  driver,
1318
1342
  familyInstance,
1319
1343
  contract,
@@ -1444,8 +1468,9 @@ var ControlClientImpl = class {
1444
1468
  });
1445
1469
  try {
1446
1470
  const enrichedIR = enrichContract(contractRaw, this.frameworkComponents ?? []);
1471
+ let deserializedContract;
1447
1472
  try {
1448
- this.familyInstance.deserializeContract(enrichedIR);
1473
+ deserializedContract = this.familyInstance.deserializeContract(enrichedIR);
1449
1474
  } catch (error) {
1450
1475
  onProgress?.({
1451
1476
  action: "emit",
@@ -1460,7 +1485,7 @@ var ControlClientImpl = class {
1460
1485
  meta: void 0
1461
1486
  });
1462
1487
  }
1463
- const result = await emit(enrichedIR, this.stack, this.options.family.emission, { serializeContract: (contract) => this.options.target.contractSerializer.serializeContract(contract) });
1488
+ const result = await emit(deserializedContract, this.stack, this.options.family.emission, { serializeContract: (contract) => this.options.target.contractSerializer.serializeContract(contract) });
1464
1489
  onProgress?.({
1465
1490
  action: "emit",
1466
1491
  kind: "spanEnd",
@@ -1493,4 +1518,4 @@ var ControlClientImpl = class {
1493
1518
  //#endregion
1494
1519
  export { ContractValidationError as a, executeDbInit as i, executeDbVerify as n, executeDbUpdate as r, createControlClient as t };
1495
1520
 
1496
- //# sourceMappingURL=client-KgJorIvG.mjs.map
1521
+ //# sourceMappingURL=client-DC-UlBLy.mjs.map