prisma-next 0.11.0-dev.3 → 0.11.0-dev.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/cli-errors-DFF1LlfU.mjs +215 -0
  2. package/dist/cli-errors-DFF1LlfU.mjs.map +1 -0
  3. package/dist/cli.mjs +8 -9
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/{client-oXO2WCPD.mjs → client-a5NJce0-.mjs} +5 -5
  6. package/dist/{client-oXO2WCPD.mjs.map → client-a5NJce0-.mjs.map} +1 -1
  7. package/dist/{command-helpers-DtavI0wJ.mjs → command-helpers-BnqwTptC.mjs} +380 -6
  8. package/dist/command-helpers-BnqwTptC.mjs.map +1 -0
  9. package/dist/commands/contract-emit.d.mts.map +1 -1
  10. package/dist/commands/contract-emit.mjs +1 -1
  11. package/dist/commands/contract-infer.d.mts.map +1 -1
  12. package/dist/commands/contract-infer.mjs +1 -1
  13. package/dist/commands/db-init.d.mts.map +1 -1
  14. package/dist/commands/db-init.mjs +33 -7
  15. package/dist/commands/db-init.mjs.map +1 -1
  16. package/dist/commands/db-schema.d.mts.map +1 -1
  17. package/dist/commands/db-schema.mjs +3 -4
  18. package/dist/commands/db-schema.mjs.map +1 -1
  19. package/dist/commands/db-sign.d.mts.map +1 -1
  20. package/dist/commands/db-sign.mjs +6 -7
  21. package/dist/commands/db-sign.mjs.map +1 -1
  22. package/dist/commands/db-update.d.mts.map +1 -1
  23. package/dist/commands/db-update.mjs +36 -8
  24. package/dist/commands/db-update.mjs.map +1 -1
  25. package/dist/commands/db-verify.d.mts.map +1 -1
  26. package/dist/commands/db-verify.mjs +1 -1
  27. package/dist/commands/migrate.d.mts +5 -1
  28. package/dist/commands/migrate.d.mts.map +1 -1
  29. package/dist/commands/migrate.mjs +44 -9
  30. package/dist/commands/migrate.mjs.map +1 -1
  31. package/dist/commands/migration-check.d.mts.map +1 -1
  32. package/dist/commands/migration-check.mjs +2 -3
  33. package/dist/commands/migration-check.mjs.map +1 -1
  34. package/dist/commands/migration-graph.d.mts.map +1 -1
  35. package/dist/commands/migration-graph.mjs +2 -3
  36. package/dist/commands/migration-graph.mjs.map +1 -1
  37. package/dist/commands/migration-list.d.mts +57 -13
  38. package/dist/commands/migration-list.d.mts.map +1 -1
  39. package/dist/commands/migration-list.mjs +2 -103
  40. package/dist/commands/migration-log.d.mts.map +1 -1
  41. package/dist/commands/migration-log.mjs +3 -4
  42. package/dist/commands/migration-log.mjs.map +1 -1
  43. package/dist/commands/migration-new.d.mts.map +1 -1
  44. package/dist/commands/migration-new.mjs +3 -4
  45. package/dist/commands/migration-new.mjs.map +1 -1
  46. package/dist/commands/migration-plan.d.mts +1 -0
  47. package/dist/commands/migration-plan.d.mts.map +1 -1
  48. package/dist/commands/migration-plan.mjs +1 -1
  49. package/dist/commands/migration-show.d.mts +1 -1
  50. package/dist/commands/migration-show.d.mts.map +1 -1
  51. package/dist/commands/migration-show.mjs +6 -7
  52. package/dist/commands/migration-show.mjs.map +1 -1
  53. package/dist/commands/migration-status.d.mts.map +1 -1
  54. package/dist/commands/migration-status.mjs +6 -7
  55. package/dist/commands/migration-status.mjs.map +1 -1
  56. package/dist/commands/ref.d.mts +1 -1
  57. package/dist/commands/ref.d.mts.map +1 -1
  58. package/dist/commands/ref.mjs +34 -9
  59. package/dist/commands/ref.mjs.map +1 -1
  60. package/dist/config-loader-B6sJjXTv.mjs.map +1 -1
  61. package/dist/config-loader.d.mts.map +1 -1
  62. package/dist/{contract-emit-bcrpT-wD.mjs → contract-emit-DYBHfZqL.mjs} +8 -7
  63. package/dist/contract-emit-DYBHfZqL.mjs.map +1 -0
  64. package/dist/{contract-emit-uwT-Mj8-.mjs → contract-emit-aFcOi3aw.mjs} +20 -14
  65. package/dist/contract-emit-aFcOi3aw.mjs.map +1 -0
  66. package/dist/{contract-enrichment-Dani0mMW.mjs → contract-enrichment-XmUPhmsS.mjs} +4 -25
  67. package/dist/contract-enrichment-XmUPhmsS.mjs.map +1 -0
  68. package/dist/{contract-infer-pKkiCt7C.mjs → contract-infer-BpJeg-Eu.mjs} +3 -4
  69. package/dist/{contract-infer-pKkiCt7C.mjs.map → contract-infer-BpJeg-Eu.mjs.map} +1 -1
  70. package/dist/{contract-space-aggregate-loader-BmNQwlws.mjs → contract-space-aggregate-loader-EVU3n9YE.mjs} +2 -2
  71. package/dist/{contract-space-aggregate-loader-BmNQwlws.mjs.map → contract-space-aggregate-loader-EVU3n9YE.mjs.map} +1 -1
  72. package/dist/{db-verify-AoIUriL4.mjs → db-verify-CxtdGiL3.mjs} +6 -7
  73. package/dist/{db-verify-AoIUriL4.mjs.map → db-verify-CxtdGiL3.mjs.map} +1 -1
  74. package/dist/exports/control-api.d.mts +1 -1
  75. package/dist/exports/control-api.d.mts.map +1 -1
  76. package/dist/exports/control-api.mjs +3 -3
  77. package/dist/exports/index.d.mts.map +1 -1
  78. package/dist/exports/index.mjs +1 -1
  79. package/dist/exports/index.mjs.map +1 -1
  80. package/dist/exports/init-output.d.mts.map +1 -1
  81. package/dist/exports/init-output.mjs +1 -1
  82. package/dist/{framework-components-65gOHkHB.mjs → framework-components-DTcjouhS.mjs} +2 -2
  83. package/dist/{framework-components-65gOHkHB.mjs.map → framework-components-DTcjouhS.mjs.map} +1 -1
  84. package/dist/global-flags-CdE7M0d9.d.mts.map +1 -1
  85. package/dist/graph-render-DJVv0_uf.mjs.map +1 -1
  86. package/dist/{init-YX6lCJpG.mjs → init-eGkSo7hi.mjs} +5 -5
  87. package/dist/{init-YX6lCJpG.mjs.map → init-eGkSo7hi.mjs.map} +1 -1
  88. package/dist/{inspect-live-schema-LeWvkZVz.mjs → inspect-live-schema-B1GCyjAJ.mjs} +5 -5
  89. package/dist/{inspect-live-schema-LeWvkZVz.mjs.map → inspect-live-schema-B1GCyjAJ.mjs.map} +1 -1
  90. package/dist/migration-cli.d.mts.map +1 -1
  91. package/dist/migration-cli.mjs.map +1 -1
  92. package/dist/{migration-command-scaffold-BtkunvFQ.mjs → migration-command-scaffold-CNdZl60X.mjs} +5 -5
  93. package/dist/{migration-command-scaffold-BtkunvFQ.mjs.map → migration-command-scaffold-CNdZl60X.mjs.map} +1 -1
  94. package/dist/migration-list-CnYiHrNV.mjs +288 -0
  95. package/dist/migration-list-CnYiHrNV.mjs.map +1 -0
  96. package/dist/{migration-plan-C2jeH1J5.mjs → migration-plan-BnmP_yNz.mjs} +346 -88
  97. package/dist/migration-plan-BnmP_yNz.mjs.map +1 -0
  98. package/dist/{migrations-CwZMa1Ck.mjs → migrations-C7YTBnLy.mjs} +11 -2
  99. package/dist/migrations-C7YTBnLy.mjs.map +1 -0
  100. package/dist/{output-BlsrGMEF.mjs → output-CUIdfYo5.mjs} +1 -1
  101. package/dist/{output-BlsrGMEF.mjs.map → output-CUIdfYo5.mjs.map} +1 -1
  102. package/dist/{progress-adapter-DFfvZcYL.mjs → progress-adapter-xASh41wr.mjs} +1 -1
  103. package/dist/{progress-adapter-DFfvZcYL.mjs.map → progress-adapter-xASh41wr.mjs.map} +1 -1
  104. package/dist/ref-advancement-CHJ_8HxQ.mjs +50 -0
  105. package/dist/ref-advancement-CHJ_8HxQ.mjs.map +1 -0
  106. package/dist/{types--CqjMdk0.d.mts → types-UWB2-rrw.d.mts} +12 -4
  107. package/dist/types-UWB2-rrw.d.mts.map +1 -0
  108. package/dist/{verify-Bom75OYI.mjs → verify-DX4RQwq4.mjs} +2 -2
  109. package/dist/{verify-Bom75OYI.mjs.map → verify-DX4RQwq4.mjs.map} +1 -1
  110. package/package.json +12 -12
  111. package/dist/cli-errors-Czmx92Zy.d.mts +0 -3
  112. package/dist/cli-errors-Djtz98Vm.mjs +0 -71
  113. package/dist/cli-errors-Djtz98Vm.mjs.map +0 -1
  114. package/dist/command-helpers-DtavI0wJ.mjs.map +0 -1
  115. package/dist/commands/migration-list.mjs.map +0 -1
  116. package/dist/contract-emit-bcrpT-wD.mjs.map +0 -1
  117. package/dist/contract-emit-uwT-Mj8-.mjs.map +0 -1
  118. package/dist/contract-enrichment-Dani0mMW.mjs.map +0 -1
  119. package/dist/migration-plan-C2jeH1J5.mjs.map +0 -1
  120. package/dist/migrations-CwZMa1Ck.mjs.map +0 -1
  121. package/dist/terminal-ui-BiB_8KNo.mjs +0 -379
  122. package/dist/terminal-ui-BiB_8KNo.mjs.map +0 -1
  123. package/dist/types--CqjMdk0.d.mts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-plan-BnmP_yNz.mjs","names":[],"sources":["../src/utils/contract-space-seed-phase.ts","../src/utils/plan-resolution.ts","../src/commands/migration-plan.ts"],"sourcesContent":["import { materialiseExtensionMigrationPackageIfMissing } from '@prisma-next/migration-tools/io';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport type { MigrationOps } from '@prisma-next/migration-tools/package';\nimport {\n emitContractSpaceArtefacts,\n planAllSpaces,\n readContractSpaceHeadRef,\n type SpacePlanOutput,\n spaceMigrationDirectory,\n} from '@prisma-next/migration-tools/spaces';\n\n/**\n * In-memory authored migration package shipped by an extension descriptor.\n * Mirrors `MigrationPackage` from `@prisma-next/migration-tools/io` (the\n * on-disk shape minus `dirPath`); redeclared structurally here so the\n * CLI helper does not couple to any family's `ExtensionMigrationPackage`\n * type — any family that ships pre-built migration packages can pass\n * them through unchanged.\n */\nexport interface DescriptorMigrationPackage {\n readonly dirName: string;\n readonly metadata: MigrationMetadata;\n readonly ops: MigrationOps;\n}\n\n/**\n * Minimal descriptor view consumed by the seed phase. Mirrors the shape\n * the SQL family ships on each declared extension entry; only the fields\n * the seed phase needs are surfaced.\n */\nexport interface SeedPhaseExtensionInput {\n readonly id: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: { readonly hash: string; readonly invariants: readonly string[] };\n readonly migrations: readonly DescriptorMigrationPackage[];\n };\n}\n\nexport interface ContractSpaceSeedPhaseInputs {\n readonly migrationsDir: string;\n readonly extensionPacks: ReadonlyArray<SeedPhaseExtensionInput>;\n}\n\n/**\n * One per-space record describing what the seed phase did for an\n * extension contract space. Surfaced verbatim by the caller (typically\n * `migration plan`) so users see a single line per touched extension.\n *\n * - `action: 'updated'` — either the on-disk head pointer changed, or\n * one or more new descriptor-shipped migration packages were\n * materialised into `migrations/<spaceId>/<dirName>/`.\n * - `action: 'unchanged'` — the on-disk head already matched the\n * descriptor and no new migration packages needed to be written.\n *\n * Either way, the artefacts (`contract.json`, `contract.d.ts`,\n * `refs/head.json`) are re-emitted: the framework owns those files and\n * makes the re-emit observably idempotent at the byte level.\n */\nexport interface ContractSpaceSeedPhaseRecord {\n readonly spaceId: string;\n readonly action: 'updated' | 'unchanged';\n readonly priorHash: string | null;\n readonly newHash: string;\n readonly newMigrationDirs: readonly string[];\n}\n\nexport interface ContractSpaceSeedPhaseResult {\n readonly seeded: readonly ContractSpaceSeedPhaseRecord[];\n}\n\n/**\n * Phase-1 of the two-phase `migration plan` pipeline (sub-spec § 4).\n *\n * For every extension that exposes a `contractSpace`:\n *\n * 1. Read the on-disk head ref (returns `null` on first emit).\n * 2. Re-emit `contract.json` / `contract.d.ts` / `refs/head.json`\n * unconditionally via {@link emitContractSpaceArtefacts}. The\n * framework owns these files; re-emit is the contract.\n * 3. Materialise any descriptor-shipped migration packages not yet on\n * disk via {@link materialiseExtensionMigrationPackageIfMissing}.\n * Existing packages are left untouched (by-existence skip).\n *\n * The return value lets the caller render a per-space status line and\n * lets the phase-2 aggregate loader run on a now-consistent disk state\n * (every loaded extension is guaranteed to have its head ref pinned\n * to the descriptor's hash and to ship every package the descriptor\n * declares).\n *\n * Output ordering is deterministic and alphabetical by spaceId (via\n * {@link planAllSpaces}, which also detects duplicate spaceIds). This\n * matches the canonical sort order used by every other aggregate\n * surface (`migrate`, `migration status`, the runner).\n */\nexport async function runContractSpaceSeedPhase(\n inputs: ContractSpaceSeedPhaseInputs,\n): Promise<ContractSpaceSeedPhaseResult> {\n const planInputs = inputs.extensionPacks\n .filter(\n (\n pack,\n ): pack is SeedPhaseExtensionInput & {\n contractSpace: NonNullable<SeedPhaseExtensionInput['contractSpace']>;\n } => pack.contractSpace !== undefined,\n )\n .map((pack) => ({\n spaceId: pack.id,\n priorContract: null,\n newContract: pack.contractSpace.contractJson,\n __pack: pack.contractSpace,\n }));\n\n // `planAllSpaces` brings deterministic alphabetical ordering and\n // duplicate-spaceId detection. The \"planner\" callback is a no-op\n // pass-through that simply returns the descriptor's pre-built\n // migration packages.\n const planned: readonly SpacePlanOutput<DescriptorMigrationPackage>[] = planAllSpaces(\n planInputs,\n (input) =>\n (\n input as typeof input & {\n readonly __pack: NonNullable<SeedPhaseExtensionInput['contractSpace']>;\n }\n ).__pack.migrations,\n );\n\n // Reassemble a spaceId → descriptor lookup so the loop below can read\n // the contractJson / headRef without leaking the typed-cast back into\n // `planAllSpaces`'s output shape.\n const descriptorBySpace = new Map<\n string,\n NonNullable<SeedPhaseExtensionInput['contractSpace']>\n >();\n for (const pack of inputs.extensionPacks) {\n if (pack.contractSpace !== undefined) descriptorBySpace.set(pack.id, pack.contractSpace);\n }\n\n const seeded: ContractSpaceSeedPhaseRecord[] = [];\n for (const space of planned) {\n const descriptor = descriptorBySpace.get(space.spaceId);\n if (descriptor === undefined) continue;\n\n const onDiskHeadRef = await readContractSpaceHeadRef(inputs.migrationsDir, space.spaceId);\n const priorHash = onDiskHeadRef?.hash ?? null;\n\n await emitContractSpaceArtefacts(inputs.migrationsDir, space.spaceId, {\n contract: descriptor.contractJson,\n contractDts: buildPlaceholderContractDts(space.spaceId),\n headRef: { hash: descriptor.headRef.hash, invariants: descriptor.headRef.invariants },\n });\n\n const spaceDir = spaceMigrationDirectory(inputs.migrationsDir, space.spaceId);\n const newMigrationDirs: string[] = [];\n for (const pkg of space.migrationPackages) {\n const { written } = await materialiseExtensionMigrationPackageIfMissing(spaceDir, pkg);\n if (written) newMigrationDirs.push(pkg.dirName);\n }\n\n const action: ContractSpaceSeedPhaseRecord['action'] =\n priorHash !== descriptor.headRef.hash || newMigrationDirs.length > 0\n ? 'updated'\n : 'unchanged';\n\n seeded.push({\n spaceId: space.spaceId,\n action,\n priorHash,\n newHash: descriptor.headRef.hash,\n newMigrationDirs,\n });\n }\n\n return { seeded };\n}\n\n/**\n * Placeholder `.d.ts` content for an extension space's on-disk mirror.\n *\n * Rendering a fully-typed `.d.ts` for an extension contract requires\n * the SQL-family renderer with the codec / typemap registry threaded\n * through; until that integration ships, the on-disk `.d.ts` is a\n * stub `export {};` module that documents how consumers should\n * validate the sibling `contract.json`. The stub typechecks on its\n * own and does not need any TypeScript suppressions.\n */\nfunction buildPlaceholderContractDts(spaceId: string): string {\n return [\n '/**',\n ` * Placeholder \\`.d.ts\\` for extension space \"${spaceId}\".`,\n ' *',\n ' * The framework re-emits this file on every `migration plan` run',\n ' * alongside `contract.json` and `refs/head.json`. A typed `.d.ts`',\n ' * rendering pass for extension contracts is tracked separately;',\n ' * until that ships, consumers should import `contract.json`',\n ' * and pass it through the target descriptor’s `contractSerializer`.',\n ' */',\n 'export {};',\n '',\n ].join('\\n');\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { ControlFamilyInstance } from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport type { MigrationGraph } from '@prisma-next/migration-tools/graph';\nimport {\n assertHashIsGraphNode,\n findLatestMigration,\n isGraphNode,\n} from '@prisma-next/migration-tools/migration-graph';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { Refs } from '@prisma-next/migration-tools/refs';\nimport { readRefSnapshot, readRefs } from '@prisma-next/migration-tools/refs';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorPlanForgotTheFlag,\n errorSnapshotMissing,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from './cli-errors';\n\nconst FULL_HASH_PATTERN = /^sha256:([0-9a-f]{64}|empty)$/;\n\nexport function looksLikeFullHash(input: string): boolean {\n return FULL_HASH_PATTERN.test(input);\n}\n\nexport type FromResolution =\n | { kind: 'greenfield'; fromHash: null; fromContract: null }\n | { kind: 'graph-node'; fromHash: string; fromContract: Contract; sourceDir: string }\n | {\n kind: 'snapshot';\n fromHash: string;\n fromContract: Contract;\n contractDts: string;\n contractJson: unknown;\n }\n | {\n kind: 'auto-baseline';\n fromHash: string;\n fromContract: Contract;\n contractDts: string;\n contractJson: unknown;\n };\n\nexport interface ResolveFromForPlanInput {\n readonly optionsFrom?: string | undefined;\n readonly refsDir: string;\n readonly bundles: readonly OnDiskMigrationPackage[];\n readonly graph: MigrationGraph;\n readonly familyInstance: ControlFamilyInstance<string, unknown>;\n readonly readBundleEndContract: (migrationDir: string) => Promise<Contract>;\n}\n\nfunction graphIsEmpty(bundles: readonly OnDiskMigrationPackage[]): boolean {\n return bundles.length === 0;\n}\n\nfunction getReachableRefs(\n refs: Refs,\n graph: MigrationGraph,\n): ReadonlyArray<{ name: string; hash: string }> {\n return Object.entries(refs)\n .flatMap(([name, entry]) =>\n entry && isGraphNode(entry.hash, graph) ? [{ name, hash: entry.hash }] : [],\n )\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport function assertFromIsGraphNode(\n fromHash: string,\n graph: MigrationGraph,\n refs: Refs,\n graphTipHash: string | null,\n): void {\n try {\n assertHashIsGraphNode(fromHash, graph);\n } catch (error) {\n if (MigrationToolsError.is(error) && error.code === 'MIGRATION.HASH_NOT_IN_GRAPH') {\n throw errorPlanForgotTheFlag(fromHash, getReachableRefs(refs, graph), graphTipHash);\n }\n throw error;\n }\n}\n\nasync function deserializeSnapshotContract(\n familyInstance: ControlFamilyInstance<string, unknown>,\n contract: unknown,\n): Promise<Result<Contract, CliStructuredError>> {\n try {\n return ok(familyInstance.deserializeContract(contract));\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorContractValidationFailed(\n `Ref snapshot contract failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: 'ref-snapshot' } },\n ),\n );\n }\n}\n\nasync function resolveGraphNodeFromBundle(\n fromHash: string,\n bundles: readonly OnDiskMigrationPackage[],\n readBundleEndContract: (migrationDir: string) => Promise<Contract>,\n explicitFromLabel?: string,\n): Promise<Result<Extract<FromResolution, { kind: 'graph-node' }>, CliStructuredError>> {\n const matchingBundle = bundles.find((pkg) => pkg.metadata.to === fromHash);\n if (!matchingBundle) {\n return notOk(\n errorUnexpected(\n explicitFromLabel\n ? `No migration bundle found for --from \"${explicitFromLabel}\" (resolved hash: ${fromHash})`\n : `No migration bundle found for graph node ${fromHash}`,\n {\n why: `The hash ${fromHash} is a graph node but no on-disk migration package has an end-contract hash matching it.`,\n fix: 'Provide a ref or hash that corresponds to an existing migration package, or run `migration list` to see available migrations.',\n },\n ),\n );\n }\n try {\n const fromContract = await readBundleEndContract(matchingBundle.dirPath);\n return ok({\n kind: 'graph-node',\n fromHash,\n fromContract,\n sourceDir: matchingBundle.dirPath,\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n throw error;\n }\n}\n\nasync function resolveFromRefName(\n refName: string,\n fromHash: string,\n input: ResolveFromForPlanInput,\n refs: Refs,\n): Promise<Result<FromResolution, CliStructuredError>> {\n const { refsDir, bundles, graph, familyInstance, readBundleEndContract } = input;\n const empty = graphIsEmpty(bundles);\n const graphTip = findLatestMigration(graph)?.to ?? null;\n\n let snapshot: Awaited<ReturnType<typeof readRefSnapshot>>;\n try {\n snapshot = await readRefSnapshot(refsDir, refName);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n if (snapshot) {\n const contractResult = await deserializeSnapshotContract(familyInstance, snapshot.contract);\n if (!contractResult.ok) {\n return contractResult;\n }\n const fromContract = contractResult.value;\n const { contractDts, contract: contractJson } = snapshot;\n if (empty) {\n return ok({ kind: 'auto-baseline', fromHash, fromContract, contractDts, contractJson });\n }\n try {\n assertFromIsGraphNode(fromHash, graph, refs, graphTip);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n throw error;\n }\n return ok({ kind: 'snapshot', fromHash, fromContract, contractDts, contractJson });\n }\n\n if (isGraphNode(fromHash, graph)) {\n return resolveGraphNodeFromBundle(fromHash, bundles, readBundleEndContract);\n }\n\n return notOk(errorSnapshotMissing(refName));\n}\n\nasync function resolveFromHashProvenance(\n fromHash: string,\n input: ResolveFromForPlanInput,\n _refs: Refs,\n explicitFromLabel?: string,\n): Promise<Result<FromResolution, CliStructuredError>> {\n const { bundles, graph } = input;\n\n if (isGraphNode(fromHash, graph)) {\n return resolveGraphNodeFromBundle(\n fromHash,\n bundles,\n input.readBundleEndContract,\n explicitFromLabel,\n );\n }\n\n throw new Error(\n `resolveFromHashProvenance: non-graph-node hash ${fromHash} should be refused via looksLikeFullHash before this helper is called`,\n );\n}\n\nexport async function resolveFromForPlan(\n input: ResolveFromForPlanInput,\n): Promise<Result<FromResolution, CliStructuredError>> {\n const { optionsFrom, refsDir, graph } = input;\n\n let refs: Refs;\n try {\n refs = await readRefs(refsDir);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n if (optionsFrom === undefined) {\n const dbRef = refs['db'];\n if (!dbRef) {\n return ok({ kind: 'greenfield', fromHash: null, fromContract: null });\n }\n return resolveFromRefName('db', dbRef.hash, input, refs);\n }\n\n const refResult = parseContractRef(optionsFrom, { graph, refs });\n if (!refResult.ok) {\n if (looksLikeFullHash(optionsFrom)) {\n const empty = graphIsEmpty(input.bundles);\n const graphTip = findLatestMigration(graph)?.to ?? null;\n if (empty) {\n return notOk(errorSnapshotMissing(optionsFrom, { viaRef: false }));\n }\n return notOk(errorPlanForgotTheFlag(optionsFrom, getReachableRefs(refs, graph), graphTip));\n }\n return notOk(mapRefResolutionError(refResult.failure));\n }\n\n const { hash: fromHash, provenance } = refResult.value;\n\n if (provenance.kind === 'ref') {\n return resolveFromRefName(provenance.refName, fromHash, input, refs);\n }\n\n return resolveFromHashProvenance(fromHash, input, refs, optionsFrom);\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport {\n type ControlFamilyInstance,\n createControlStack,\n hasOperationPreview,\n type MigrationPlanOperation,\n type OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { canonicalizeJson } from '@prisma-next/framework-components/utils';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { computeMigrationHash } from '@prisma-next/migration-tools/hash';\nimport { deriveProvidedInvariants } from '@prisma-next/migration-tools/invariants';\nimport {\n copyFilesWithRename,\n formatMigrationDirName,\n writeMigrationPackage,\n} from '@prisma-next/migration-tools/io';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join, relative } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport {\n type CliErrorConflict,\n CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorMigrationPlanningFailed,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n getTargetMigrations,\n loadMigrationPackages,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { buildContractSpaceAggregate } from '../utils/contract-space-aggregate-loader';\nimport { runContractSpaceSeedPhase } from '../utils/contract-space-seed-phase';\nimport { toExtensionInputs } from '../utils/extension-pack-inputs';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { resolveFromForPlan } from '../utils/plan-resolution';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationPlanOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly name?: string;\n readonly from?: string;\n}\n\n/**\n * Load a predecessor migration's destination contract from its sibling\n * `end-contract.json` on disk and route it through the family's\n * `ContractSerializer` (via `deserializeContract`) so the in-memory shape\n * is the hydrated `Contract` every other caller sees. Bypassing this\n * seam was the root cause of TML-2536: a raw `JSON.parse(...) as Contract`\n * here let polymorphic `storage.types` entries reach the planner without\n * the `kind` discriminator the planner dispatches on.\n *\n * Throws `CliStructuredError` with:\n * - `errorFileNotFound` when the sibling file is missing — the user\n * has likely deleted or never authored the snapshot, and the\n * message names the file and points them at re-emitting from the\n * source.\n * - `errorContractValidationFailed` when the JSON parses but the\n * family deserializer rejects it (legacy untagged shape, structural\n * mismatch, etc.) — the message names the predecessor's path so\n * the operator can locate the bad snapshot.\n */\nasync function readPredecessorEndContract(\n migrationDir: string,\n familyInstance: ControlFamilyInstance<string, unknown>,\n): Promise<Contract> {\n const path = join(migrationDir, 'end-contract.json');\n let raw: string;\n try {\n raw = await readFile(path, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n throw errorFileNotFound(path, {\n why: `Predecessor migration is missing its destination contract snapshot at ${path}`,\n fix: 'Re-emit the predecessor migration (`prisma-next migration plan` from its source) so its sibling `end-contract.json` is restored, then re-run this command.',\n });\n }\n throw error;\n }\n try {\n return familyInstance.deserializeContract(JSON.parse(raw) as unknown);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n throw error;\n }\n throw errorContractValidationFailed(\n `Predecessor contract at ${path} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path } },\n );\n }\n}\n\nasync function writeSnapshotContractArtifacts(\n packageDir: string,\n contractJson: unknown,\n contractDts: string,\n artifactBasename: 'start-contract' | 'end-contract',\n): Promise<void> {\n await mkdir(packageDir, { recursive: true });\n const jsonContent = `${canonicalizeJson(contractJson)}\\n`;\n const dtsContent = contractDts.endsWith('\\n') ? contractDts : `${contractDts}\\n`;\n await writeFile(join(packageDir, `${artifactBasename}.json`), jsonContent);\n await writeFile(join(packageDir, `${artifactBasename}.d.ts`), dtsContent);\n}\n\nasync function writeSnapshotStartContract(\n packageDir: string,\n contractJson: unknown,\n contractDts: string,\n): Promise<void> {\n await writeSnapshotContractArtifacts(packageDir, contractJson, contractDts, 'start-contract');\n}\n\ntype PlannerSuccess = {\n readonly plannedOps: readonly MigrationPlanOperation[];\n readonly migrationTsContent: string;\n readonly hasPlaceholders: boolean;\n};\n\ntype TargetMigrationsApi = NonNullable<ReturnType<typeof getTargetMigrations>>;\n\nasync function runPlannerLeg(\n planner: ReturnType<TargetMigrationsApi['createPlanner']>,\n migrations: TargetMigrationsApi,\n frameworkComponents: ReturnType<typeof assertFrameworkComponentsCompatible>,\n contract: Contract,\n fromContract: Contract | null,\n spaceId: string,\n): Promise<Result<PlannerSuccess, CliStructuredError>> {\n const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);\n const plannerResult = planner.plan({\n contract,\n schema: fromSchema,\n policy: { allowedOperationClasses: ['additive', 'widening', 'destructive', 'data'] },\n fromContract,\n frameworkComponents,\n spaceId,\n });\n if (plannerResult.kind === 'failure') {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: plannerResult.conflicts as readonly CliErrorConflict[],\n }),\n );\n }\n\n let plannedOps: readonly MigrationPlanOperation[] = [];\n let hasPlaceholders = false;\n try {\n plannedOps = plannerResult.plan.operations;\n if (plannedOps.length === 0) {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: [\n {\n kind: 'unsupportedChange',\n summary:\n 'Contract changed but planner produced no operations. ' +\n 'This indicates unsupported or ignored changes.',\n },\n ],\n }),\n );\n }\n } catch (e) {\n if (CliStructuredError.is(e) && e.domain === 'MIG' && e.code === '2001') {\n hasPlaceholders = true;\n } else {\n throw e;\n }\n }\n\n return ok({\n plannedOps,\n migrationTsContent: plannerResult.plan.renderTypeScript(),\n hasPlaceholders,\n });\n}\n\nasync function writePlannedMigrationPackage(\n packageDir: string,\n fromHash: string | null,\n toHash: string,\n createdAt: Date,\n leg: PlannerSuccess,\n): Promise<void> {\n const opsForWrite = leg.hasPlaceholders ? [] : leg.plannedOps;\n const metadataWithInvariants: Omit<MigrationMetadata, 'migrationHash'> = {\n from: fromHash,\n to: toHash,\n hints: {\n used: [],\n applied: [],\n plannerVersion: '2.0.0',\n },\n labels: [],\n providedInvariants: deriveProvidedInvariants(opsForWrite),\n createdAt: createdAt.toISOString(),\n };\n const metadata: MigrationMetadata = {\n ...metadataWithInvariants,\n migrationHash: computeMigrationHash(metadataWithInvariants, opsForWrite),\n };\n await writeMigrationPackage(packageDir, metadata, opsForWrite);\n await writeMigrationTs(packageDir, leg.migrationTsContent);\n}\n\nexport interface MigrationPlanResult {\n readonly ok: boolean;\n readonly noOp: boolean;\n readonly from: string | null;\n readonly to: string;\n readonly dir?: string;\n readonly baselineDir?: string;\n /**\n * Extension-space migration packages materialised onto disk during this\n * `plan` run. Each entry names a `migrations/<spaceId>/<dirName>/`\n * tree the framework wrote alongside the app-space migration directory.\n * Empty when the project has no extension packs declaring a contract\n * space, or when every extension-space package is already on disk.\n *\n * Surfacing these in the result (rather than only via `ui.step` log\n * lines) makes the cross-space side effect explicit to JSON consumers\n * and the success-summary renderer — the same multi-space side effect\n * that `migrate` will replay.\n */\n readonly emittedExtensionDirs: readonly { readonly spaceId: string; readonly dirName: string }[];\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the migration plan operations.\n * Replaces the previous `sql?: readonly string[]` field; consumers should\n * read `result.preview?.statements`.\n */\n readonly preview?: OperationPreview;\n readonly summary: string;\n /**\n * When true, `migration.ts` was written but contains unfilled\n * `placeholder(...)` calls. The user must edit the file and then run\n * `node migration.ts` to self-emit `ops.json` / `migration.json`.\n */\n readonly pendingPlaceholders?: boolean;\n readonly timings: {\n readonly total: number;\n };\n}\n\nasync function executeMigrationPlanCommand(\n options: MigrationPlanOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrationPlanResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative } =\n resolveMigrationPaths(options.config, config);\n\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (options.from) {\n details.push({ label: 'from', value: options.from });\n }\n if (options.name) {\n details.push({ label: 'name', value: options.name });\n }\n const header = formatStyledHeader({\n command: 'migration plan',\n description: 'Plan a migration from contract changes',\n url: 'https://pris.ly/migration-plan',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n // Load contract file (the \"to\" contract)\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Construct the family instance up-front so on-disk reads (the app\n // contract here + every `readPredecessorEndContract` below) cross the\n // serializer seam at the read site, not after the planner has already\n // started dispatching on raw shapes. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let toContract: Contract;\n try {\n toContract = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const rawStorageHash = toContract.storage?.storageHash;\n if (typeof rawStorageHash !== 'string') {\n return notOk(\n errorContractValidationFailed('Contract is missing storageHash', {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n const toStorageHash = rawStorageHash;\n\n const { refsDir } = resolveMigrationPaths(options.config, config);\n\n let fromContract: Contract | null = null;\n let fromHash: string | null = null;\n let fromContractSourceDir: string | null = null;\n let snapshotStartContract: { contractJson: unknown; contractDts: string } | null = null;\n let isAutoBaseline = false;\n\n try {\n const { bundles, graph } = await loadMigrationPackages(appMigrationsDir);\n\n const resolutionResult = await resolveFromForPlan({\n optionsFrom: options.from,\n refsDir,\n bundles,\n graph,\n familyInstance,\n readBundleEndContract: (migrationDir) =>\n readPredecessorEndContract(migrationDir, familyInstance),\n });\n\n if (!resolutionResult.ok) {\n return notOk(resolutionResult.failure);\n }\n\n switch (resolutionResult.value.kind) {\n case 'greenfield':\n break;\n case 'graph-node':\n fromHash = resolutionResult.value.fromHash;\n fromContract = resolutionResult.value.fromContract;\n fromContractSourceDir = resolutionResult.value.sourceDir;\n break;\n case 'snapshot':\n fromHash = resolutionResult.value.fromHash;\n fromContract = resolutionResult.value.fromContract;\n snapshotStartContract = {\n contractJson: resolutionResult.value.contractJson,\n contractDts: resolutionResult.value.contractDts,\n };\n break;\n case 'auto-baseline':\n fromHash = resolutionResult.value.fromHash;\n fromContract = resolutionResult.value.fromContract;\n snapshotStartContract = {\n contractJson: resolutionResult.value.contractJson,\n contractDts: resolutionResult.value.contractDts,\n };\n isAutoBaseline = true;\n break;\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n const message = error instanceof Error ? error.message : String(error);\n return notOk(\n errorUnexpected(message, {\n why: `Unexpected error while loading migrations: ${message}`,\n }),\n );\n }\n\n // Phase 1 — seed: unconditionally re-emit per-space pinned artefacts\n // (contract.json / contract.d.ts / refs/head.json) and materialise any\n // descriptor-shipped migration packages not yet on disk. Runs before\n // the no-op check so that an extension bump alone (with no structural\n // app-space change) still re-pins extension artefacts on disk.\n const canonicalExtensionInputs = toExtensionInputs(config.extensionPacks ?? []);\n const seedResult = await runContractSpaceSeedPhase({\n migrationsDir,\n extensionPacks: canonicalExtensionInputs,\n });\n if (!flags.json && !flags.quiet) {\n for (const record of seedResult.seeded) {\n if (record.action === 'updated') {\n const pkgSuffix =\n record.newMigrationDirs.length > 0\n ? `; ${record.newMigrationDirs.length} new migration package(s) materialised`\n : '';\n ui.step(`Updated ${record.spaceId} to ${record.newHash}${pkgSuffix}`);\n }\n }\n }\n const emittedExtensionDirs = seedResult.seeded.flatMap((r) =>\n r.newMigrationDirs.map((dirName) => ({ spaceId: r.spaceId, dirName })),\n );\n\n // Check for no-op (same hash means no changes). Auto-baseline is exempt:\n // an empty graph with db ref at the current contract still needs a\n // null → fromHash baseline bundle so migrate can anchor the marker.\n if (fromHash === toStorageHash && !isAutoBaseline) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: true,\n from: fromHash,\n to: toStorageHash,\n operations: [],\n emittedExtensionDirs,\n summary: 'No changes detected between contracts',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n // Check target supports migrations\n const migrations = getTargetMigrations(config.target);\n if (!migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n // Phase 2 — load: build the aggregate against the now-consistent disk\n // state that phase 1 just seeded. The seed phase guarantees every\n // declared extension has its head ref pinned, so the loader's\n // declaredButUnmigrated precheck always passes here. The app contract\n // was already routed through `familyInstance.deserializeContract` at the\n // read site above (see TML-2536), so it's the hydrated `Contract`\n // here — no second validation pass needed.\n const aggregateResult = await buildContractSpaceAggregate({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: toContract,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n if (!aggregateResult.ok) {\n return notOk(aggregateResult.failure);\n }\n const aggregate = aggregateResult.value;\n\n const frameworkComponents = assertFrameworkComponentsCompatible(\n config.family.familyId,\n config.target.targetId,\n [config.target, config.adapter, ...(config.extensionPacks ?? [])],\n );\n\n try {\n const planner = migrations.createPlanner(familyInstance);\n\n if (\n isAutoBaseline &&\n fromHash !== null &&\n fromContract !== null &&\n snapshotStartContract !== null\n ) {\n const baselineTimestamp = new Date();\n const deltaTimestamp = new Date(baselineTimestamp.getTime() + 60_000);\n const baselineDirName = formatMigrationDirName(baselineTimestamp, 'baseline');\n const deltaDirName = formatMigrationDirName(deltaTimestamp, options.name ?? 'migration');\n const baselinePackageDir = join(appMigrationsDir, baselineDirName);\n const deltaPackageDir = join(appMigrationsDir, deltaDirName);\n\n const baselineLeg = await runPlannerLeg(\n planner,\n migrations,\n frameworkComponents,\n fromContract,\n null,\n aggregate.app.spaceId,\n );\n if (!baselineLeg.ok) {\n return notOk(baselineLeg.failure);\n }\n\n await writePlannedMigrationPackage(\n baselinePackageDir,\n null,\n fromHash,\n baselineTimestamp,\n baselineLeg.value,\n );\n await writeSnapshotContractArtifacts(\n baselinePackageDir,\n snapshotStartContract.contractJson,\n snapshotStartContract.contractDts,\n 'end-contract',\n );\n\n if (fromHash === toStorageHash) {\n const baselineOps = baselineLeg.value.hasPlaceholders ? [] : baselineLeg.value.plannedOps;\n if (baselineLeg.value.hasPlaceholders) {\n const baselineDir = relative(process.cwd(), baselinePackageDir);\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: baselineDir,\n baselineDir,\n operations: [],\n emittedExtensionDirs,\n pendingPlaceholders: true,\n summary:\n 'Planned baseline with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const preview = hasOperationPreview(familyInstance)\n ? familyInstance.toOperationPreview(baselineOps)\n : undefined;\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n baselineDir: relative(process.cwd(), baselinePackageDir),\n operations: baselineOps.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n emittedExtensionDirs,\n ...(preview !== undefined ? { preview } : {}),\n summary: buildAutoBaselinePlanSummary(0, emittedExtensionDirs.length),\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const deltaLeg = await runPlannerLeg(\n planner,\n migrations,\n frameworkComponents,\n aggregate.app.contract,\n fromContract,\n aggregate.app.spaceId,\n );\n if (!deltaLeg.ok) {\n return notOk(deltaLeg.failure);\n }\n\n await writePlannedMigrationPackage(\n deltaPackageDir,\n fromHash,\n toStorageHash,\n deltaTimestamp,\n deltaLeg.value,\n );\n const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);\n await copyFilesWithRename(deltaPackageDir, [\n { sourcePath: destinationArtifacts.jsonPath, destName: 'end-contract.json' },\n { sourcePath: destinationArtifacts.dtsPath, destName: 'end-contract.d.ts' },\n ]);\n await writeSnapshotStartContract(\n deltaPackageDir,\n snapshotStartContract.contractJson,\n snapshotStartContract.contractDts,\n );\n\n const deltaOps = deltaLeg.value.hasPlaceholders ? [] : deltaLeg.value.plannedOps;\n if (deltaLeg.value.hasPlaceholders) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), deltaPackageDir),\n baselineDir: relative(process.cwd(), baselinePackageDir),\n operations: [],\n emittedExtensionDirs,\n pendingPlaceholders: true,\n summary:\n 'Planned baseline + migration with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const preview = hasOperationPreview(familyInstance)\n ? familyInstance.toOperationPreview(deltaOps)\n : undefined;\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), deltaPackageDir),\n baselineDir: relative(process.cwd(), baselinePackageDir),\n operations: deltaOps.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n emittedExtensionDirs,\n ...(preview !== undefined ? { preview } : {}),\n summary: buildAutoBaselinePlanSummary(deltaOps.length, emittedExtensionDirs.length),\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const timestamp = new Date();\n const slug = options.name ?? 'migration';\n const dirName = formatMigrationDirName(timestamp, slug);\n const packageDir = join(appMigrationsDir, dirName);\n\n const deltaLeg = await runPlannerLeg(\n planner,\n migrations,\n frameworkComponents,\n aggregate.app.contract,\n fromContract,\n aggregate.app.spaceId,\n );\n if (!deltaLeg.ok) {\n return notOk(deltaLeg.failure);\n }\n\n await writePlannedMigrationPackage(\n packageDir,\n fromHash,\n toStorageHash,\n timestamp,\n deltaLeg.value,\n );\n const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);\n await copyFilesWithRename(packageDir, [\n { sourcePath: destinationArtifacts.jsonPath, destName: 'end-contract.json' },\n { sourcePath: destinationArtifacts.dtsPath, destName: 'end-contract.d.ts' },\n ]);\n if (fromContractSourceDir !== null) {\n const sourceArtifacts = getEmittedArtifactPaths(\n join(fromContractSourceDir, 'end-contract.json'),\n );\n await copyFilesWithRename(packageDir, [\n { sourcePath: sourceArtifacts.jsonPath, destName: 'start-contract.json' },\n { sourcePath: sourceArtifacts.dtsPath, destName: 'start-contract.d.ts' },\n ]);\n } else if (snapshotStartContract !== null) {\n await writeSnapshotStartContract(\n packageDir,\n snapshotStartContract.contractJson,\n snapshotStartContract.contractDts,\n );\n }\n\n if (deltaLeg.value.hasPlaceholders) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), packageDir),\n operations: [],\n emittedExtensionDirs,\n pendingPlaceholders: true,\n summary:\n 'Planned migration with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const plannedOps = deltaLeg.value.plannedOps;\n const preview = hasOperationPreview(familyInstance)\n ? familyInstance.toOperationPreview(plannedOps)\n : undefined;\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), packageDir),\n operations: plannedOps.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n emittedExtensionDirs,\n ...(preview !== undefined ? { preview } : {}),\n summary: buildPlanSummary(plannedOps.length, emittedExtensionDirs.length),\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n const message = error instanceof Error ? error.message : String(error);\n return notOk(\n errorUnexpected(message, {\n why: `Unexpected error during migration plan: ${message}`,\n }),\n );\n }\n}\n\nexport function createMigrationPlanCommand(): Command {\n const command = new Command('plan');\n setCommandDescriptions(\n command,\n 'Plan a migration from contract changes',\n 'Compares the emitted contract against the latest on-disk migration state and\\n' +\n 'produces a new migration package with the required operations. No database\\n' +\n 'connection is needed — this is a fully offline operation.',\n );\n setCommandExamples(command, [\n 'prisma-next migration plan',\n 'prisma-next migration plan --name add-users-table',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--name <slug>', 'Name slug for the migration directory', 'migration')\n .option(\n '--from <contract>',\n 'Starting contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .action(async (options: MigrationPlanOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n const result = await executeMigrationPlanCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (planResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(planResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationPlanOutput(planResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n\n/**\n * Compose the success-line summary so the cross-space side effect\n * (extension-space migration packages materialised on disk during\n * this `plan` run) is visible in the top line — not just in the\n * step log above it.\n *\n * Example outputs:\n * - `Planned 3 operation(s)` (app-space-only project)\n * - `Planned 3 operation(s); materialised 1 extension-space migration` (one extension)\n * - `Planned 3 operation(s); materialised 2 extension-space migrations` (two extensions)\n *\n * Locks AC3 at the summary-line level: a reader of the success line\n * can tell that something happened beyond the app space.\n */\nfunction buildPlanSummary(plannedOpsCount: number, emittedExtensionDirsCount: number): string {\n const base = `Planned ${plannedOpsCount} operation(s)`;\n if (emittedExtensionDirsCount === 0) return base;\n const noun =\n emittedExtensionDirsCount === 1 ? 'extension-space migration' : 'extension-space migrations';\n return `${base}; materialised ${emittedExtensionDirsCount} ${noun}`;\n}\n\nfunction buildAutoBaselinePlanSummary(\n deltaOpsCount: number,\n emittedExtensionDirsCount: number,\n): string {\n const base = `Planned baseline + ${deltaOpsCount} operation(s)`;\n if (emittedExtensionDirsCount === 0) return base;\n const noun =\n emittedExtensionDirsCount === 1 ? 'extension-space migration' : 'extension-space migrations';\n return `${base}; materialised ${emittedExtensionDirsCount} ${noun}`;\n}\n\nexport function formatMigrationPlanOutput(result: MigrationPlanResult, flags: GlobalFlags): string {\n const lines: string[] = [];\n const useColor = flags.color !== false;\n\n const green_ = useColor ? (s: string) => `\\x1b[32m${s}\\x1b[0m` : (s: string) => s;\n const yellow_ = useColor ? (s: string) => `\\x1b[33m${s}\\x1b[0m` : (s: string) => s;\n const dim_ = useColor ? (s: string) => `\\x1b[2m${s}\\x1b[0m` : (s: string) => s;\n\n // Renders the extension-space materialisation block + canonical apply-step\n // hint shared by the no-op, placeholder, and full-plan branches. The app\n // space short-circuits do not skip it: an extension-only bump emits new\n // `migrations/<spaceId>/<dirName>/` directories on disk that the user\n // still has to apply, so the success line must surface them.\n function appendEmittedExtensions(): void {\n if (result.emittedExtensionDirs.length === 0) return;\n lines.push('');\n lines.push(dim_('Emitted extension migrations:'));\n for (const entry of result.emittedExtensionDirs) {\n lines.push(dim_(` ${entry.spaceId} → migrations/${entry.spaceId}/${entry.dirName}`));\n }\n lines.push('');\n lines.push(\n `Next: review the extension migrations above, then run ${green_('prisma-next migrate')}.`,\n );\n }\n\n if (result.noOp) {\n lines.push(`${green_('✔')} No changes detected`);\n lines.push(dim_(` from: ${result.from}`));\n lines.push(dim_(` to: ${result.to}`));\n appendEmittedExtensions();\n return lines.join('\\n');\n }\n\n if (result.pendingPlaceholders) {\n lines.push(`${yellow_('⚠')} ${result.summary}`);\n lines.push('');\n lines.push(dim_(`from: ${result.from}`));\n lines.push(dim_(`to: ${result.to}`));\n if (result.dir) {\n lines.push(dim_(`dir: ${result.dir}`));\n }\n lines.push('');\n lines.push(\n 'Open migration.ts and replace each `placeholder(...)` call with your actual query.',\n );\n lines.push(`Then run: ${green_(`node ${result.dir ?? '<dir>'}/migration.ts`)}`);\n appendEmittedExtensions();\n return lines.join('\\n');\n }\n\n lines.push(`${green_('✔')} ${result.summary}`);\n lines.push('');\n\n if (result.operations.length > 0) {\n lines.push(dim_('│'));\n for (let i = 0; i < result.operations.length; i++) {\n const op = result.operations[i]!;\n const isLast = i === result.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n // operationClass tag is intentionally NOT inlined per spec:\n // a destructive footer warning still surfaces below this list.\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${yellow_('(destructive)')}` : '';\n lines.push(`${dim_(treeChar)}─ ${op.label}${destructiveMarker}`);\n }\n\n const hasDestructive = result.operations.some((op) => op.operationClass === 'destructive');\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${yellow_('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n lines.push('');\n }\n\n lines.push(dim_(`from: ${result.from}`));\n lines.push(dim_(`to: ${result.to}`));\n if (result.baselineDir) {\n lines.push(dim_(`Baseline → ${result.baselineDir}`));\n }\n if (result.dir) {\n lines.push(dim_(`App space → ${result.dir}`));\n }\n // Per-space block: surface the extension-space directories materialised\n // alongside the app-space migration. Without this block the cross-space\n // side effect is invisible in the success summary (e2e finding F1).\n for (const entry of result.emittedExtensionDirs) {\n lines.push(\n dim_(`Extension space ${entry.spaceId} → migrations/${entry.spaceId}/${entry.dirName}`),\n );\n }\n\n lines.push('');\n // The \"Next:\" hint always points at the canonical apply path\n // (`prisma-next migrate`) regardless of how many spaces were\n // materialised — `db update` is a dev-time convenience, not the\n // canonical replay step.\n const reviewTarget =\n result.baselineDir !== undefined && result.dir !== undefined\n ? `${result.baselineDir} and ${result.dir}`\n : (result.baselineDir ?? result.dir ?? '<dir>');\n lines.push(\n `Next: review ${green_(reviewTarget)} if needed, then run ${green_('prisma-next migrate')}.`,\n );\n\n if (result.preview && result.preview.statements.length > 0) {\n // The non-empty length is already guaranteed by the surrounding check, so\n // a plain `every` here is equivalent to the helper in formatters/migrations.ts.\n const allSql = result.preview.statements.every((s) => s.language === 'sql');\n lines.push('');\n lines.push(dim_(allSql ? 'DDL preview' : 'Operation preview'));\n lines.push('');\n for (const statement of result.preview.statements) {\n const trimmed = statement.text.trim();\n if (!trimmed) continue;\n const line = statement.language === 'sql' && !trimmed.endsWith(';') ? `${trimmed};` : trimmed;\n lines.push(line);\n }\n }\n\n if (flags.verbose && result.timings) {\n lines.push('');\n lines.push(dim_(`Total time: ${result.timings.total}ms`));\n }\n\n return lines.join('\\n');\n}\n\nexport type PrefixResolutionFailure =\n | { reason: 'ambiguous'; count: number }\n | { reason: 'not-found' };\n\n/**\n * Resolve a migration package by **target contract hash** (`metadata.to`)\n * using exact match or prefix match.\n *\n * Note: matches `metadata.to` (the contract hash this migration produces),\n * not `metadata.migrationHash` (the package's content-addressed identity).\n * Tries exact match first, then prefix match (auto-prepending `sha256:` when\n * the needle omits the scheme). Returns the matched package on success, or a\n * discriminated failure indicating whether the prefix was ambiguous or simply\n * not found.\n *\n * @internal Exported for testing only.\n */\nexport function resolveBundleByPrefix<T extends { metadata: { to: string } }>(\n bundles: readonly T[],\n needle: string,\n): Result<T, PrefixResolutionFailure> {\n const exact = bundles.find((p) => p.metadata.to === needle);\n if (exact) return ok(exact);\n\n const prefixWithScheme = needle.startsWith('sha256:') ? needle : `sha256:${needle}`;\n const candidates = bundles.filter((p) => p.metadata.to.startsWith(prefixWithScheme));\n\n if (candidates.length === 1) return ok(candidates[0]!);\n if (candidates.length > 1) return notOk({ reason: 'ambiguous', count: candidates.length });\n return notOk({ reason: 'not-found' });\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { c as isVerbose, o as createColorFormatter, s as formatDim } from "./terminal-ui-BiB_8KNo.mjs";
1
+ import { A as formatDim, j as isVerbose, k as createColorFormatter } from "./command-helpers-BnqwTptC.mjs";
2
2
  import { cyan, green, yellow } from "colorette";
3
3
  //#region src/utils/formatters/migrations.ts
4
4
  /**
@@ -98,6 +98,10 @@ function formatMigrationPlanOutput(result, flags) {
98
98
  lines.push("");
99
99
  lines.push(`${formatDimText(`Destination hash: ${result.plan.destination.storageHash}`)}`);
100
100
  }
101
+ if (result.plannedAdvanceRef) {
102
+ lines.push("");
103
+ lines.push(formatDimText(`Would advance ref "${result.plannedAdvanceRef.name}" → ${result.plannedAdvanceRef.hash}`));
104
+ }
101
105
  const preview = result.plan?.preview;
102
106
  if (preview) {
103
107
  lines.push("");
@@ -128,6 +132,10 @@ function formatMigrationApplyCommandOutput(result, flags) {
128
132
  lines.push("");
129
133
  for (const line of formatPerSpaceBlock(result.perSpace, "apply", useColor)) lines.push(line);
130
134
  }
135
+ if (result.advancedRef) {
136
+ lines.push("");
137
+ lines.push(formatDimText(`Advanced ref "${result.advancedRef.name}" → ${result.advancedRef.hash}`));
138
+ }
131
139
  lines.push("");
132
140
  lines.push(formatDimText("Next: prisma-next migration status"));
133
141
  if (isVerbose(flags, 1) && result.timings) {
@@ -214,6 +222,7 @@ function formatMigrationApplyOutput(result, flags) {
214
222
  if (result.marker.profileHash) lines.push(`${formatDimText(` Profile hash: ${result.marker.profileHash}`)}`);
215
223
  }
216
224
  if (isVerbose(flags, 1)) lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);
225
+ if (result.advancedRef) lines.push(formatDimText(`Advanced ref "${result.advancedRef.name}" → ${result.advancedRef.hash}`));
217
226
  }
218
227
  return lines.join("\n");
219
228
  }
@@ -226,4 +235,4 @@ function formatMigrationJson(result) {
226
235
  //#endregion
227
236
  export { formatMigrationShowOutput as a, formatMigrationPlanOutput as i, formatMigrationApplyOutput as n, formatMigrationJson as r, formatMigrationApplyCommandOutput as t };
228
237
 
229
- //# sourceMappingURL=migrations-CwZMa1Ck.mjs.map
238
+ //# sourceMappingURL=migrations-C7YTBnLy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations-C7YTBnLy.mjs","names":[],"sources":["../src/utils/formatters/migrations.ts"],"sourcesContent":["import type { OperationPreview } from '@prisma-next/framework-components/control';\nimport { cyan, green, yellow } from 'colorette';\n\nimport type { AggregatePerSpaceExecutionEntry } from '../../control-api/types';\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim, isVerbose } from './helpers';\n\n/**\n * Render a single statement of an `OperationPreview` for the human-readable\n * preview block. SQL statements get a trailing `;` if missing so the rendered\n * preview is byte-identical to the legacy `string[]`-based renderer for SQL\n * targets. Other languages (`'mongodb-shell'`) render verbatim.\n */\nfunction renderPreviewStatement(text: string, language: string): string | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n if (language === 'sql') {\n return trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n }\n return trimmed;\n}\n\n/**\n * Choose the header label for a preview block. SQL-only previews keep the\n * legacy `DDL preview` label so the rendered output is byte-identical to the\n * pre-aggregate SQL CLI; previews from any other family — or a mix that\n * includes any non-SQL language — use the family-agnostic `Operation preview`\n * label.\n *\n * An empty `statements` array deliberately renders as `Operation preview`\n * rather than `DDL preview`: `Array.prototype.every` is vacuously true for\n * empty arrays, but we have no evidence the preview is SQL-only when no\n * statements are present, so the family-agnostic label is the safer default.\n */\nexport function previewBlockHeader(preview: OperationPreview): string {\n const allSql =\n preview.statements.length > 0 && preview.statements.every((s) => s.language === 'sql');\n return allSql ? 'DDL preview' : 'Operation preview';\n}\n\n// ============================================================================\n// Migration Command Output Formatters (shared by db init and db update)\n// ============================================================================\n\n/**\n * Shared CLI output type for migration commands (db init, db update).\n */\nexport interface MigrationCommandResult {\n readonly ok: true;\n readonly mode: 'plan' | 'apply';\n readonly plan: {\n readonly targetId: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the planned operations. Replaces the\n * previous `sql?: readonly string[]`. Consumers should read\n * `plan.preview?.statements`.\n */\n readonly preview?: OperationPreview;\n };\n readonly execution?: {\n readonly operationsPlanned: number;\n readonly operationsExecuted: number;\n };\n readonly marker?: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n /**\n * Per-space execution breakdown in canonical schedule order\n * (extensions alphabetically, then app). Surfaces per-space markers\n * and the ops grouped by space, so the CLI summary can name which\n * space each op and marker belongs to instead of flattening them\n * into a single ambiguous list. See {@link AggregatePerSpaceExecutionEntry}.\n */\n readonly perSpace?: ReadonlyArray<AggregatePerSpaceExecutionEntry>;\n readonly advancedRef?: { readonly name: string; readonly hash: string } | null;\n readonly plannedAdvanceRef?: { readonly name: string; readonly hash: string } | null;\n readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Render the shared per-space execution block consumed by the `db init`\n * / `db update` / `migrate` summaries. Always shows: space\n * label (`Extension space: <id>` or `App space`) → per-op lines under\n * each space → per-space marker hash (when known).\n *\n * `mode` controls the marker label phrasing — `'apply'` shows\n * `marker → <hash>` (post-apply), `'plan'` omits the marker line\n * entirely (no marker has been written yet).\n */\nexport function formatPerSpaceBlock(\n perSpace: ReadonlyArray<AggregatePerSpaceExecutionEntry>,\n mode: 'plan' | 'apply',\n useColor: boolean,\n): readonly string[] {\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatCyan = createColorFormatter(useColor, cyan);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n const lines: string[] = [];\n for (let s = 0; s < perSpace.length; s++) {\n const space = perSpace[s]!;\n if (s > 0) lines.push('');\n const header =\n space.kind === 'app'\n ? formatCyan('App space')\n : formatCyan(`Extension space: ${space.spaceId}`);\n lines.push(header);\n if (space.operations.length === 0) {\n lines.push(` ${formatDimText('(no operations)')}`);\n } else {\n for (let i = 0; i < space.operations.length; i++) {\n const op = space.operations[i]!;\n const isLast = i === space.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${formatYellow('(destructive)')}` : '';\n lines.push(` ${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);\n }\n }\n if (mode === 'apply' && space.marker) {\n lines.push(` ${formatDimText(`marker: ${space.marker.storageHash}`)}`);\n }\n }\n return lines;\n}\n\n/**\n * Formats human-readable output for migration commands (db init, db update) in plan mode.\n */\nexport function formatMigrationPlanOutput(\n result: MigrationCommandResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Plan summary\n const operationCount = result.plan?.operations.length ?? 0;\n const spaceCount = result.perSpace?.length ?? 0;\n if (spaceCount > 0) {\n lines.push(\n `${formatGreen('✔')} Planned ${operationCount} operation(s) across ${spaceCount} contract space${spaceCount === 1 ? '' : 's'}`,\n );\n } else {\n lines.push(`${formatGreen('✔')} Planned ${operationCount} operation(s)`);\n }\n\n const formatYellow = createColorFormatter(useColor, yellow);\n\n // Per-space breakdown takes precedence over the flat ops tree when\n // the aggregate flow surfaced one.\n if (result.perSpace && result.perSpace.length > 0) {\n lines.push('');\n lines.push(...formatPerSpaceBlock(result.perSpace, 'plan', useColor));\n const hasDestructive = result.perSpace.some((s) =>\n s.operations.some((op) => op.operationClass === 'destructive'),\n );\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${formatYellow('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n } else if (result.plan?.operations && result.plan.operations.length > 0) {\n // Single-space fallback (no aggregate breakdown). Same flat tree\n // we've always rendered.\n lines.push(`${formatDimText('│')}`);\n for (let i = 0; i < result.plan.operations.length; i++) {\n const op = result.plan.operations[i];\n if (!op) continue;\n const isLast = i === result.plan.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${formatYellow('(destructive)')}` : '';\n lines.push(`${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);\n }\n\n const hasDestructive = result.plan.operations.some((op) => op.operationClass === 'destructive');\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${formatYellow('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n }\n\n // Destination hash\n if (result.plan?.destination) {\n lines.push('');\n lines.push(`${formatDimText(`Destination hash: ${result.plan.destination.storageHash}`)}`);\n }\n\n if (result.plannedAdvanceRef) {\n lines.push('');\n lines.push(\n formatDimText(\n `Would advance ref \"${result.plannedAdvanceRef.name}\" → ${result.plannedAdvanceRef.hash}`,\n ),\n );\n }\n\n // Statement preview (any family that implements OperationPreviewCapable)\n const preview = result.plan?.preview;\n if (preview) {\n lines.push('');\n lines.push(`${formatDimText(previewBlockHeader(preview))}`);\n if (preview.statements.length === 0) {\n lines.push(`${formatDimText('No operations.')}`);\n } else {\n lines.push('');\n for (const statement of preview.statements) {\n const rendered = renderPreviewStatement(statement.text, statement.language);\n if (rendered) {\n lines.push(rendered);\n }\n }\n }\n }\n\n // Timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(`Total time: ${result.timings.total}ms`)}`);\n }\n\n // Note about dry run\n lines.push('');\n lines.push(`${formatDimText('This is a dry run. No changes were applied.')}`);\n lines.push(`${formatDimText('Run without --dry-run to apply changes.')}`);\n\n return lines.join('\\n');\n}\n\nexport interface MigrationApplyCommandOutputResult {\n readonly migrationsApplied: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName?: string;\n readonly migrationHash?: string;\n readonly from?: string;\n readonly to?: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n /**\n * Per-space breakdown in canonical schedule order (extensions\n * alphabetically, then app). Always present for the aggregate-walking\n * `migrate` command.\n */\n readonly perSpace: readonly AggregatePerSpaceExecutionEntry[];\n readonly timings?: {\n readonly total: number;\n };\n readonly advancedRef?: { readonly name: string; readonly hash: string } | null;\n}\n\nexport function formatMigrationApplyCommandOutput(\n result: MigrationApplyCommandOutputResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n\n if (result.perSpace.length > 0) {\n lines.push('');\n for (const line of formatPerSpaceBlock(result.perSpace, 'apply', useColor)) {\n lines.push(line);\n }\n }\n\n if (result.advancedRef) {\n lines.push('');\n lines.push(\n formatDimText(`Advanced ref \"${result.advancedRef.name}\" → ${result.advancedRef.hash}`),\n );\n }\n\n lines.push('');\n lines.push(formatDimText('Next: prisma-next migration status'));\n\n if (isVerbose(flags, 1) && result.timings) {\n lines.push('');\n lines.push(formatDimText(`Total time: ${result.timings.total}ms`));\n }\n\n return lines.join('\\n');\n}\n\ninterface MigrationShowSpacePresent {\n readonly kind: 'present';\n readonly spaceId: string;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string | null;\n readonly to: string;\n readonly migrationHash: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\ninterface MigrationShowSpaceMissing {\n readonly kind: 'missing';\n readonly spaceId: string;\n readonly summary: string;\n}\n\ntype MigrationShowSpaceResult = MigrationShowSpacePresent | MigrationShowSpaceMissing;\n\ninterface MigrationShowResult {\n readonly spaces: readonly MigrationShowSpaceResult[];\n}\n\nfunction formatSpaceShowBlock(\n space: MigrationShowSpacePresent,\n useColor: boolean,\n): readonly string[] {\n const formatGreen = createColorFormatter(useColor, green);\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n const lines: string[] = [];\n lines.push(`${formatGreen('✔')} ${space.dirName}`);\n lines.push(`${formatDimText(` from: ${space.from ?? '(baseline)'}`)}`);\n lines.push(`${formatDimText(` to: ${space.to}`)}`);\n lines.push(`${formatDimText(` migrationHash: ${space.migrationHash}`)}`);\n lines.push(`${formatDimText(` created: ${space.createdAt}`)}`);\n\n lines.push('');\n lines.push(`${space.operations.length} operation(s)`);\n\n if (space.operations.length > 0) {\n lines.push(`${formatDimText('│')}`);\n for (let i = 0; i < space.operations.length; i++) {\n const op = space.operations[i]!;\n const isLast = i === space.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${formatYellow('(destructive)')}` : '';\n lines.push(`${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);\n }\n\n const hasDestructive = space.operations.some((op) => op.operationClass === 'destructive');\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${formatYellow('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n }\n\n if (space.preview.statements.length > 0) {\n lines.push('');\n lines.push(`${formatDimText(previewBlockHeader(space.preview))}`);\n lines.push('');\n for (const statement of space.preview.statements) {\n const rendered = renderPreviewStatement(statement.text, statement.language);\n if (rendered) {\n lines.push(rendered);\n }\n }\n }\n\n return lines;\n}\n\nexport function formatMigrationShowOutput(result: MigrationShowResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n const multipleSpaces = result.spaces.length > 1;\n const lines: string[] = [];\n\n for (let i = 0; i < result.spaces.length; i++) {\n const space = result.spaces[i]!;\n if (multipleSpaces) {\n lines.push(formatDimText(`── ${space.spaceId} ──`));\n }\n if (space.kind === 'missing') {\n lines.push(formatDimText(` ${space.summary}`));\n } else {\n for (const line of formatSpaceShowBlock(space, useColor)) {\n lines.push(line);\n }\n }\n if (i < result.spaces.length - 1) {\n lines.push('');\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats human-readable output for migration commands (db init, db update) in apply mode.\n */\nexport function formatMigrationApplyOutput(\n result: MigrationCommandResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Success summary\n const executed = result.execution?.operationsExecuted ?? 0;\n const spaceCount = result.perSpace?.length ?? 0;\n\n if (executed === 0) {\n const acrossClause =\n spaceCount > 0 ? ` across ${spaceCount} contract space${spaceCount === 1 ? '' : 's'}` : '';\n lines.push(`${formatGreen('✔')} Database already matches contract${acrossClause}`);\n } else if (spaceCount > 0) {\n lines.push(\n `${formatGreen('✔')} Applied ${executed} operation(s) across ${spaceCount} contract space${spaceCount === 1 ? '' : 's'}`,\n );\n } else {\n lines.push(`${formatGreen('✔')} Applied ${executed} operation(s)`);\n }\n\n // Per-space breakdown — replaces the single ambiguous `Signature:`\n // line with a per-space marker + ops listing.\n if (result.perSpace && result.perSpace.length > 0) {\n lines.push('');\n lines.push(...formatPerSpaceBlock(result.perSpace, 'apply', useColor));\n lines.push('');\n lines.push(\n formatDimText(\n `Run 'prisma-next migration status' to confirm ${\n spaceCount === 1 ? 'the space is' : 'all spaces are'\n } up to date.`,\n ),\n );\n } else if (result.marker) {\n // Single-space fallback (no aggregate breakdown surfaced — e.g.\n // older callers / non-aggregate code paths). The label is\n // `App-space marker` (not `Signature`) so that when only one\n // marker is observable we still name what it covers explicitly.\n lines.push(`${formatDimText(` App-space marker: ${result.marker.storageHash}`)}`);\n if (result.marker.profileHash) {\n lines.push(`${formatDimText(` Profile hash: ${result.marker.profileHash}`)}`);\n }\n }\n\n // Timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n if (result.advancedRef) {\n lines.push(\n formatDimText(`Advanced ref \"${result.advancedRef.name}\" → ${result.advancedRef.hash}`),\n );\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for migration commands (db init, db update).\n */\nexport function formatMigrationJson(result: MigrationCommandResult): string {\n return JSON.stringify(result, null, 2);\n}\n"],"mappings":"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"}
@@ -107,4 +107,4 @@ function buildNextSteps(options) {
107
107
  //#endregion
108
108
  export { renderInitOutro as i, buildNextSteps as n, formatInitJson as r, InitOutputSchema as t };
109
109
 
110
- //# sourceMappingURL=output-BlsrGMEF.mjs.map
110
+ //# sourceMappingURL=output-CUIdfYo5.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"output-BlsrGMEF.mjs","names":[],"sources":["../src/commands/init/output.ts"],"sourcesContent":["import { type } from 'arktype';\nimport type { GlobalFlags } from '../../utils/global-flags';\nimport type { TerminalUI } from '../../utils/terminal-ui';\n\n/**\n * arktype schema for the structured success document `init --json` writes\n * to stdout (FR1.5). The same shape backs the human-readable outro\n * renderer (FR10), so the two output modes carry identical information.\n *\n * `target` is normalised to the user-facing flag value (`mongodb` rather\n * than the internal `mongo`) so consumers can round-trip the document\n * straight into a follow-up `--target` invocation.\n *\n * The `ok: true` literal is the documented success/error discriminator —\n * see [Style Guide § JSON Semantics](../../../../../../../docs/CLI%20Style%20Guide.md#json-semantics).\n * Error envelopes (`CliErrorEnvelope`) carry `ok: false` so consumers can\n * branch with `if (doc.ok)` without inspecting the rest of the structure.\n */\nexport const InitOutputSchema = type({\n ok: 'true',\n target: \"'postgres'|'mongodb'\",\n authoring: \"'psl'|'typescript'\",\n schemaPath: 'string',\n filesWritten: 'string[]',\n /**\n * FR9.1 — files removed from disk during this run. Populated only on\n * re-init when previously-emitted contract artefacts (`contract.json`,\n * `contract.d.ts`, `start-/end-contract.*`, `ops.json`,\n * `migration.json`) were left behind by an earlier run. Empty on a\n * green-field init.\n */\n filesDeleted: 'string[]',\n packagesInstalled: {\n skipped: 'boolean',\n deps: 'string[]',\n devDeps: 'string[]',\n },\n contractEmitted: 'boolean',\n nextSteps: 'string[]',\n warnings: 'string[]',\n});\n\nexport type InitOutput = typeof InitOutputSchema.infer;\n\n/**\n * Serialises the output document for `--json`. Sorted keys are not enforced\n * — `JSON.stringify` preserves insertion order, and the schema field order\n * is the documented order, which matches what users will see when they\n * `jq .` the result.\n */\nexport function formatInitJson(output: InitOutput): string {\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Renders the human-readable outro on stderr (FR10.1). Re-uses the same\n * data structure as the JSON output so the two stay in lock-step.\n *\n * Warnings come before \"Next steps\" because they describe state the user\n * needs to be aware of before acting on the next-steps list.\n */\nexport function renderInitOutro(ui: TerminalUI, output: InitOutput, flags: GlobalFlags): void {\n if (flags.quiet || flags.json) {\n return;\n }\n\n for (const warning of output.warnings) {\n ui.warn(warning);\n }\n\n const lines: string[] = [];\n lines.push(`Target: ${output.target}`);\n lines.push(`Authoring: ${output.authoring}`);\n lines.push(`Schema: ${output.schemaPath}`);\n lines.push('');\n lines.push('Files written:');\n for (const file of output.filesWritten) {\n lines.push(` • ${file}`);\n }\n\n if (output.filesDeleted.length > 0) {\n lines.push('');\n lines.push('Files deleted (stale contract artefacts):');\n for (const file of output.filesDeleted) {\n lines.push(` • ${file}`);\n }\n }\n\n if (!output.packagesInstalled.skipped) {\n lines.push('');\n lines.push('Packages installed:');\n for (const dep of output.packagesInstalled.deps) {\n lines.push(` • ${dep}`);\n }\n for (const dep of output.packagesInstalled.devDeps) {\n lines.push(` • ${dep} (dev)`);\n }\n }\n\n lines.push('');\n lines.push('Next steps:');\n for (const step of output.nextSteps) {\n lines.push(` ${step}`);\n }\n\n ui.note(lines.join('\\n'), 'Done');\n}\n\n/**\n * Builds the `nextSteps` array from the resolved scaffold state. Steps are\n * ordered by the workflow a user needs to follow: configure connection →\n * (emit if not yet done) → run a starter query → docs / agent skill.\n *\n * The strings are stable and human-readable; agents wanting to act on them\n * should match on substrings (e.g. \"DATABASE_URL\") rather than exact text,\n * since copy may evolve.\n */\nexport function buildNextSteps(options: {\n readonly target: 'postgres' | 'mongodb';\n readonly contractEmitted: boolean;\n readonly emitCommand: string;\n readonly schemaPath: string;\n /**\n * Whether the project-level Prisma Next skills install actually ran\n * and succeeded during this `init`. When false (the user passed\n * `--no-skill`, so the install was skipped), the\n * \"registered with your agent runtime\" step is omitted — the skip is\n * already surfaced in the warnings array with a manual-install hint.\n */\n readonly skillRegistered: boolean;\n}): string[] {\n const steps: string[] = [];\n let stepNumber = 1;\n const push = (text: string): void => {\n steps.push(`${stepNumber}. ${text}`);\n stepNumber += 1;\n };\n push('Set DATABASE_URL in your environment (export it or add it to .env).');\n if (!options.contractEmitted) {\n push(`Emit the contract: \\`${options.emitCommand}\\``);\n push(`Edit your schema at ${options.schemaPath}, then re-run the emit command.`);\n } else {\n push(`Edit your schema at ${options.schemaPath}, then re-run \\`${options.emitCommand}\\`.`);\n }\n push('Open prisma-next.md for a quick reference on how to write your first typed query.');\n if (options.skillRegistered) {\n push(\n 'Prisma Next skills are registered with your agent runtime — open the project in your IDE and ask the agent to add a model, run a query, or plan a migration.',\n );\n }\n return steps;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,MAAa,mBAAmB,KAAK;CACnC,IAAI;CACJ,QAAQ;CACR,WAAW;CACX,YAAY;CACZ,cAAc;;;;;;;;CAQd,cAAc;CACd,mBAAmB;EACjB,SAAS;EACT,MAAM;EACN,SAAS;EACV;CACD,iBAAiB;CACjB,WAAW;CACX,UAAU;CACX,CAAC;;;;;;;AAUF,SAAgB,eAAe,QAA4B;CACzD,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE;;;;;;;;;AAUxC,SAAgB,gBAAgB,IAAgB,QAAoB,OAA0B;CAC5F,IAAI,MAAM,SAAS,MAAM,MACvB;CAGF,KAAK,MAAM,WAAW,OAAO,UAC3B,GAAG,KAAK,QAAQ;CAGlB,MAAM,QAAkB,EAAE;CAC1B,MAAM,KAAK,cAAc,OAAO,SAAS;CACzC,MAAM,KAAK,cAAc,OAAO,YAAY;CAC5C,MAAM,KAAK,cAAc,OAAO,aAAa;CAC7C,MAAM,KAAK,GAAG;CACd,MAAM,KAAK,iBAAiB;CAC5B,KAAK,MAAM,QAAQ,OAAO,cACxB,MAAM,KAAK,OAAO,OAAO;CAG3B,IAAI,OAAO,aAAa,SAAS,GAAG;EAClC,MAAM,KAAK,GAAG;EACd,MAAM,KAAK,4CAA4C;EACvD,KAAK,MAAM,QAAQ,OAAO,cACxB,MAAM,KAAK,OAAO,OAAO;;CAI7B,IAAI,CAAC,OAAO,kBAAkB,SAAS;EACrC,MAAM,KAAK,GAAG;EACd,MAAM,KAAK,sBAAsB;EACjC,KAAK,MAAM,OAAO,OAAO,kBAAkB,MACzC,MAAM,KAAK,OAAO,MAAM;EAE1B,KAAK,MAAM,OAAO,OAAO,kBAAkB,SACzC,MAAM,KAAK,OAAO,IAAI,QAAQ;;CAIlC,MAAM,KAAK,GAAG;CACd,MAAM,KAAK,cAAc;CACzB,KAAK,MAAM,QAAQ,OAAO,WACxB,MAAM,KAAK,KAAK,OAAO;CAGzB,GAAG,KAAK,MAAM,KAAK,KAAK,EAAE,OAAO;;;;;;;;;;;AAYnC,SAAgB,eAAe,SAalB;CACX,MAAM,QAAkB,EAAE;CAC1B,IAAI,aAAa;CACjB,MAAM,QAAQ,SAAuB;EACnC,MAAM,KAAK,GAAG,WAAW,IAAI,OAAO;EACpC,cAAc;;CAEhB,KAAK,sEAAsE;CAC3E,IAAI,CAAC,QAAQ,iBAAiB;EAC5B,KAAK,wBAAwB,QAAQ,YAAY,IAAI;EACrD,KAAK,uBAAuB,QAAQ,WAAW,iCAAiC;QAEhF,KAAK,uBAAuB,QAAQ,WAAW,kBAAkB,QAAQ,YAAY,KAAK;CAE5F,KAAK,oFAAoF;CACzF,IAAI,QAAQ,iBACV,KACE,+JACD;CAEH,OAAO"}
1
+ {"version":3,"file":"output-CUIdfYo5.mjs","names":[],"sources":["../src/commands/init/output.ts"],"sourcesContent":["import { type } from 'arktype';\nimport type { GlobalFlags } from '../../utils/global-flags';\nimport type { TerminalUI } from '../../utils/terminal-ui';\n\n/**\n * arktype schema for the structured success document `init --json` writes\n * to stdout (FR1.5). The same shape backs the human-readable outro\n * renderer (FR10), so the two output modes carry identical information.\n *\n * `target` is normalised to the user-facing flag value (`mongodb` rather\n * than the internal `mongo`) so consumers can round-trip the document\n * straight into a follow-up `--target` invocation.\n *\n * The `ok: true` literal is the documented success/error discriminator —\n * see [Style Guide § JSON Semantics](../../../../../../../docs/CLI%20Style%20Guide.md#json-semantics).\n * Error envelopes (`CliErrorEnvelope`) carry `ok: false` so consumers can\n * branch with `if (doc.ok)` without inspecting the rest of the structure.\n */\nexport const InitOutputSchema = type({\n ok: 'true',\n target: \"'postgres'|'mongodb'\",\n authoring: \"'psl'|'typescript'\",\n schemaPath: 'string',\n filesWritten: 'string[]',\n /**\n * FR9.1 — files removed from disk during this run. Populated only on\n * re-init when previously-emitted contract artefacts (`contract.json`,\n * `contract.d.ts`, `start-/end-contract.*`, `ops.json`,\n * `migration.json`) were left behind by an earlier run. Empty on a\n * green-field init.\n */\n filesDeleted: 'string[]',\n packagesInstalled: {\n skipped: 'boolean',\n deps: 'string[]',\n devDeps: 'string[]',\n },\n contractEmitted: 'boolean',\n nextSteps: 'string[]',\n warnings: 'string[]',\n});\n\nexport type InitOutput = typeof InitOutputSchema.infer;\n\n/**\n * Serialises the output document for `--json`. Sorted keys are not enforced\n * — `JSON.stringify` preserves insertion order, and the schema field order\n * is the documented order, which matches what users will see when they\n * `jq .` the result.\n */\nexport function formatInitJson(output: InitOutput): string {\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Renders the human-readable outro on stderr (FR10.1). Re-uses the same\n * data structure as the JSON output so the two stay in lock-step.\n *\n * Warnings come before \"Next steps\" because they describe state the user\n * needs to be aware of before acting on the next-steps list.\n */\nexport function renderInitOutro(ui: TerminalUI, output: InitOutput, flags: GlobalFlags): void {\n if (flags.quiet || flags.json) {\n return;\n }\n\n for (const warning of output.warnings) {\n ui.warn(warning);\n }\n\n const lines: string[] = [];\n lines.push(`Target: ${output.target}`);\n lines.push(`Authoring: ${output.authoring}`);\n lines.push(`Schema: ${output.schemaPath}`);\n lines.push('');\n lines.push('Files written:');\n for (const file of output.filesWritten) {\n lines.push(` • ${file}`);\n }\n\n if (output.filesDeleted.length > 0) {\n lines.push('');\n lines.push('Files deleted (stale contract artefacts):');\n for (const file of output.filesDeleted) {\n lines.push(` • ${file}`);\n }\n }\n\n if (!output.packagesInstalled.skipped) {\n lines.push('');\n lines.push('Packages installed:');\n for (const dep of output.packagesInstalled.deps) {\n lines.push(` • ${dep}`);\n }\n for (const dep of output.packagesInstalled.devDeps) {\n lines.push(` • ${dep} (dev)`);\n }\n }\n\n lines.push('');\n lines.push('Next steps:');\n for (const step of output.nextSteps) {\n lines.push(` ${step}`);\n }\n\n ui.note(lines.join('\\n'), 'Done');\n}\n\n/**\n * Builds the `nextSteps` array from the resolved scaffold state. Steps are\n * ordered by the workflow a user needs to follow: configure connection →\n * (emit if not yet done) → run a starter query → docs / agent skill.\n *\n * The strings are stable and human-readable; agents wanting to act on them\n * should match on substrings (e.g. \"DATABASE_URL\") rather than exact text,\n * since copy may evolve.\n */\nexport function buildNextSteps(options: {\n readonly target: 'postgres' | 'mongodb';\n readonly contractEmitted: boolean;\n readonly emitCommand: string;\n readonly schemaPath: string;\n /**\n * Whether the project-level Prisma Next skills install actually ran\n * and succeeded during this `init`. When false (the user passed\n * `--no-skill`, so the install was skipped), the\n * \"registered with your agent runtime\" step is omitted — the skip is\n * already surfaced in the warnings array with a manual-install hint.\n */\n readonly skillRegistered: boolean;\n}): string[] {\n const steps: string[] = [];\n let stepNumber = 1;\n const push = (text: string): void => {\n steps.push(`${stepNumber}. ${text}`);\n stepNumber += 1;\n };\n push('Set DATABASE_URL in your environment (export it or add it to .env).');\n if (!options.contractEmitted) {\n push(`Emit the contract: \\`${options.emitCommand}\\``);\n push(`Edit your schema at ${options.schemaPath}, then re-run the emit command.`);\n } else {\n push(`Edit your schema at ${options.schemaPath}, then re-run \\`${options.emitCommand}\\`.`);\n }\n push('Open prisma-next.md for a quick reference on how to write your first typed query.');\n if (options.skillRegistered) {\n push(\n 'Prisma Next skills are registered with your agent runtime — open the project in your IDE and ask the agent to add a model, run a query, or plan a migration.',\n );\n }\n return steps;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,MAAa,mBAAmB,KAAK;CACnC,IAAI;CACJ,QAAQ;CACR,WAAW;CACX,YAAY;CACZ,cAAc;;;;;;;;CAQd,cAAc;CACd,mBAAmB;EACjB,SAAS;EACT,MAAM;EACN,SAAS;CACX;CACA,iBAAiB;CACjB,WAAW;CACX,UAAU;AACZ,CAAC;;;;;;;AAUD,SAAgB,eAAe,QAA4B;CACzD,OAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AACvC;;;;;;;;AASA,SAAgB,gBAAgB,IAAgB,QAAoB,OAA0B;CAC5F,IAAI,MAAM,SAAS,MAAM,MACvB;CAGF,KAAK,MAAM,WAAW,OAAO,UAC3B,GAAG,KAAK,OAAO;CAGjB,MAAM,QAAkB,CAAC;CACzB,MAAM,KAAK,cAAc,OAAO,QAAQ;CACxC,MAAM,KAAK,cAAc,OAAO,WAAW;CAC3C,MAAM,KAAK,cAAc,OAAO,YAAY;CAC5C,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,gBAAgB;CAC3B,KAAK,MAAM,QAAQ,OAAO,cACxB,MAAM,KAAK,OAAO,MAAM;CAG1B,IAAI,OAAO,aAAa,SAAS,GAAG;EAClC,MAAM,KAAK,EAAE;EACb,MAAM,KAAK,2CAA2C;EACtD,KAAK,MAAM,QAAQ,OAAO,cACxB,MAAM,KAAK,OAAO,MAAM;CAE5B;CAEA,IAAI,CAAC,OAAO,kBAAkB,SAAS;EACrC,MAAM,KAAK,EAAE;EACb,MAAM,KAAK,qBAAqB;EAChC,KAAK,MAAM,OAAO,OAAO,kBAAkB,MACzC,MAAM,KAAK,OAAO,KAAK;EAEzB,KAAK,MAAM,OAAO,OAAO,kBAAkB,SACzC,MAAM,KAAK,OAAO,IAAI,OAAO;CAEjC;CAEA,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,aAAa;CACxB,KAAK,MAAM,QAAQ,OAAO,WACxB,MAAM,KAAK,KAAK,MAAM;CAGxB,GAAG,KAAK,MAAM,KAAK,IAAI,GAAG,MAAM;AAClC;;;;;;;;;;AAWA,SAAgB,eAAe,SAalB;CACX,MAAM,QAAkB,CAAC;CACzB,IAAI,aAAa;CACjB,MAAM,QAAQ,SAAuB;EACnC,MAAM,KAAK,GAAG,WAAW,IAAI,MAAM;EACnC,cAAc;CAChB;CACA,KAAK,qEAAqE;CAC1E,IAAI,CAAC,QAAQ,iBAAiB;EAC5B,KAAK,wBAAwB,QAAQ,YAAY,GAAG;EACpD,KAAK,uBAAuB,QAAQ,WAAW,gCAAgC;CACjF,OACE,KAAK,uBAAuB,QAAQ,WAAW,kBAAkB,QAAQ,YAAY,IAAI;CAE3F,KAAK,mFAAmF;CACxF,IAAI,QAAQ,iBACV,KACE,8JACF;CAEF,OAAO;AACT"}
@@ -40,4 +40,4 @@ function createProgressAdapter(options) {
40
40
  //#endregion
41
41
  export { createProgressAdapter as t };
42
42
 
43
- //# sourceMappingURL=progress-adapter-DFfvZcYL.mjs.map
43
+ //# sourceMappingURL=progress-adapter-xASh41wr.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress-adapter-DFfvZcYL.mjs","names":[],"sources":["../src/utils/progress-adapter.ts"],"sourcesContent":["import type { SpinnerResult } from '@clack/prompts';\nimport type { ControlProgressEvent, OnControlProgress } from '../control-api/types';\nimport type { GlobalFlags } from './global-flags';\nimport type { TerminalUI } from './terminal-ui';\n\n/**\n * Options for creating a progress adapter.\n */\ninterface ProgressAdapterOptions {\n readonly ui: TerminalUI;\n readonly flags: GlobalFlags;\n}\n\n/**\n * State for tracking active spans in the progress adapter.\n */\ninterface SpanState {\n readonly spinner: SpinnerResult;\n readonly startTime: number;\n readonly label: string;\n}\n\n/**\n * Creates a progress adapter that converts control-api progress events\n * into CLI spinner/progress output on stderr.\n *\n * The adapter:\n * - Starts/succeeds spinners for top-level span boundaries\n * - Prints per-operation lines for nested spans (e.g., migration operations under 'apply')\n * - Respects quiet/json/non-TTY flags (no-op in those cases)\n */\nexport function createProgressAdapter(options: ProgressAdapterOptions): OnControlProgress {\n const { ui, flags } = options;\n\n // Skip progress if quiet, JSON output, or non-interactive\n if (flags.quiet || flags.json || !ui.isInteractive) {\n return () => {};\n }\n\n // Track active spans by spanId\n const activeSpans = new Map<string, SpanState>();\n\n return (event: ControlProgressEvent) => {\n if (event.kind === 'spanStart') {\n // Nested spans (with parentSpanId) are printed as step lines\n if (event.parentSpanId) {\n ui.step(`${event.label}...`);\n return;\n }\n\n // Top-level spans get a spinner\n const spinner = ui.spinner();\n spinner.start(event.label);\n\n activeSpans.set(event.spanId, {\n spinner,\n startTime: Date.now(),\n label: event.label,\n });\n } else if (event.kind === 'spanEnd') {\n const spanState = activeSpans.get(event.spanId);\n if (spanState) {\n const elapsed = Date.now() - spanState.startTime;\n if (event.outcome === 'error') {\n spanState.spinner.error(`${spanState.label} (failed)`);\n } else if (event.outcome === 'skipped') {\n spanState.spinner.stop(`${spanState.label} (skipped)`);\n } else {\n spanState.spinner.stop(`${spanState.label} (${elapsed}ms)`);\n }\n activeSpans.delete(event.spanId);\n }\n }\n };\n}\n"],"mappings":";;;;;;;;;;AA+BA,SAAgB,sBAAsB,SAAoD;CACxF,MAAM,EAAE,IAAI,UAAU;CAGtB,IAAI,MAAM,SAAS,MAAM,QAAQ,CAAC,GAAG,eACnC,aAAa;CAIf,MAAM,8BAAc,IAAI,KAAwB;CAEhD,QAAQ,UAAgC;EACtC,IAAI,MAAM,SAAS,aAAa;GAE9B,IAAI,MAAM,cAAc;IACtB,GAAG,KAAK,GAAG,MAAM,MAAM,KAAK;IAC5B;;GAIF,MAAM,UAAU,GAAG,SAAS;GAC5B,QAAQ,MAAM,MAAM,MAAM;GAE1B,YAAY,IAAI,MAAM,QAAQ;IAC5B;IACA,WAAW,KAAK,KAAK;IACrB,OAAO,MAAM;IACd,CAAC;SACG,IAAI,MAAM,SAAS,WAAW;GACnC,MAAM,YAAY,YAAY,IAAI,MAAM,OAAO;GAC/C,IAAI,WAAW;IACb,MAAM,UAAU,KAAK,KAAK,GAAG,UAAU;IACvC,IAAI,MAAM,YAAY,SACpB,UAAU,QAAQ,MAAM,GAAG,UAAU,MAAM,WAAW;SACjD,IAAI,MAAM,YAAY,WAC3B,UAAU,QAAQ,KAAK,GAAG,UAAU,MAAM,YAAY;SAEtD,UAAU,QAAQ,KAAK,GAAG,UAAU,MAAM,IAAI,QAAQ,KAAK;IAE7D,YAAY,OAAO,MAAM,OAAO"}
1
+ {"version":3,"file":"progress-adapter-xASh41wr.mjs","names":[],"sources":["../src/utils/progress-adapter.ts"],"sourcesContent":["import type { SpinnerResult } from '@clack/prompts';\nimport type { ControlProgressEvent, OnControlProgress } from '../control-api/types';\nimport type { GlobalFlags } from './global-flags';\nimport type { TerminalUI } from './terminal-ui';\n\n/**\n * Options for creating a progress adapter.\n */\ninterface ProgressAdapterOptions {\n readonly ui: TerminalUI;\n readonly flags: GlobalFlags;\n}\n\n/**\n * State for tracking active spans in the progress adapter.\n */\ninterface SpanState {\n readonly spinner: SpinnerResult;\n readonly startTime: number;\n readonly label: string;\n}\n\n/**\n * Creates a progress adapter that converts control-api progress events\n * into CLI spinner/progress output on stderr.\n *\n * The adapter:\n * - Starts/succeeds spinners for top-level span boundaries\n * - Prints per-operation lines for nested spans (e.g., migration operations under 'apply')\n * - Respects quiet/json/non-TTY flags (no-op in those cases)\n */\nexport function createProgressAdapter(options: ProgressAdapterOptions): OnControlProgress {\n const { ui, flags } = options;\n\n // Skip progress if quiet, JSON output, or non-interactive\n if (flags.quiet || flags.json || !ui.isInteractive) {\n return () => {};\n }\n\n // Track active spans by spanId\n const activeSpans = new Map<string, SpanState>();\n\n return (event: ControlProgressEvent) => {\n if (event.kind === 'spanStart') {\n // Nested spans (with parentSpanId) are printed as step lines\n if (event.parentSpanId) {\n ui.step(`${event.label}...`);\n return;\n }\n\n // Top-level spans get a spinner\n const spinner = ui.spinner();\n spinner.start(event.label);\n\n activeSpans.set(event.spanId, {\n spinner,\n startTime: Date.now(),\n label: event.label,\n });\n } else if (event.kind === 'spanEnd') {\n const spanState = activeSpans.get(event.spanId);\n if (spanState) {\n const elapsed = Date.now() - spanState.startTime;\n if (event.outcome === 'error') {\n spanState.spinner.error(`${spanState.label} (failed)`);\n } else if (event.outcome === 'skipped') {\n spanState.spinner.stop(`${spanState.label} (skipped)`);\n } else {\n spanState.spinner.stop(`${spanState.label} (${elapsed}ms)`);\n }\n activeSpans.delete(event.spanId);\n }\n }\n };\n}\n"],"mappings":";;;;;;;;;;AA+BA,SAAgB,sBAAsB,SAAoD;CACxF,MAAM,EAAE,IAAI,UAAU;CAGtB,IAAI,MAAM,SAAS,MAAM,QAAQ,CAAC,GAAG,eACnC,aAAa,CAAC;CAIhB,MAAM,8BAAc,IAAI,IAAuB;CAE/C,QAAQ,UAAgC;EACtC,IAAI,MAAM,SAAS,aAAa;GAE9B,IAAI,MAAM,cAAc;IACtB,GAAG,KAAK,GAAG,MAAM,MAAM,IAAI;IAC3B;GACF;GAGA,MAAM,UAAU,GAAG,QAAQ;GAC3B,QAAQ,MAAM,MAAM,KAAK;GAEzB,YAAY,IAAI,MAAM,QAAQ;IAC5B;IACA,WAAW,KAAK,IAAI;IACpB,OAAO,MAAM;GACf,CAAC;EACH,OAAO,IAAI,MAAM,SAAS,WAAW;GACnC,MAAM,YAAY,YAAY,IAAI,MAAM,MAAM;GAC9C,IAAI,WAAW;IACb,MAAM,UAAU,KAAK,IAAI,IAAI,UAAU;IACvC,IAAI,MAAM,YAAY,SACpB,UAAU,QAAQ,MAAM,GAAG,UAAU,MAAM,UAAU;SAChD,IAAI,MAAM,YAAY,WAC3B,UAAU,QAAQ,KAAK,GAAG,UAAU,MAAM,WAAW;SAErD,UAAU,QAAQ,KAAK,GAAG,UAAU,MAAM,IAAI,QAAQ,IAAI;IAE5D,YAAY,OAAO,MAAM,MAAM;GACjC;EACF;CACF;AACF"}
@@ -0,0 +1,50 @@
1
+ import { ifDefined } from "@prisma-next/utils/defined";
2
+ import { readFile } from "node:fs/promises";
3
+ import { writeRefPaired } from "@prisma-next/migration-tools/refs";
4
+ //#region src/utils/ref-advancement.ts
5
+ function computeRefAdvancementName(options) {
6
+ if (options.advanceRef !== void 0) return options.advanceRef;
7
+ if (options.db === void 0) return "db";
8
+ return null;
9
+ }
10
+ async function readContractIR(contractJson, contractJsonPath) {
11
+ return {
12
+ contract: contractJson,
13
+ contractDts: await readFile(contractJsonPath.replace(/\.json$/i, ".d.ts"), "utf-8")
14
+ };
15
+ }
16
+ async function executeRefAdvancement(refsDir, name, hash, contractIR) {
17
+ await writeRefPaired(refsDir, name, {
18
+ hash,
19
+ invariants: []
20
+ }, contractIR);
21
+ return {
22
+ name,
23
+ hash
24
+ };
25
+ }
26
+ async function buildRefAdvancementFields(options) {
27
+ const name = computeRefAdvancementName({
28
+ ...ifDefined("advanceRef", options.advanceRef),
29
+ ...ifDefined("db", options.db)
30
+ });
31
+ if (name === null) return {
32
+ advancedRef: null,
33
+ plannedAdvanceRef: null
34
+ };
35
+ if (options.mode === "plan") return {
36
+ advancedRef: null,
37
+ plannedAdvanceRef: {
38
+ name,
39
+ hash: options.hash
40
+ }
41
+ };
42
+ return {
43
+ advancedRef: await executeRefAdvancement(options.refsDir, name, options.hash, options.contractIR),
44
+ plannedAdvanceRef: null
45
+ };
46
+ }
47
+ //#endregion
48
+ export { readContractIR as i, computeRefAdvancementName as n, executeRefAdvancement as r, buildRefAdvancementFields as t };
49
+
50
+ //# sourceMappingURL=ref-advancement-CHJ_8HxQ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref-advancement-CHJ_8HxQ.mjs","names":[],"sources":["../src/utils/ref-advancement.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { ContractIR } from '@prisma-next/migration-tools/refs';\nimport { writeRefPaired } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\nexport interface RefAdvancementFields {\n readonly advancedRef: { readonly name: string; readonly hash: string } | null;\n readonly plannedAdvanceRef: { readonly name: string; readonly hash: string } | null;\n}\n\nexport function computeRefAdvancementName(options: {\n readonly advanceRef?: string;\n readonly db?: string;\n}): string | null {\n if (options.advanceRef !== undefined) {\n return options.advanceRef;\n }\n if (options.db === undefined) {\n return 'db';\n }\n return null;\n}\n\nexport async function readContractIR(\n contractJson: Record<string, unknown>,\n contractJsonPath: string,\n): Promise<ContractIR> {\n const contractDtsPath = contractJsonPath.replace(/\\.json$/i, '.d.ts');\n const contractDts = await readFile(contractDtsPath, 'utf-8');\n return { contract: contractJson, contractDts };\n}\n\nexport async function executeRefAdvancement(\n refsDir: string,\n name: string,\n hash: string,\n contractIR: ContractIR,\n): Promise<{ name: string; hash: string }> {\n await writeRefPaired(refsDir, name, { hash, invariants: [] }, contractIR);\n return { name, hash };\n}\n\nexport async function buildRefAdvancementFields(options: {\n readonly advanceRef?: string;\n readonly db?: string;\n readonly refsDir: string;\n readonly contractIR: ContractIR;\n readonly mode: 'plan' | 'apply';\n readonly hash: string;\n}): Promise<RefAdvancementFields> {\n const name = computeRefAdvancementName({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n });\n if (name === null) {\n return { advancedRef: null, plannedAdvanceRef: null };\n }\n if (options.mode === 'plan') {\n return { advancedRef: null, plannedAdvanceRef: { name, hash: options.hash } };\n }\n const advancedRef = await executeRefAdvancement(\n options.refsDir,\n name,\n options.hash,\n options.contractIR,\n );\n return { advancedRef, plannedAdvanceRef: null };\n}\n"],"mappings":";;;;AAUA,SAAgB,0BAA0B,SAGxB;CAChB,IAAI,QAAQ,eAAe,KAAA,GACzB,OAAO,QAAQ;CAEjB,IAAI,QAAQ,OAAO,KAAA,GACjB,OAAO;CAET,OAAO;AACT;AAEA,eAAsB,eACpB,cACA,kBACqB;CAGrB,OAAO;EAAE,UAAU;EAAc,aAAA,MADP,SADF,iBAAiB,QAAQ,YAAY,OACZ,GAAG,OAAO;CACd;AAC/C;AAEA,eAAsB,sBACpB,SACA,MACA,MACA,YACyC;CACzC,MAAM,eAAe,SAAS,MAAM;EAAE;EAAM,YAAY,CAAC;CAAE,GAAG,UAAU;CACxE,OAAO;EAAE;EAAM;CAAK;AACtB;AAEA,eAAsB,0BAA0B,SAOd;CAChC,MAAM,OAAO,0BAA0B;EACrC,GAAG,UAAU,cAAc,QAAQ,UAAU;EAC7C,GAAG,UAAU,MAAM,QAAQ,EAAE;CAC/B,CAAC;CACD,IAAI,SAAS,MACX,OAAO;EAAE,aAAa;EAAM,mBAAmB;CAAK;CAEtD,IAAI,QAAQ,SAAS,QACnB,OAAO;EAAE,aAAa;EAAM,mBAAmB;GAAE;GAAM,MAAM,QAAQ;EAAK;CAAE;CAQ9E,OAAO;EAAE,aAAA,MANiB,sBACxB,QAAQ,SACR,MACA,QAAQ,MACR,QAAQ,UACV;EACsB,mBAAmB;CAAK;AAChD"}
@@ -1,8 +1,9 @@
1
- import { t as CliStructuredError } from "./cli-errors-Czmx92Zy.mjs";
1
+ import { CliStructuredError as CliStructuredError$1 } from "@prisma-next/errors/control";
2
2
  import { Result } from "@prisma-next/utils/result";
3
3
  import { ContractSourceDiagnostics, ContractSourceProvider } from "@prisma-next/config/config-types";
4
4
  import { ControlAdapterDescriptor, ControlDriverDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyDescriptor, ControlFamilyInstance, ControlTargetDescriptor, CoreSchemaView, MigrationPlanOperation, MigrationPlannerConflict, OperationPreview, SignDatabaseResult, VerifyDatabaseResult, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
5
5
  import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
6
+ import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
6
7
  import { Contract, ContractMarkerRecord } from "@prisma-next/contract/types";
7
8
  import { PslDocumentAst } from "@prisma-next/framework-components/psl-ast";
8
9
  import { OnDiskMigrationPackage } from "@prisma-next/migration-tools/package";
@@ -47,7 +48,7 @@ interface ExecuteDbVerifySuccess {
47
48
  readonly memberOrder: readonly string[];
48
49
  readonly appSpaceId: string;
49
50
  }
50
- type ExecuteDbVerifyResult = Result<ExecuteDbVerifySuccess, CliStructuredError>;
51
+ type ExecuteDbVerifyResult = Result<ExecuteDbVerifySuccess, CliStructuredError$1>;
51
52
  /**
52
53
  * Loader → verifier pipeline shared by `db verify` modes (`full`,
53
54
  * `marker-only`, `schema-only`).
@@ -665,6 +666,13 @@ type MigrationApplyResult = Result<MigrationApplySuccess, MigrationApplyFailure>
665
666
  interface ContractEmitOptions {
666
667
  /** Path to the prisma-next.config.ts file */
667
668
  readonly configPath: string;
669
+ /**
670
+ * Directory to write contract artifacts into. When set, `contract.json` and
671
+ * `contract.d.ts` are written inside this directory, taking precedence over
672
+ * any output path from the loaded config. The value must be an absolute path;
673
+ * resolution against cwd is the caller's responsibility.
674
+ */
675
+ readonly outputPath?: string;
668
676
  /** Optional AbortSignal for cancelling the in-flight emit */
669
677
  readonly signal?: AbortSignal;
670
678
  /** Optional progress callback for observing source-resolution and emit spans */
@@ -858,5 +866,5 @@ interface ControlClient {
858
866
  emit(options: EmitOptions): Promise<EmitResult>;
859
867
  }
860
868
  //#endregion
861
- export { ExecuteDbVerifyOptions as A, EmitSuccess as C, SchemaVerifyOptions as D, OnControlProgress as E, executeDbVerify as M, SignOptions as O, EmitResult as S, MigrationApplyPathDecision as T, DbUpdateSuccess as _, ControlClient as a, EmitFailureCode as b, DbInitFailure as c, DbInitResult as d, DbInitSuccess as f, DbUpdateResult as g, DbUpdateOptions as h, ControlActionName as i, ExecuteDbVerifyResult as j, VerifyOptions as k, DbInitFailureCode as l, DbUpdateFailureCode as m, ContractEmitOptions as n, ControlClientOptions as o, DbUpdateFailure as p, ContractEmitResult as r, ControlProgressEvent as s, AggregatePerSpaceExecutionEntry as t, DbInitOptions as u, EmitContractConfig as v, IntrospectOptions as w, EmitOptions as x, EmitFailure as y };
862
- //# sourceMappingURL=types--CqjMdk0.d.mts.map
869
+ export { ExecuteDbVerifyOptions as A, EmitSuccess as C, SchemaVerifyOptions as D, OnControlProgress as E, executeDbVerify as M, CliStructuredError$1 as N, SignOptions as O, EmitResult as S, MigrationApplyPathDecision as T, DbUpdateSuccess as _, ControlClient as a, EmitFailureCode as b, DbInitFailure as c, DbInitResult as d, DbInitSuccess as f, DbUpdateResult as g, DbUpdateOptions as h, ControlActionName as i, ExecuteDbVerifyResult as j, VerifyOptions as k, DbInitFailureCode as l, DbUpdateFailureCode as m, ContractEmitOptions as n, ControlClientOptions as o, DbUpdateFailure as p, ContractEmitResult as r, ControlProgressEvent as s, AggregatePerSpaceExecutionEntry as t, DbInitOptions as u, EmitContractConfig as v, IntrospectOptions as w, EmitOptions as x, EmitFailure as y };
870
+ //# sourceMappingURL=types-UWB2-rrw.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-UWB2-rrw.d.mts","names":[],"sources":["../src/control-api/operations/db-verify.ts","../src/control-api/types.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { c as isVerbose, o as createColorFormatter, s as formatDim } from "./terminal-ui-BiB_8KNo.mjs";
1
+ import { A as formatDim, j as isVerbose, k as createColorFormatter } from "./command-helpers-BnqwTptC.mjs";
2
2
  import { ifDefined } from "@prisma-next/utils/defined";
3
3
  import { bold, cyan, dim, green, magenta, red, yellow } from "colorette";
4
4
  //#region src/utils/formatters/verify.ts
@@ -381,4 +381,4 @@ function formatSignJson(result) {
381
381
  //#endregion
382
382
  export { formatSignJson as a, formatVerifyOutput as c, formatSchemaVerifyOutput as i, formatIntrospectOutput as n, formatSignOutput as o, formatSchemaVerifyJson as r, formatVerifyJson as s, formatIntrospectJson as t };
383
383
 
384
- //# sourceMappingURL=verify-Bom75OYI.mjs.map
384
+ //# sourceMappingURL=verify-DX4RQwq4.mjs.map