prisma-next 0.12.0-dev.1 → 0.12.0-dev.10

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 (40) hide show
  1. package/dist/cli.mjs +4 -4
  2. package/dist/{client-KgJorIvG.mjs → client-CDr4o07S.mjs} +18 -5
  3. package/dist/client-CDr4o07S.mjs.map +1 -0
  4. package/dist/commands/contract-infer.mjs +1 -1
  5. package/dist/commands/db-init.mjs +2 -2
  6. package/dist/commands/db-schema.mjs +1 -1
  7. package/dist/commands/db-sign.mjs +1 -1
  8. package/dist/commands/db-update.mjs +2 -2
  9. package/dist/commands/db-verify.mjs +1 -1
  10. package/dist/commands/migrate.d.mts +1 -1
  11. package/dist/commands/migrate.mjs +1 -1
  12. package/dist/commands/migration-graph.d.mts +20 -2
  13. package/dist/commands/migration-graph.d.mts.map +1 -1
  14. package/dist/commands/migration-graph.mjs +2 -2
  15. package/dist/commands/migration-list.d.mts +1 -1
  16. package/dist/commands/migration-log.d.mts +1 -1
  17. package/dist/commands/migration-log.mjs +1 -1
  18. package/dist/commands/migration-show.d.mts +1 -1
  19. package/dist/commands/migration-show.mjs +1 -1
  20. package/dist/commands/migration-status.mjs +2 -2
  21. package/dist/commands/migration-status.mjs.map +1 -1
  22. package/dist/commands/ref.d.mts +1 -1
  23. package/dist/{contract-infer-D8uEbJuu.mjs → contract-infer-C8J1WMvO.mjs} +2 -2
  24. package/dist/{contract-infer-D8uEbJuu.mjs.map → contract-infer-C8J1WMvO.mjs.map} +1 -1
  25. package/dist/{db-verify-v_vUKXTU.mjs → db-verify-BeRHwN8M.mjs} +2 -2
  26. package/dist/{db-verify-v_vUKXTU.mjs.map → db-verify-BeRHwN8M.mjs.map} +1 -1
  27. package/dist/exports/control-api.d.mts +1 -1
  28. package/dist/exports/control-api.d.mts.map +1 -1
  29. package/dist/exports/control-api.mjs +1 -1
  30. package/dist/{inspect-live-schema-C6ohV_oQ.mjs → inspect-live-schema-BlKR2Zln.mjs} +2 -2
  31. package/dist/{inspect-live-schema-C6ohV_oQ.mjs.map → inspect-live-schema-BlKR2Zln.mjs.map} +1 -1
  32. package/dist/{migration-command-scaffold-CjvwO6at.mjs → migration-command-scaffold-BAGUiGOK.mjs} +2 -2
  33. package/dist/{migration-command-scaffold-CjvwO6at.mjs.map → migration-command-scaffold-BAGUiGOK.mjs.map} +1 -1
  34. package/dist/{migration-graph-D7DVUElV.mjs → migration-graph-C9WC-7eO.mjs} +324 -78
  35. package/dist/migration-graph-C9WC-7eO.mjs.map +1 -0
  36. package/dist/{types-Dt_SfqFm.d.mts → types-CeC5ec2Y.d.mts} +8 -2
  37. package/dist/{types-Dt_SfqFm.d.mts.map → types-CeC5ec2Y.d.mts.map} +1 -1
  38. package/package.json +11 -11
  39. package/dist/client-KgJorIvG.mjs.map +0 -1
  40. package/dist/migration-graph-D7DVUElV.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-KgJorIvG.mjs","names":["SPAN_IDS","emitContractArtifacts"],"sources":["../src/control-api/errors.ts","../src/control-api/operations/apply.ts","../src/control-api/operations/migration-helpers.ts","../src/control-api/operations/db-apply.ts","../src/control-api/operations/db-init.ts","../src/control-api/operations/db-update.ts","../src/control-api/operations/db-verify.ts","../src/control-api/operations/migration-apply.ts","../src/control-api/client.ts"],"sourcesContent":["export class ContractValidationError extends Error {\n override readonly cause?: unknown;\n\n constructor(message: string, cause?: unknown) {\n super(message);\n this.name = 'ContractValidationError';\n this.cause = cause;\n }\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlFamilyInstance,\n MigrationOperationPolicy,\n TargetMigrationsCapability,\n} from '@prisma-next/framework-components/control';\nimport type { ContractSpaceAggregate, PerSpacePlan } from '@prisma-next/migration-tools/aggregate';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport type { OnControlProgress, PerSpaceExecutionEntry } from '../types';\n\n/**\n * Span id emitted via `onProgress` for the apply phase. Stable\n * identifier consumed by the structured-output renderer and by tests.\n */\nconst APPLY_SPAN_ID = 'apply' as const;\n\n/**\n * Action that originated this apply call. Threaded into `OnControlProgress`\n * events so the parent CLI command can attribute the span correctly,\n * and used to compose action-specific summary phrasing.\n */\nexport type ApplyAction = 'dbInit' | 'dbUpdate' | 'migrationApply';\n\n/**\n * Failure variant emitted by {@link applyMigration} when the runner\n * itself rejects the apply. Mirrors the failure shape callers\n * already wrap into their own action-specific failure envelopes\n * (`DbInitFailure`, `DbUpdateFailure`, `MigrationApplyFailure`) so each\n * caller keeps owning its own discriminated failure code.\n */\nexport interface ApplyRunnerFailure {\n readonly summary: string;\n readonly why?: string;\n readonly meta: Record<string, unknown>;\n}\n\nexport interface ApplyMigrationInputs<TFamilyId extends string, TTargetId extends string> {\n readonly aggregate: ContractSpaceAggregate;\n /**\n * Per-space plans, keyed by `spaceId`. Produced by either the full\n * {@link planMigration} pipeline (`db init` / `db update` — synth\n * for the app, graph-walk for extensions) or by direct\n * {@link graphWalkStrategy} calls (`migrate` — graph-walk\n * for every member). Either way, the runner consumes the same shape.\n */\n readonly perSpacePlans: ReadonlyMap<string, PerSpacePlan>;\n /**\n * Canonical schedule order — extensions alphabetically by `spaceId`,\n * then app. Mirrors {@link import('@prisma-next/migration-tools/concatenate-space-apply-inputs').concatenateSpaceApplyInputs}'s\n * convention so `MigrationRunnerFailure.failingSpace` attribution\n * stays byte-for-byte stable across callers.\n */\n readonly applyOrder: readonly string[];\n readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;\n readonly familyInstance: ControlFamilyInstance<TFamilyId, unknown>;\n readonly migrations: TargetMigrationsCapability<\n TFamilyId,\n TTargetId,\n ControlFamilyInstance<TFamilyId, unknown>\n >;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n readonly policy: MigrationOperationPolicy;\n readonly action: ApplyAction;\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Resolved per-space plan in canonical schedule order. Surfaced from\n * {@link applyMigration} to callers so each one can build its own\n * action-specific success envelope (e.g. `DbInitSuccess` vs\n * `MigrationApplySuccess`) without re-deriving the ordering.\n */\nexport interface OrderedResolution {\n readonly spaceId: string;\n readonly entry: PerSpacePlan;\n}\n\nexport interface ApplyMigrationValue {\n readonly orderedResolutions: readonly OrderedResolution[];\n readonly totalOpsPlanned: number;\n readonly totalOpsExecuted: number;\n /**\n * Per-space breakdown ready to thread into action-specific success\n * envelopes. Each entry carries the post-apply marker (live storage hash\n * plus invariants) so callers can render it directly without re-reading.\n */\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n}\n\nexport type ApplyMigrationResult = Result<ApplyMigrationValue, ApplyRunnerFailure>;\n\n/**\n * Runner-driving tail shared by every apply caller — `db init`,\n * `db update`, and `migrate`. Consumes already-resolved per-space\n * plans (the planner-vs-replay distinction is owned by the caller) and\n * dispatches them to the runner in canonical order.\n *\n * Marker advancement is part of the runner's per-space transaction\n * (the SQL family runner writes the marker as the last step of each\n * space's transaction), so this primitive does not advance markers\n * separately — by the time `execute` returns ok, every\n * space's marker has been advanced to its plan's destination.\n *\n * Span emission (`spanStart 'apply'` / `spanEnd 'apply'`) is owned here\n * so callers don't have to duplicate it; the `action` field on each\n * progress event is taken from the caller's `action` argument.\n */\nexport async function applyMigration<TFamilyId extends string, TTargetId extends string>(\n inputs: ApplyMigrationInputs<TFamilyId, TTargetId>,\n): Promise<ApplyMigrationResult> {\n const {\n aggregate,\n perSpacePlans,\n applyOrder,\n driver,\n familyInstance,\n migrations,\n frameworkComponents,\n policy,\n action,\n onProgress,\n } = inputs;\n\n const orderedResolutions = collectOrdered(applyOrder, perSpacePlans);\n\n const runner = migrations.createRunner(familyInstance);\n\n onProgress?.({\n action,\n kind: 'spanStart',\n spanId: APPLY_SPAN_ID,\n label: progressLabelForAction(action),\n });\n\n const perSpaceOptions = orderedResolutions.map((r) => ({\n space: r.spaceId,\n plan: r.entry.plan,\n driver,\n destinationContract: r.entry.destinationContract,\n policy,\n frameworkComponents,\n // Per-space post-apply schema verification is non-strict: each\n // space's `destinationContract` describes only its own slice; a\n // strict verifier would treat every other space's tables as\n // `extras`. Tolerant mode still catches missing tables / columns.\n strictVerification: false,\n }));\n\n const runnerResult = await runner.execute({ driver, perSpaceOptions });\n\n if (!runnerResult.ok) {\n onProgress?.({ action, kind: 'spanEnd', spanId: APPLY_SPAN_ID, outcome: 'error' });\n return notOk({\n summary: runnerResult.failure.summary,\n ...ifDefined('why', runnerResult.failure.why),\n meta: {\n ...(runnerResult.failure.meta ?? {}),\n failingSpace: runnerResult.failure.failingSpace,\n runnerErrorCode: runnerResult.failure.code,\n },\n });\n }\n onProgress?.({ action, kind: 'spanEnd', spanId: APPLY_SPAN_ID, outcome: 'ok' });\n\n const totalOpsPlanned = runnerResult.value.perSpaceResults.reduce(\n (sum, r) => sum + r.value.operationsPlanned,\n 0,\n );\n const totalOpsExecuted = runnerResult.value.perSpaceResults.reduce(\n (sum, r) => sum + r.value.operationsExecuted,\n 0,\n );\n\n const perSpace = buildPerSpaceBreakdown(orderedResolutions, aggregate.app.spaceId, {\n includeMarkers: true,\n });\n\n return ok({\n orderedResolutions,\n totalOpsPlanned,\n totalOpsExecuted,\n perSpace,\n });\n}\n\n/**\n * Project the planner's per-space resolutions into the\n * `PerSpaceExecutionEntry[]` shape the CLI surfaces.\n *\n * `includeMarkers` is `true` for apply-mode (each space's marker is\n * the `destination.storageHash` of its plan, which the runner\n * advances as the last step of each space's transaction) and `false`\n * for plan-mode (no marker has been written yet).\n *\n * Exported alongside {@link applyMigration} so plan-mode callers can\n * assemble the same per-space block without going through the runner.\n */\nexport function buildPerSpaceBreakdown(\n orderedResolutions: readonly OrderedResolution[],\n appSpaceId: string,\n options: { readonly includeMarkers: boolean },\n): readonly PerSpaceExecutionEntry[] {\n return orderedResolutions.map((r) => {\n const operations = r.entry.displayOps.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n }));\n const base: PerSpaceExecutionEntry = {\n spaceId: r.spaceId,\n kind: r.spaceId === appSpaceId ? 'app' : 'extension',\n operations,\n };\n if (!options.includeMarkers) return base;\n return {\n ...base,\n marker: { storageHash: r.entry.plan.destination.storageHash },\n };\n });\n}\n\n/**\n * Materialise the `applyOrder` ordering into resolved per-space\n * entries. Throws if the planner output is missing a member listed\n * in `applyOrder` — a wiring bug that should never reach runtime.\n *\n * Exported so callers building their own success envelopes after a\n * plan-mode dispatch can replay the same ordering.\n */\nexport function collectOrdered(\n applyOrder: readonly string[],\n perSpace: ReadonlyMap<string, PerSpacePlan>,\n): readonly OrderedResolution[] {\n return applyOrder.map((spaceId) => {\n const entry = perSpace.get(spaceId);\n if (!entry) {\n throw new Error(`planner output missing per-space plan for \"${spaceId}\"`);\n }\n return { spaceId, entry };\n });\n}\n\n/**\n * Action-appropriate label for the `spanStart` event the apply\n * primitive emits. `applyMigration` is shared by `db init`, `db update`,\n * and `migrate`; the span label tracks the user-visible action\n * so structured-progress output reads naturally for each surface.\n */\nexport function progressLabelForAction(action: ApplyAction): string {\n switch (action) {\n case 'dbInit':\n return 'Initialising database across spaces';\n case 'dbUpdate':\n return 'Updating database across spaces';\n case 'migrationApply':\n return 'Applying migration plan across spaces';\n }\n}\n","import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';\nimport type { ControlActionName, OnControlProgress } from '../types';\n\n/**\n * Strips operation objects to their public shape (id, label, operationClass).\n * Used at the API boundary to avoid leaking internal fields (precheck, execute, postcheck, etc.).\n */\nexport function stripOperations(\n operations: readonly MigrationPlanOperation[],\n): ReadonlyArray<{ readonly id: string; readonly label: string; readonly operationClass: string }> {\n return operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n }));\n}\n\n/**\n * Creates per-operation progress callbacks for the runner.\n * Returns undefined when no onProgress callback is provided.\n */\nexport function createOperationCallbacks(\n onProgress: OnControlProgress | undefined,\n action: ControlActionName,\n parentSpanId: string,\n) {\n if (!onProgress) {\n return undefined;\n }\n return {\n onOperationStart: (op: MigrationPlanOperation) => {\n onProgress({\n action,\n kind: 'spanStart',\n spanId: `operation:${op.id}`,\n parentSpanId,\n label: op.label,\n });\n },\n onOperationComplete: (op: MigrationPlanOperation) => {\n onProgress({\n action,\n kind: 'spanEnd',\n spanId: `operation:${op.id}`,\n outcome: 'ok',\n });\n },\n };\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyInstance,\n MigrationOperationPolicy,\n MigrationPlanOperation,\n OperationPreview,\n TargetMigrationsCapability,\n} from '@prisma-next/framework-components/control';\nimport { hasOperationPreview } from '@prisma-next/framework-components/control';\nimport {\n type ContractSpaceAggregate,\n type PlannerError,\n planMigration,\n} from '@prisma-next/migration-tools/aggregate';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { CliStructuredError } from '../../utils/cli-errors';\nimport {\n type BuildAggregateInputs,\n buildContractSpaceAggregate,\n} from '../../utils/contract-space-aggregate-loader';\nimport type {\n DbInitFailure,\n DbInitResult,\n DbInitSuccess,\n DbUpdateFailure,\n DbUpdateResult,\n DbUpdateSuccess,\n OnControlProgress,\n PerSpaceExecutionEntry,\n} from '../types';\nimport { applyMigration, buildPerSpaceBreakdown, collectOrdered } from './apply';\nimport { stripOperations } from './migration-helpers';\n\n/**\n * Span IDs emitted via `onProgress` during the apply flow.\n * Stable identifiers consumed by the structured-output renderer and by\n * tests asserting on span ids. The `apply` span itself is owned by\n * the {@link applyMigration} primitive — only the introspect / plan\n * spans are emitted directly here.\n */\nconst SPAN_IDS = {\n introspect: 'introspect',\n plan: 'plan',\n} as const;\n\n/**\n * Inputs shared by `db init` and `db update` apply flows.\n *\n * Accepts the already-validated app contract + descriptor list — the\n * loader gathers the rest from disk + descriptors. The CLI is the\n * descriptor-import boundary; everything downstream is descriptor-free.\n */\nexport interface ExecuteApplyOptions<TFamilyId extends string, TTargetId extends string> {\n readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;\n readonly familyInstance: ControlFamilyInstance<TFamilyId, unknown>;\n readonly contract: Contract;\n readonly mode: 'plan' | 'apply';\n readonly migrations: TargetMigrationsCapability<\n TFamilyId,\n TTargetId,\n ControlFamilyInstance<TFamilyId, unknown>\n >;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n readonly migrationsDir: string;\n readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;\n readonly targetId: TTargetId;\n readonly policy: MigrationOperationPolicy;\n readonly action: 'dbInit' | 'dbUpdate';\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Loader → planner → runner pipeline shared by `db init` and `db update`.\n *\n * The pipeline:\n *\n * 1. **Load**: build a {@link ContractSpaceAggregate} from the descriptor\n * set + on-disk on-disk artefacts. Any layout / drift / disjointness /\n * integrity violation short-circuits with a structured error.\n * 2. **Read DB state**: marker rows (`familyInstance.readAllMarkers`)\n * + introspected schema (`familyInstance.introspect`).\n * 3. **Plan**: {@link planMigration} chooses graph-walk vs synth per\n * member according to `callerPolicy.ignoreGraphFor`. The app member\n * is forced through synth (today's daily-driver behaviour); every\n * extension member walks its on-disk graph.\n * 4. **Apply** (when `mode === 'apply'`): every per-space `MigrationPlan`\n * feeds into the runner's `execute` — one outer\n * transaction across every space; failure on any space rolls back\n * every space's writes.\n */\nexport async function executeApply<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteApplyOptions<TFamilyId, TTargetId>,\n): Promise<DbInitResult | DbUpdateResult> {\n const {\n driver,\n familyInstance,\n contract,\n mode,\n migrations,\n frameworkComponents,\n migrationsDir,\n extensionPacks,\n targetId,\n policy,\n action,\n onProgress,\n } = options;\n\n // 1. Load aggregate from descriptors + on-disk state.\n const loadInputs: BuildAggregateInputs<TFamilyId, TTargetId> = {\n targetId,\n migrationsDir,\n appContract: contract,\n extensionPacks,\n deserializeContract: (json) => familyInstance.deserializeContract(json),\n };\n const loaded = await buildContractSpaceAggregate(loadInputs);\n if (!loaded.ok) {\n throw loaded.failure;\n }\n const aggregate = loaded.value;\n\n // 2. Read live DB state (markers + schema).\n const markerRows = await familyInstance.readAllMarkers({ driver });\n\n // 2a. Orphan-marker pre-flight: refuse to *apply* when a marker row\n // exists for a space that is not declared in the aggregate. Plan mode\n // (`db init/update --dry-run`) must still be able to introspect the\n // aggregate plan in this state — a retired extension whose marker\n // happens to linger should not block the user from inspecting what a\n // run would do. Apply mode tells the user to clean up the orphan\n // before silently advancing the app's marker.\n if (mode === 'apply') {\n const orphanMarkerError = detectOrphanMarkers(aggregate, markerRows);\n if (orphanMarkerError !== null) {\n throw orphanMarkerError;\n }\n }\n\n onProgress?.({\n action,\n kind: 'spanStart',\n spanId: SPAN_IDS.introspect,\n label: 'Introspecting database schema',\n });\n const schemaIR = await familyInstance.introspect({ driver });\n onProgress?.({ action, kind: 'spanEnd', spanId: SPAN_IDS.introspect, outcome: 'ok' });\n\n // 3. Plan via aggregate planner. App is forced through synth (today's\n // `db init` / `db update` daily-driver behaviour); extensions walk\n // their on-disk migration graphs.\n onProgress?.({\n action,\n kind: 'spanStart',\n spanId: SPAN_IDS.plan,\n label: 'Planning migration',\n });\n const planResult = await planMigration<TFamilyId, TTargetId>({\n aggregate,\n currentDBState: { markersBySpaceId: markerRows, schemaIntrospection: schemaIR },\n familyInstance,\n migrations,\n frameworkComponents,\n callerPolicy: { ignoreGraphFor: new Set([aggregate.app.spaceId]) },\n operationPolicy: policy,\n });\n if (!planResult.ok) {\n onProgress?.({ action, kind: 'spanEnd', spanId: SPAN_IDS.plan, outcome: 'error' });\n return mapPlannerError(planResult.failure);\n }\n onProgress?.({ action, kind: 'spanEnd', spanId: SPAN_IDS.plan, outcome: 'ok' });\n\n const orderedResolutions = collectOrdered(planResult.value.applyOrder, planResult.value.perSpace);\n\n // The destination's structural shape comes from the app's plan — its\n // `destination` is the storage hash users see in CLI output.\n const appResolution = orderedResolutions.find((r) => r.spaceId === aggregate.app.spaceId);\n if (!appResolution) {\n throw new Error(\n 'Aggregate planner returned no plan for the app member — the planner is supposed to always emit one.',\n );\n }\n const appPlan = appResolution.entry.plan;\n\n // 4. Plan-mode: surface aggregate operations without applying.\n if (mode === 'plan') {\n const aggregateOps = orderedResolutions.flatMap((r) => r.entry.displayOps);\n const preview = hasOperationPreview(familyInstance)\n ? familyInstance.toOperationPreview(aggregateOps)\n : undefined;\n const perSpace = buildPerSpaceBreakdown(orderedResolutions, aggregate.app.spaceId, {\n includeMarkers: false,\n });\n const summary = `Planned ${aggregateOps.length} operation(s) across ${orderedResolutions.length} space(s)`;\n return wrapPlanResult({\n operations: aggregateOps,\n destination: appPlan.destination,\n preview,\n perSpace,\n summary,\n });\n }\n\n // 5. Apply mode: hand off to the shared `applyMigration` primitive.\n // The runner-driving tail is identical for `db init` / `db update` /\n // `migrate` — only how each caller produces `perSpacePlans`\n // differs (synth + graph-walk via planMigration here; graph-walk\n // only for migrate). Each caller produces perSpacePlans differently;\n // this helper handles the shared apply tail.\n const applied = await applyMigration({\n aggregate,\n perSpacePlans: planResult.value.perSpace,\n applyOrder: planResult.value.applyOrder,\n driver,\n familyInstance,\n migrations,\n frameworkComponents,\n policy,\n action,\n ...ifDefined('onProgress', onProgress),\n });\n if (!applied.ok) {\n return buildRunnerFailure({\n summary: applied.failure.summary,\n ...ifDefined('why', applied.failure.why),\n meta: applied.failure.meta,\n });\n }\n\n const aggregateOps = applied.value.orderedResolutions.flatMap((r) => r.entry.displayOps);\n const summary =\n action === 'dbInit'\n ? `Applied ${applied.value.totalOpsExecuted} operation(s) across ${applied.value.orderedResolutions.length} space(s), database signed`\n : applied.value.totalOpsExecuted === 0\n ? `Database already matches contract across ${applied.value.orderedResolutions.length} space(s), signature updated`\n : `Applied ${applied.value.totalOpsExecuted} operation(s) across ${applied.value.orderedResolutions.length} space(s), signature updated`;\n\n return wrapApplyResult({\n operations: aggregateOps,\n destination: appPlan.destination,\n operationsPlanned: applied.value.totalOpsPlanned,\n operationsExecuted: applied.value.totalOpsExecuted,\n perSpace: applied.value.perSpace,\n summary,\n });\n}\n\n/**\n * Compare the live `_prisma_marker` rows against the aggregate's\n * declared members. Any marker row whose `space` is not a member of\n * the aggregate is an \"orphan\" — typically a marker left behind by\n * an extension that was removed from `extensionPacks` without first\n * cleaning up its on-disk migrations / database tables.\n *\n * Returns a {@link CliStructuredError} envelope (code `5002`,\n * `kind: 'orphanMarker'`) for the first orphan it finds, or `null`\n * when every marker row maps to a declared member. Mirrors the M2\n * `runContractSpaceVerifierMarkerCheck` envelope so downstream\n * tooling (integration tests, JSON consumers) keeps asserting on the\n * same shape.\n */\nfunction detectOrphanMarkers(\n aggregate: ContractSpaceAggregate,\n markerRows: ReadonlyMap<string, unknown>,\n): CliStructuredError | null {\n const memberSpaceIds = new Set<string>([\n aggregate.app.spaceId,\n ...aggregate.extensions.map((m) => m.spaceId),\n ]);\n const orphans: string[] = [];\n for (const [spaceId, row] of markerRows) {\n if (row !== null && row !== undefined && !memberSpaceIds.has(spaceId)) {\n orphans.push(spaceId);\n }\n }\n if (orphans.length === 0) return null;\n orphans.sort((a, b) => a.localeCompare(b));\n const summary =\n orphans.length === 1\n ? `Orphan contract-space marker detected for \"${orphans[0]}\"`\n : `Orphan contract-space markers detected for ${orphans.length} spaces`;\n return new CliStructuredError('5002', summary, {\n domain: 'MIG',\n why: `The database has \\`_prisma_marker\\` rows for spaces (${orphans\n .map((s) => `\"${s}\"`)\n .join(\n ', ',\n )}) that are not declared in the project's \\`extensionPacks\\`. The aggregate pipeline refuses to advance markers it cannot account for.`,\n fix: 'Either re-declare the missing extension(s) in `extensionPacks` (so the aggregate owns them again), or remove the orphan marker row(s) from `_prisma_marker` once you have confirmed the corresponding tables can be safely retired.',\n docsUrl: 'https://pris.ly/contract-spaces',\n meta: {\n violations: orphans.map((spaceId) => ({ kind: 'orphanMarker', spaceId })),\n },\n });\n}\n\nfunction mapPlannerError(error: PlannerError): DbInitResult | DbUpdateResult {\n if (error.kind === 'appSynthFailure') {\n const failure: DbInitFailure | DbUpdateFailure = {\n code: 'PLANNING_FAILED',\n summary: 'Migration planning failed due to conflicts',\n conflicts: error.conflicts,\n why: undefined,\n meta: undefined,\n };\n return notOk(failure) as DbInitResult | DbUpdateResult;\n }\n if (error.kind === 'extensionPathUnreachable') {\n return buildRunnerFailure({\n summary: `Cannot resolve apply path for extension space \"${error.spaceId}\"`,\n why: `No path in the on-disk migration graph for extension space \"${error.spaceId}\" reaches the on-disk head ref hash \"${error.target}\".`,\n meta: { spaceId: error.spaceId, target: error.target },\n });\n }\n if (error.kind === 'extensionPathUnsatisfiable') {\n return buildRunnerFailure({\n summary: `Cannot resolve apply path for extension space \"${error.spaceId}\"`,\n why: `On-disk migration graph for extension space \"${error.spaceId}\" reaches the on-disk head ref but does not cover required invariants: ${error.missingInvariants.join(', ')}.`,\n meta: { spaceId: error.spaceId, missingInvariants: error.missingInvariants },\n });\n }\n // policyConflict — surfaces as a runner-style failure naming the\n // space; conceptually a configuration bug, but mapping it onto the\n // existing failure surface keeps callers untouched.\n return buildRunnerFailure({\n summary: `Aggregate planner policy conflict for space \"${error.spaceId}\"`,\n why: error.detail,\n meta: { spaceId: error.spaceId },\n });\n}\n\nfunction wrapPlanResult(args: {\n readonly operations: readonly MigrationPlanOperation[];\n readonly destination: { readonly storageHash: string; readonly profileHash?: string };\n readonly preview: OperationPreview | undefined;\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n readonly summary: string;\n}): DbInitResult | DbUpdateResult {\n const success: DbInitSuccess | DbUpdateSuccess = {\n mode: 'plan',\n plan: {\n operations: stripOperations(args.operations),\n ...ifDefined('preview', args.preview),\n },\n destination: {\n storageHash: args.destination.storageHash,\n ...ifDefined('profileHash', args.destination.profileHash),\n },\n perSpace: args.perSpace,\n summary: args.summary,\n };\n return ok(success);\n}\n\nfunction wrapApplyResult(args: {\n readonly operations: readonly MigrationPlanOperation[];\n readonly destination: { readonly storageHash: string; readonly profileHash?: string };\n readonly operationsPlanned: number;\n readonly operationsExecuted: number;\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n readonly summary: string;\n}): DbInitResult | DbUpdateResult {\n const success: DbInitSuccess | DbUpdateSuccess = {\n mode: 'apply',\n plan: { operations: stripOperations(args.operations) },\n destination: {\n storageHash: args.destination.storageHash,\n ...ifDefined('profileHash', args.destination.profileHash),\n },\n execution: {\n operationsPlanned: args.operationsPlanned,\n operationsExecuted: args.operationsExecuted,\n },\n marker: args.destination.profileHash\n ? { storageHash: args.destination.storageHash, profileHash: args.destination.profileHash }\n : { storageHash: args.destination.storageHash },\n perSpace: args.perSpace,\n summary: args.summary,\n };\n return ok(success);\n}\n\nfunction buildRunnerFailure(args: {\n readonly summary: string;\n readonly why?: string;\n readonly meta: Record<string, unknown>;\n}): DbInitResult | DbUpdateResult {\n const failure: DbInitFailure | DbUpdateFailure = {\n code: 'RUNNER_FAILED',\n summary: args.summary,\n why: args.why,\n meta: args.meta,\n conflicts: undefined,\n };\n return notOk(failure) as DbInitResult | DbUpdateResult;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyInstance,\n TargetMigrationsCapability,\n} from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { DbInitResult, OnControlProgress } from '../types';\nimport { executeApply } from './db-apply';\n\n/**\n * Options for executing the `db init` operation.\n *\n * `db init` runs the loader → planner → runner pipeline:\n *\n * 1. {@link executeApply} loads a `ContractSpaceAggregate` via\n * {@link import('@prisma-next/migration-tools/aggregate').loadContractSpaceAggregate}\n * from the supplied descriptor set + on-disk on-disk artefacts.\n * 2. The aggregate planner runs with `callerPolicy.ignoreGraphFor`\n * locked to the app member — synth strategy for the app, graph-walk\n * for every extension.\n * 3. The runner's `execute` applies the per-space plans\n * inside one outer transaction.\n *\n * `extensionPacks` mirrors `Config.extensionPacks` (descriptor list).\n * The loader (sub-spec § Loader) is the sole descriptor-import boundary.\n */\nexport interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extends string> {\n readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;\n readonly familyInstance: ControlFamilyInstance<TFamilyId, unknown>;\n readonly contract: Contract;\n readonly mode: 'plan' | 'apply';\n readonly migrations: TargetMigrationsCapability<\n TFamilyId,\n TTargetId,\n ControlFamilyInstance<TFamilyId, unknown>\n >;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n /**\n * On-disk migrations directory the aggregate loader reads on-disk\n * artefacts from. Required.\n */\n readonly migrationsDir: string;\n /**\n * Resolved adapter target id. Threaded through to the loader for\n * target-consistency checks across descriptors and the app contract.\n */\n readonly targetId: TTargetId;\n /**\n * Declared extension descriptors. Defaults to an empty list, which\n * routes through the same loader → planner → runner pipeline with no\n * extension members in the aggregate.\n */\n readonly extensionPacks?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;\n /** Optional progress callback for observing operation progress */\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Execute `db init` against the configured contract.\n *\n * Routes through the loader → planner → runner pipeline (sub-spec\n * \"Commit-by-commit § Commit 4\"). Always additive-only; destructive\n * changes belong to `db update`.\n */\nexport async function executeDbInit<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteDbInitOptions<TFamilyId, TTargetId>,\n): Promise<DbInitResult> {\n const result = await executeApply<TFamilyId, TTargetId>({\n driver: options.driver,\n familyInstance: options.familyInstance,\n contract: options.contract,\n mode: options.mode,\n migrations: options.migrations,\n frameworkComponents: options.frameworkComponents,\n migrationsDir: options.migrationsDir,\n targetId: options.targetId,\n extensionPacks: options.extensionPacks ?? [],\n policy: { allowedOperationClasses: ['additive'] },\n action: 'dbInit',\n ...ifDefined('onProgress', options.onProgress),\n });\n return result as DbInitResult;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyInstance,\n TargetMigrationsCapability,\n} from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk } from '@prisma-next/utils/result';\nimport type { DbUpdateResult, OnControlProgress } from '../types';\nimport { executeApply } from './db-apply';\n\nconst DB_UPDATE_POLICY = {\n allowedOperationClasses: ['additive', 'widening', 'destructive'] as const,\n} as const;\n\n/**\n * Options for the `db update` operation.\n *\n * Same loader → planner → runner pipeline as `db init`, but with the\n * widened operation policy (additive + widening + destructive). The\n * destructive-change confirmation gate runs at this layer: when\n * `mode === 'apply'` and `acceptDataLoss` is `false`, the operation\n * pre-plans, surfaces destructive ops to the caller, and aborts.\n */\nexport interface ExecuteDbUpdateOptions<TFamilyId extends string, TTargetId extends string> {\n readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;\n readonly familyInstance: ControlFamilyInstance<TFamilyId, unknown>;\n readonly contract: Contract;\n readonly mode: 'plan' | 'apply';\n readonly migrations: TargetMigrationsCapability<\n TFamilyId,\n TTargetId,\n ControlFamilyInstance<TFamilyId, unknown>\n >;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n readonly acceptDataLoss?: boolean;\n readonly migrationsDir: string;\n readonly targetId: TTargetId;\n readonly extensionPacks?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Execute `db update` against the configured contract.\n *\n * Routes through the loader → planner → runner pipeline. Destructive\n * operations require either `acceptDataLoss: true` or a prior\n * `mode: 'plan'` invocation that surfaces the destructive ops; the\n * confirmation gate is implemented here so the lower-level applier\n * remains policy-agnostic.\n */\nexport async function executeDbUpdate<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteDbUpdateOptions<TFamilyId, TTargetId>,\n): Promise<DbUpdateResult> {\n const sharedInputs = {\n driver: options.driver,\n familyInstance: options.familyInstance,\n contract: options.contract,\n migrations: options.migrations,\n frameworkComponents: options.frameworkComponents,\n migrationsDir: options.migrationsDir,\n targetId: options.targetId,\n extensionPacks: options.extensionPacks ?? [],\n policy: DB_UPDATE_POLICY,\n action: 'dbUpdate' as const,\n ...ifDefined('onProgress', options.onProgress),\n };\n if (options.mode === 'apply' && !options.acceptDataLoss) {\n const gate = await guardDestructiveChanges<TFamilyId, TTargetId>(sharedInputs);\n if (gate !== null) return gate;\n }\n return (await executeApply<TFamilyId, TTargetId>({\n ...sharedInputs,\n mode: options.mode,\n })) as DbUpdateResult;\n}\n\n/**\n * Pre-plan once when running `db update apply` without `acceptDataLoss`.\n * Surfaces destructive operations across every space; if any are\n * planned, returns a `DESTRUCTIVE_CHANGES` failure that the CLI shows\n * as a confirmation prompt. Returns `null` when the apply is safe to\n * run.\n */\nasync function guardDestructiveChanges<TFamilyId extends string, TTargetId extends string>(\n sharedInputs: Omit<Parameters<typeof executeApply<TFamilyId, TTargetId>>[0], 'mode'>,\n): Promise<DbUpdateResult | null> {\n const planResult = (await executeApply<TFamilyId, TTargetId>({\n ...sharedInputs,\n mode: 'plan',\n })) as DbUpdateResult;\n if (!planResult.ok) return planResult;\n const destructiveOps = planResult.value.plan.operations\n .filter((op) => op.operationClass === 'destructive')\n .map((op) => ({ id: op.id, label: op.label }));\n if (destructiveOps.length === 0) return null;\n return notOk({\n code: 'DESTRUCTIVE_CHANGES',\n summary: `Planned ${destructiveOps.length} destructive operation(s) that require confirmation`,\n why: 'Destructive operations require confirmation — re-run with -y to accept',\n conflicts: undefined,\n meta: { destructiveOperations: destructiveOps },\n });\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyInstance,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n type ContractSpaceMember,\n requireHeadRef,\n type VerifierOutput,\n verifyMigration,\n} from '@prisma-next/migration-tools/aggregate';\nimport { castAs } from '@prisma-next/utils/casts';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { CliStructuredError } from '../../utils/cli-errors';\nimport {\n type BuildAggregateInputs,\n buildContractSpaceAggregate,\n} from '../../utils/contract-space-aggregate-loader';\nimport type { OnControlProgress } from '../types';\n\n/**\n * Span IDs emitted via `onProgress` during the aggregate verify flow.\n * Mirrors the span identifiers used by the legacy precheck / marker-check\n * helpers so structured-output renderers and progress tests keep working.\n */\nconst SPAN_IDS = {\n introspect: 'introspect',\n verify: 'verify',\n} as const;\n\n/**\n * Inputs for the aggregate `db verify` operation.\n *\n * Loader → verifier pipeline. The loader (sole descriptor-import\n * boundary) builds a {@link import('@prisma-next/migration-tools/aggregate').ContractSpaceAggregate};\n * the aggregate verifier bundles `markerCheck` + per-space pre-projected\n * `schemaCheck`. `mode: 'strict' | 'lenient'` maps directly to the user\n * facing `--strict` flag.\n */\nexport interface ExecuteDbVerifyOptions<TFamilyId extends string, TTargetId extends string> {\n readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;\n readonly familyInstance: ControlFamilyInstance<TFamilyId, unknown>;\n readonly contract: Contract;\n readonly migrationsDir: string;\n readonly targetId: TTargetId;\n readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n readonly mode: 'strict' | 'lenient';\n readonly skipSchema: boolean;\n readonly skipMarker: boolean;\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Result of the aggregate verify operation.\n *\n * Marker-check failures are surfaced as a {@link CliStructuredError}\n * (same envelope code `5002` the legacy `runContractSpaceVerifierMarkerCheck`\n * emitted, so downstream tooling and integration tests assert on the\n * same shape).\n *\n * On success, the per-space schema results are returned for the CLI to\n * render. When `skipSchema` is true (`--marker-only`), the schema map\n * is empty.\n */\nexport interface ExecuteDbVerifySuccess {\n readonly schemaResults: ReadonlyMap<string, VerifyDatabaseSchemaResult>;\n readonly memberOrder: readonly string[];\n readonly appSpaceId: string;\n}\n\nexport type ExecuteDbVerifyResult = Result<ExecuteDbVerifySuccess, CliStructuredError>;\n\n/**\n * Loader → verifier pipeline shared by `db verify` modes (`full`,\n * `marker-only`, `schema-only`).\n *\n * 1. **Load**: build a {@link import('@prisma-next/migration-tools/aggregate').ContractSpaceAggregate}\n * from descriptors + on-disk on-disk artefacts. Layout / drift /\n * integrity / disjointness violations short-circuit with a\n * structured CLI error.\n * 2. **Read DB state**: marker rows + (when `skipSchema` is `false`)\n * schema introspection.\n * 3. **Verify**: {@link verifyMigration} returns per-space\n * `markerCheck` + per-space pre-projected `schemaCheck` (closes F23).\n * Marker mismatches map to `CliStructuredError` (code `5002`) so\n * callers (CLI command) can render and exit. Schema results are\n * returned to the caller verbatim.\n */\nexport async function executeDbVerify<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteDbVerifyOptions<TFamilyId, TTargetId>,\n): Promise<ExecuteDbVerifyResult> {\n const { driver, familyInstance, onProgress, skipSchema, skipMarker } = options;\n const loaded = await buildContractSpaceAggregate(buildLoadInputs(options));\n if (!loaded.ok) return notOk(loaded.failure);\n const aggregate = loaded.value;\n\n const markersBySpaceId = await familyInstance.readAllMarkers({ driver });\n const schemaIntrospection = skipSchema\n ? null\n : await runIntrospection({ driver, familyInstance, onProgress });\n\n emitVerifySpan(onProgress, 'spanStart');\n const verifyResult = verifyMigration({\n aggregate,\n markersBySpaceId,\n schemaIntrospection,\n mode: options.mode,\n verifySchemaForMember: createPerMemberVerifier(options),\n });\n return finaliseVerifyResult({ verifyResult, aggregate, skipMarker, onProgress });\n}\n\nfunction buildLoadInputs<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteDbVerifyOptions<TFamilyId, TTargetId>,\n): BuildAggregateInputs<TFamilyId, TTargetId> {\n return {\n targetId: options.targetId,\n migrationsDir: options.migrationsDir,\n appContract: options.contract,\n extensionPacks: options.extensionPacks,\n deserializeContract: (json) => options.familyInstance.deserializeContract(json),\n };\n}\n\nasync function runIntrospection<TFamilyId extends string, TTargetId extends string>(args: {\n driver: ControlDriverInstance<TFamilyId, TTargetId>;\n familyInstance: ControlFamilyInstance<TFamilyId, unknown>;\n onProgress: OnControlProgress | undefined;\n}): Promise<unknown> {\n const { driver, familyInstance, onProgress } = args;\n onProgress?.({\n action: 'dbVerify',\n kind: 'spanStart',\n spanId: SPAN_IDS.introspect,\n label: 'Introspecting database schema',\n });\n try {\n const result = await familyInstance.introspect({ driver });\n onProgress?.({\n action: 'dbVerify',\n kind: 'spanEnd',\n spanId: SPAN_IDS.introspect,\n outcome: 'ok',\n });\n return result;\n } catch (error) {\n onProgress?.({\n action: 'dbVerify',\n kind: 'spanEnd',\n spanId: SPAN_IDS.introspect,\n outcome: 'error',\n });\n throw error;\n }\n}\n\n/**\n * Build the per-member schema callback handed to the aggregate verifier.\n * When `skipSchema` is true the callback short-circuits with a synthetic\n * `ok` result so the verifier still runs the (cheap) schemaCheck loop\n * without invoking the family's verification path.\n */\nexport function createPerMemberVerifier<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteDbVerifyOptions<TFamilyId, TTargetId>,\n): (\n projectedSchema: unknown,\n member: ContractSpaceMember,\n verifyMode: 'strict' | 'lenient',\n) => VerifyDatabaseSchemaResult {\n const { skipSchema, familyInstance, frameworkComponents } = options;\n return (projectedSchema, member, verifyMode) => {\n if (skipSchema) return buildSkippedSchemaResult(member);\n return familyInstance.verifySchema({\n contract: member.contract(),\n // The family's `TSchemaIR` is opaque to migration-tools; the\n // aggregate verifier passes through whatever we hand it. The\n // family expects its own IR shape on the way back.\n schema: projectedSchema as never,\n strict: verifyMode === 'strict',\n frameworkComponents,\n });\n };\n}\n\nfunction emitVerifySpan(\n onProgress: OnControlProgress | undefined,\n kind: 'spanStart' | 'spanEndOk' | 'spanEndError',\n): void {\n if (kind === 'spanStart') {\n onProgress?.({\n action: 'dbVerify',\n kind: 'spanStart',\n spanId: SPAN_IDS.verify,\n label: 'Verifying contract spaces',\n });\n return;\n }\n onProgress?.({\n action: 'dbVerify',\n kind: 'spanEnd',\n spanId: SPAN_IDS.verify,\n outcome: kind === 'spanEndOk' ? 'ok' : 'error',\n });\n}\n\n/**\n * Map an {@link VerifierOutput} to the operation's\n * {@link ExecuteDbVerifyResult}, applying the `skipMarker` policy used\n * by the CLI's `--schema-only` mode.\n */\nfunction finaliseVerifyResult(args: {\n verifyResult: VerifierOutput<VerifyDatabaseSchemaResult>;\n aggregate: {\n readonly app: { readonly spaceId: string };\n readonly extensions: ReadonlyArray<{ readonly spaceId: string }>;\n };\n skipMarker: boolean;\n onProgress: OnControlProgress | undefined;\n}): ExecuteDbVerifyResult {\n const { verifyResult, aggregate, skipMarker, onProgress } = args;\n if (!verifyResult.ok) {\n emitVerifySpan(onProgress, 'spanEndError');\n return notOk(\n new CliStructuredError('5002', 'Aggregate verifier introspection failed', {\n domain: 'MIG',\n why: verifyResult.failure.detail,\n fix: 'Check database connectivity and the introspection tooling.',\n docsUrl: 'https://pris.ly/contract-spaces',\n }),\n );\n }\n const markerError = skipMarker\n ? null\n : mapMarkerCheckFailures(aggregate.app.spaceId, verifyResult.value.markerCheck);\n if (markerError !== null) {\n emitVerifySpan(onProgress, 'spanEndError');\n return notOk(markerError);\n }\n emitVerifySpan(onProgress, 'spanEndOk');\n return ok({\n schemaResults: verifyResult.value.schemaCheck.perSpace,\n memberOrder: [aggregate.app.spaceId, ...aggregate.extensions.map((e) => e.spaceId)],\n appSpaceId: aggregate.app.spaceId,\n });\n}\n\nfunction buildSkippedSchemaResult(member: ContractSpaceMember): VerifyDatabaseSchemaResult {\n const contract = member.contract();\n const headRef = requireHeadRef(member);\n const profileHash = castAs<{ profileHash?: string }>(contract).profileHash;\n return {\n ok: true,\n summary: 'Schema verification skipped',\n contract: {\n storageHash: headRef.hash,\n ...(profileHash ? { profileHash } : {}),\n },\n target: { expected: contract.target },\n schema: {\n issues: [],\n root: {\n status: 'pass',\n kind: 'skipped',\n name: member.spaceId,\n contractPath: '',\n code: 'SKIPPED',\n message: 'Schema verification skipped',\n expected: undefined,\n actual: undefined,\n children: [],\n },\n counts: { pass: 0, warn: 0, fail: 0, totalNodes: 0 },\n },\n timings: { total: 0 },\n };\n}\n\n/**\n * Translate per-space marker check failures and orphan markers into a\n * single CLI structured error envelope. Preserves the legacy code\n * `5002` (was emitted by `runContractSpaceVerifierMarkerCheck`).\n */\nfunction mapMarkerCheckFailures(\n appSpaceId: string,\n section: {\n readonly perSpace: ReadonlyMap<\n string,\n | { readonly kind: 'ok' }\n | { readonly kind: 'absent' }\n | { readonly kind: 'hashMismatch'; readonly markerHash: string; readonly expected: string }\n | { readonly kind: 'missingInvariants'; readonly missing: readonly string[] }\n >;\n readonly orphanMarkers: readonly { readonly spaceId: string; readonly row: unknown }[];\n },\n): CliStructuredError | null {\n const violations: Array<{\n kind: string;\n spaceId: string;\n remediation: string;\n }> = [];\n for (const [spaceId, result] of section.perSpace) {\n if (result.kind === 'ok' || result.kind === 'absent') continue;\n if (result.kind === 'hashMismatch') {\n violations.push({\n kind: 'hashMismatch',\n spaceId,\n remediation:\n spaceId === appSpaceId\n ? 'Run `prisma-next db update` to advance the marker, or roll the database back to the recorded hash.'\n : `Apply on-disk migrations under \\`migrations/${spaceId}/\\` to advance the marker, or remove the conflicting marker row.`,\n });\n continue;\n }\n if (result.kind === 'missingInvariants') {\n violations.push({\n kind: 'invariantsMismatch',\n spaceId,\n remediation: `Re-apply the migrations under \\`migrations/${spaceId}/\\` so the marker carries invariants: ${result.missing.join(', ')}.`,\n });\n }\n }\n for (const orphan of section.orphanMarkers) {\n violations.push({\n kind: 'orphanMarker',\n spaceId: orphan.spaceId,\n remediation: `Add the corresponding extension to \\`extensionPacks\\` in \\`prisma-next.config.ts\\`, or delete the orphan marker row for \"${orphan.spaceId}\".`,\n });\n }\n if (violations.length === 0) return null;\n const lines = violations.map((v) => `- [${v.kind}] ${v.spaceId}: ${v.remediation}`);\n const summary =\n violations.length === 1\n ? 'Contract-space verifier found a violation'\n : `Contract-space verifier found violations (${violations.length})`;\n return new CliStructuredError('5002', summary, {\n domain: 'MIG',\n why: `The on-disk \\`migrations/\\` directory, the \\`extensionPacks\\` declaration, and the live database marker rows are not in agreement.\\n${lines.join('\\n')}`,\n fix: violations[0]?.remediation ?? 'Review and reconcile the violations listed above.',\n docsUrl: 'https://pris.ly/contract-spaces',\n meta: { violations },\n });\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyInstance,\n TargetMigrationsCapability,\n} from '@prisma-next/framework-components/control';\nimport {\n type ContractMarkerRecordLike,\n type ContractSpaceAggregate,\n type ContractSpaceMember,\n graphWalkStrategy,\n type PerSpacePlan,\n requireHeadRef,\n} from '@prisma-next/migration-tools/aggregate';\nimport { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';\nimport { errorNoInvariantPath } from '@prisma-next/migration-tools/errors';\nimport { findPathWithDecision } from '@prisma-next/migration-tools/migration-graph';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport {\n type BuildAggregateInputs,\n buildContractSpaceAggregate,\n} from '../../utils/contract-space-aggregate-loader';\nimport type {\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n MigrationApplyResult,\n MigrationApplySuccess,\n OnControlProgress,\n PerSpaceExecutionEntry,\n} from '../types';\nimport { applyMigration, buildPerSpaceBreakdown } from './apply';\n\n/**\n * Inputs for the aggregate-walking `migrate` control-api\n * operation.\n *\n * The CLI command resolves the descriptor surface (config, refs,\n * contract envelope) and hands a flat input through. The operation\n * is the single descriptor-free seam between the CLI and the\n * aggregate runtime.\n */\nexport interface ExecuteMigrationApplyOptions<TFamilyId extends string, TTargetId extends string> {\n readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;\n readonly familyInstance: ControlFamilyInstance<TFamilyId, unknown>;\n /** Already-validated app contract (the canonical \"where we are heading\" hash). */\n readonly contract: Contract;\n readonly migrations: TargetMigrationsCapability<\n TFamilyId,\n TTargetId,\n ControlFamilyInstance<TFamilyId, unknown>\n >;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n readonly migrationsDir: string;\n readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;\n readonly targetId: TTargetId;\n /**\n * Optional app-space ref override. When provided, the app member's\n * graph-walk targets this hash instead of `member.headRef.hash`.\n * Extensions are unaffected — they always walk to their own head.\n */\n readonly refHash?: string;\n /**\n * Required invariants attached to the user-supplied app-space ref.\n * Threaded into the graph-walk's `required` calculation so the\n * planner picks an invariant-bearing path and surfaces the\n * required/satisfied set on the success envelope. When `refHash`\n * is absent the file's `member.headRef.invariants` are used.\n */\n readonly refInvariants?: readonly string[];\n /**\n * Resolved name of the user-supplied app-space ref. Surfaces in\n * `pathDecision.refName` and in `MIGRATION.NO_INVARIANT_PATH`\n * error envelopes so diagnostics name what the user actually\n * passed (`--ref prod`) instead of a synthetic placeholder.\n * Ignored when `refHash` is absent.\n */\n readonly refName?: string;\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Apply pending migrations across every contract space (app +\n * extensions). Replay-only: graph-walk against the on-disk graph for\n * every member; no synth, no introspection.\n *\n * Pipeline:\n *\n * 1. Load aggregate from disk (loader hydrates extension graphs;\n * caller provides app-space packages).\n * 2. Read live marker rows per space (`familyInstance.readAllMarkers`).\n * 3. Per member: `graphWalkStrategy` plots the path from the live\n * marker to `member.headRef.hash` (or `refHash` for the app\n * member when provided). Empty-graph members fail loudly — a\n * \"never planned\" space is a user-error condition for replay.\n * 4. Hand off to {@link applyMigration} (the runner-driving tail\n * shared with `db init` / `db update`). Marker advancement is\n * inside the per-space transaction.\n *\n * Encodes the replay-only contract: every contract space must have an\n * authored migration graph on disk before this operation can advance it.\n */\nexport async function executeMigrationApply<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteMigrationApplyOptions<TFamilyId, TTargetId>,\n): Promise<MigrationApplyResult> {\n const {\n driver,\n familyInstance,\n contract,\n migrations,\n frameworkComponents,\n migrationsDir,\n extensionPacks,\n targetId,\n refHash,\n refInvariants,\n refName,\n onProgress,\n } = options;\n\n const loadInputs: BuildAggregateInputs<TFamilyId, TTargetId> = {\n targetId,\n migrationsDir,\n appContract: contract,\n extensionPacks,\n deserializeContract: (json) => familyInstance.deserializeContract(json),\n };\n const loaded = await buildContractSpaceAggregate(loadInputs);\n if (!loaded.ok) {\n throw loaded.failure;\n }\n const aggregate = loaded.value;\n\n const markerRows = await familyInstance.readAllMarkers({ driver });\n\n // Plan every member via graph-walk. App member targets `refHash`\n // when provided, otherwise its own head; extensions always walk\n // to their own head ref.\n const allMembers: ReadonlyArray<ContractSpaceMember> = [aggregate.app, ...aggregate.extensions];\n const perSpacePlans = new Map<string, PerSpacePlan>();\n // Already-at-head empty-graph members (typically extensions whose\n // head ref is the empty sentinel, or whose live marker already\n // matches the target). Kept out of the runner schedule so we don't\n // write spurious markers for greenfield extensions, but merged back\n // into the success envelope so every loaded member is represented.\n const atHeadResolutions = new Map<string, PerSpacePlan>();\n for (const member of allMembers) {\n const isAppMember = member.spaceId === aggregate.app.spaceId;\n // The aggregate passed the integrity gate, so every member's head ref\n // is resolved (the app's is synthesised from the live contract).\n const headRef = requireHeadRef(member);\n const targetHash = isAppMember && refHash !== undefined ? refHash : headRef.hash;\n const liveMarker = markerRows.get(member.spaceId) ?? null;\n\n // Empty-graph members fail loudly: replay needs an on-disk path\n // and an empty graph means the user has never planned this space.\n if (member.graph().nodes.size === 0) {\n // Edge case: target == EMPTY (greenfield, nothing to do) or\n // the live marker already matches the target. Loader integrity\n // allows this for extensions whose head ref is the empty\n // sentinel. Record a zero-op resolution so the aggregate result\n // still surfaces the member in `perSpace[]` as already-at-head;\n // the runner is not invoked for these members because they have\n // no authored ops and (for greenfield extensions) no marker to\n // advance.\n const liveHash = liveMarker?.storageHash;\n if (\n targetHash === liveHash ||\n (liveHash === undefined && targetHash === EMPTY_CONTRACT_HASH)\n ) {\n atHeadResolutions.set(\n member.spaceId,\n buildAtHeadResolution({\n aggregateTargetId: aggregate.targetId,\n member,\n targetHash,\n liveMarker,\n }),\n );\n continue;\n }\n return notOk(buildNeverPlannedFailure(member.spaceId, targetHash));\n }\n\n const targetInvariants =\n isAppMember && refHash !== undefined && refInvariants !== undefined\n ? refInvariants\n : headRef.invariants;\n const targetMember: ContractSpaceMember =\n targetHash === headRef.hash && targetInvariants === headRef.invariants\n ? member\n : { ...member, headRef: { hash: targetHash, invariants: targetInvariants } };\n\n const walked = graphWalkStrategy({\n aggregateTargetId: aggregate.targetId,\n member: targetMember,\n currentMarker: liveMarker,\n ...(isAppMember && refName !== undefined ? { refName } : {}),\n });\n if (walked.kind === 'unreachable') {\n return notOk(buildPathNotFoundFailure(member.spaceId, liveMarker, targetHash));\n }\n if (walked.kind === 'unsatisfiable') {\n // Surface the canonical MIGRATION.NO_INVARIANT_PATH envelope\n // (the error rendering pipeline maps it to meta.code +\n // meta.required + meta.missing + meta.structuralPath that the\n // cli-journeys invariant suite asserts on).\n // Greenfield runs (no marker yet) use the canonical empty-hash\n // sentinel so the structural path stays attached to the\n // `MIGRATION.NO_INVARIANT_PATH` error envelope. Using an empty\n // string here would leave the structural lookup with a hash that\n // is never a graph node, producing an empty `structuralPath` and\n // a less actionable diagnostic.\n const fromHash = liveMarker?.storageHash ?? EMPTY_CONTRACT_HASH;\n const structural = findPathWithDecision(targetMember.graph(), fromHash, targetHash, {\n required: new Set<string>(),\n });\n const structuralPath =\n structural.kind === 'ok'\n ? structural.decision.selectedPath.map((edge) => ({\n dirName: edge.dirName,\n migrationHash: edge.migrationHash,\n from: edge.from,\n to: edge.to,\n invariants: edge.invariants,\n }))\n : [];\n throw errorNoInvariantPath({\n ...(isAppMember && refName !== undefined ? { refName } : {}),\n required: targetInvariants,\n missing: walked.missing,\n structuralPath,\n });\n }\n\n perSpacePlans.set(member.spaceId, walked.result);\n }\n\n const canonicalOrder = [...aggregate.extensions.map((m) => m.spaceId), aggregate.app.spaceId];\n const applyOrder = canonicalOrder.filter((spaceId) => perSpacePlans.has(spaceId));\n\n // Short-circuit: nothing pending across any space (no runner-bound\n // plans). Surfaces every loaded member — including at-head empty-\n // graph extensions — in `perSpace[]` so the result reflects the\n // full aggregate, not just the spaces the runner would have touched.\n const totalPlannedOps = sumPlannedOps(applyOrder, perSpacePlans);\n if (totalPlannedOps === 0) {\n const ordered = canonicalOrder\n .filter((spaceId) => perSpacePlans.has(spaceId) || atHeadResolutions.has(spaceId))\n .map((spaceId) => {\n const entry = perSpacePlans.get(spaceId) ?? atHeadResolutions.get(spaceId);\n if (entry === undefined) {\n throw new Error(`Unreachable: missing per-space plan for \"${spaceId}\"`);\n }\n return { spaceId, entry };\n });\n const perSpace = buildPerSpaceBreakdown(ordered, aggregate.app.spaceId, {\n includeMarkers: true,\n });\n const totalSpaces = ordered.length;\n return ok(\n buildSuccess({\n aggregate,\n orderedResolutions: ordered,\n perSpace,\n totalOpsExecuted: 0,\n summary:\n totalSpaces === 0\n ? 'Already up to date — no contract spaces are loaded'\n : totalSpaces === 1\n ? 'Already up to date'\n : `Already up to date across ${totalSpaces} space(s)`,\n }),\n );\n }\n\n const applied = await applyMigration({\n aggregate,\n perSpacePlans,\n applyOrder,\n driver,\n familyInstance,\n migrations,\n frameworkComponents,\n policy: { allowedOperationClasses: ['additive', 'widening', 'destructive', 'data'] },\n action: 'migrationApply',\n ...ifDefined('onProgress', onProgress),\n });\n\n if (!applied.ok) {\n const failure: MigrationApplyFailure = {\n code: 'RUNNER_FAILED',\n summary: applied.failure.summary,\n why: applied.failure.why,\n meta: applied.failure.meta,\n };\n return notOk(failure);\n }\n\n // Merge at-head zero-op resolutions back into the canonical order\n // so the success envelope surfaces every loaded member, not just\n // those the runner executed.\n const orderedAll = canonicalOrder\n .filter((spaceId) => perSpacePlans.has(spaceId) || atHeadResolutions.has(spaceId))\n .map((spaceId) => {\n if (perSpacePlans.has(spaceId)) {\n const fromRunner = applied.value.orderedResolutions.find((r) => r.spaceId === spaceId);\n if (fromRunner !== undefined) return fromRunner;\n }\n const entry = atHeadResolutions.get(spaceId);\n if (entry === undefined) {\n throw new Error(`Unreachable: missing per-space plan for \"${spaceId}\"`);\n }\n return { spaceId, entry };\n });\n const perSpaceAll = buildPerSpaceBreakdown(orderedAll, aggregate.app.spaceId, {\n includeMarkers: true,\n });\n const totalMigrationsApplied = applied.value.orderedResolutions.reduce(\n (sum, r) => sum + (r.entry.migrationEdges?.length ?? 0),\n 0,\n );\n const summary = `Applied ${totalMigrationsApplied} migration(s) (${applied.value.totalOpsExecuted} operation(s)) across ${orderedAll.length} contract space(s)`;\n\n return ok(\n buildSuccess({\n aggregate,\n orderedResolutions: orderedAll,\n perSpace: perSpaceAll,\n totalOpsExecuted: applied.value.totalOpsExecuted,\n summary,\n }),\n );\n}\n\n/**\n * Build a zero-op {@link PerSpacePlan} for an empty-graph\n * member whose live marker already matches the target. Lets the apply\n * pipeline thread the member through `perSpacePlans` -> `applyOrder`\n * -> the success envelope's `perSpace[]` block so the result reflects\n * every loaded space, even when there is nothing to execute.\n */\nfunction buildAtHeadResolution(args: {\n readonly aggregateTargetId: string;\n readonly member: ContractSpaceMember;\n readonly targetHash: string;\n readonly liveMarker: ContractMarkerRecordLike | null;\n}): PerSpacePlan {\n const { aggregateTargetId, member, targetHash, liveMarker } = args;\n return {\n plan: {\n targetId: aggregateTargetId,\n spaceId: member.spaceId,\n origin: liveMarker === null ? null : { storageHash: liveMarker.storageHash },\n destination: { storageHash: targetHash },\n operations: [],\n providedInvariants: [],\n },\n displayOps: [],\n destinationContract: member.contract(),\n strategy: 'graph-walk',\n migrationEdges: [],\n };\n}\n\nfunction sumPlannedOps(\n applyOrder: readonly string[],\n perSpacePlans: ReadonlyMap<string, PerSpacePlan>,\n): number {\n let total = 0;\n for (const spaceId of applyOrder) {\n const entry = perSpacePlans.get(spaceId);\n if (!entry) continue;\n total += entry.plan.operations.length;\n }\n return total;\n}\n\ninterface BuildSuccessArgs {\n readonly aggregate: ContractSpaceAggregate;\n readonly orderedResolutions: ReadonlyArray<{\n readonly spaceId: string;\n readonly entry: PerSpacePlan;\n }>;\n readonly perSpace: ReadonlyArray<PerSpaceExecutionEntry>;\n readonly totalOpsExecuted: number;\n readonly summary: string;\n}\n\nfunction buildSuccess(args: BuildSuccessArgs): MigrationApplySuccess {\n // The marker hash surfaced at the top level is the **app member's**\n // post-apply marker (the top-level `markerHash` field).\n // Per-space markers live on `perSpace[].marker.storageHash`.\n const appResolution = args.orderedResolutions.find(\n (r) => r.spaceId === args.aggregate.app.spaceId,\n );\n const appMarkerHash =\n appResolution?.entry.plan.destination.storageHash ?? requireHeadRef(args.aggregate.app).hash;\n\n // Per-migration entries (one per authored edge) preserve the\n // `migrationsApplied` count semantics for back-compat with existing\n // JSON-shape consumers (e.g. `parsed.applied.length` in integration\n // tests). The aggregate per-space breakdown lives on `perSpace[]`.\n const applied = args.orderedResolutions.flatMap((r) => {\n const edges = r.entry.migrationEdges ?? [];\n return edges.map((edge) => ({\n spaceId: r.spaceId,\n dirName: edge.dirName,\n migrationHash: edge.migrationHash,\n from: edge.from,\n to: edge.to,\n operationsExecuted: edge.operationCount,\n }));\n });\n\n const appPlan = appResolution?.entry;\n const pathDecision: MigrationApplyPathDecision | undefined = appPlan?.pathDecision\n ? {\n fromHash: appPlan.pathDecision.fromHash,\n toHash: appPlan.pathDecision.toHash,\n alternativeCount: appPlan.pathDecision.alternativeCount,\n tieBreakReasons: appPlan.pathDecision.tieBreakReasons,\n ...(appPlan.pathDecision.refName !== undefined\n ? { refName: appPlan.pathDecision.refName }\n : {}),\n requiredInvariants: appPlan.pathDecision.requiredInvariants ?? [],\n satisfiedInvariants: appPlan.pathDecision.satisfiedInvariants ?? [],\n selectedPath: appPlan.pathDecision.selectedPath.map((entry) => ({\n dirName: entry.dirName,\n migrationHash: entry.migrationHash,\n from: entry.from,\n to: entry.to,\n invariants: entry.invariants,\n })),\n }\n : undefined;\n\n return {\n migrationsApplied: applied.length,\n markerHash: appMarkerHash,\n applied,\n summary: args.summary,\n perSpace: args.perSpace,\n ...(pathDecision !== undefined ? { pathDecision } : {}),\n };\n}\n\n/**\n * Build the `neverPlanned` failure raised when a contract space has no on-disk\n * migration graph but migrate was asked to reach a target hash. The `why`\n * states only the condition; the recovery sequence is composed by\n * `errorPathUnreachable`'s `fix`.\n *\n * @internal Exported for testing only.\n */\nexport function buildNeverPlannedFailure(\n spaceId: string,\n targetHash: string,\n): MigrationApplyFailure {\n return {\n code: 'MIGRATION_PATH_NOT_FOUND',\n summary: `No on-disk migrations for contract space \"${spaceId}\"`,\n why: `migrate is replay-only: every contract space must have an authored migration graph on disk. Space \"${spaceId}\" has no migrations under \\`migrations/${spaceId}/\\` but its head ref targets \"${targetHash}\".`,\n meta: { spaceId, target: targetHash, kind: 'neverPlanned' },\n };\n}\n\n/**\n * Build the `pathUnreachable` failure raised when an emitted contract has no\n * on-disk migration edge from the current marker to the target. The `why`\n * states only the condition (no edge between the two named states, and migrate\n * replays edges rather than inventing them); the recovery sequence — plan the\n * edge, then re-apply — is composed by `errorPathUnreachable`'s `fix`, so the\n * two read as one non-redundant plan-then-apply story.\n *\n * @internal Exported for testing only.\n */\nexport function buildPathNotFoundFailure(\n spaceId: string,\n marker: ContractMarkerRecordLike | null,\n targetHash: string,\n): MigrationApplyFailure {\n const fromHash = marker?.storageHash ?? '<empty>';\n // The app-case phrasing names the user-visible condition (a\n // contract has been emitted that no on-disk migration reaches) so\n // the error reads naturally for the app member. Extension spaces\n // see the same condition expressed against the offending space.\n const summary =\n spaceId === 'app'\n ? 'Current contract has no planned migration path'\n : `Current contract has no planned migration path for contract space \"${spaceId}\"`;\n return {\n code: 'MIGRATION_PATH_NOT_FOUND',\n summary,\n why: `No migration edge connects the current state \"${fromHash}\" to the target \"${targetHash}\" in contract space \"${spaceId}\". The on-disk migration graph does not join the two, and migrate replays existing edges — it never invents one.`,\n meta: { spaceId, fromHash, targetHash, kind: 'pathUnreachable' },\n };\n}\n","import type { Contract, ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { emit as emitContractArtifacts } from '@prisma-next/emitter';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlFamilyInstance,\n ControlStack,\n CoreSchemaView,\n MigrationPlanOperation,\n OperationPreview,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n APP_SPACE_ID,\n createControlStack,\n hasMigrations,\n hasOperationPreview,\n hasPslContractInfer,\n hasSchemaView,\n} from '@prisma-next/framework-components/control';\nimport type { PslDocumentAst } from '@prisma-next/framework-components/psl-ast';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport { enrichContract } from './contract-enrichment';\nimport { ContractValidationError } from './errors';\nimport { executeDbInit } from './operations/db-init';\nimport { executeDbUpdate } from './operations/db-update';\nimport { type ExecuteDbVerifyResult, executeDbVerify } from './operations/db-verify';\nimport { executeMigrationApply } from './operations/migration-apply';\n\nimport type {\n ControlActionName,\n ControlClient,\n ControlClientOptions,\n DbInitOptions,\n DbInitResult,\n DbUpdateOptions,\n DbUpdateResult,\n DbVerifyOptions,\n EmitOptions,\n EmitResult,\n IntrospectOptions,\n MigrationApplyOptions,\n MigrationApplyResult,\n OnControlProgress,\n SchemaVerifyOptions,\n SignOptions,\n VerifyOptions,\n} from './types';\n\n/**\n * Creates a programmatic control client for Prisma Next operations.\n *\n * The client accepts framework component descriptors at creation time,\n * manages driver lifecycle via connect()/close(), and exposes domain\n * operations that delegate to the existing family instance methods.\n *\n * @see {@link ControlClient} for the client interface\n * @see README.md \"Programmatic Control API\" section for usage examples\n */\nexport function createControlClient(options: ControlClientOptions): ControlClient {\n return new ControlClientImpl(options);\n}\n\n/**\n * Implementation of ControlClient.\n * Manages initialization and connection state, delegates operations to family instance.\n */\nclass ControlClientImpl implements ControlClient {\n private readonly options: ControlClientOptions;\n private stack: ControlStack | null = null;\n private driver: ControlDriverInstance<string, string> | null = null;\n private familyInstance: ControlFamilyInstance<string, unknown> | null = null;\n private frameworkComponents: ReadonlyArray<\n TargetBoundComponentDescriptor<string, string>\n > | null = null;\n private initialized = false;\n private readonly defaultConnection: unknown;\n\n constructor(options: ControlClientOptions) {\n this.options = options;\n this.defaultConnection = options.connection;\n }\n\n init(): void {\n if (this.initialized) {\n return; // Idempotent\n }\n\n this.stack = createControlStack({\n family: this.options.family,\n target: this.options.target,\n adapter: this.options.adapter,\n driver: this.options.driver,\n extensionPacks: this.options.extensionPacks,\n });\n\n this.familyInstance = this.options.family.create(this.stack);\n\n // Validate and type-narrow framework components\n const rawComponents = [\n this.options.target,\n this.options.adapter,\n ...(this.options.extensionPacks ?? []),\n ];\n this.frameworkComponents = assertFrameworkComponentsCompatible(\n this.options.family.familyId,\n this.options.target.targetId,\n rawComponents,\n );\n\n this.initialized = true;\n }\n\n async connect(connection?: unknown): Promise<void> {\n // Auto-init if needed\n this.init();\n\n if (this.driver) {\n throw new Error('Already connected. Call close() before reconnecting.');\n }\n\n // Resolve connection: argument > default from options\n const resolvedConnection = connection ?? this.defaultConnection;\n if (resolvedConnection === undefined) {\n throw new Error(\n 'No connection provided. Pass a connection to connect() or provide a default connection when creating the client.',\n );\n }\n\n // Check for driver descriptor\n if (!this.stack?.driver) {\n throw new Error(\n 'Driver is not configured. Pass a driver descriptor when creating the control client to enable database operations.',\n );\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: required for runtime connection type flexibility\n this.driver = await this.stack.driver.create(resolvedConnection as any);\n }\n\n async close(): Promise<void> {\n if (this.driver) {\n await this.driver.close();\n this.driver = null;\n }\n }\n\n private async ensureConnected(): Promise<{\n driver: ControlDriverInstance<string, string>;\n familyInstance: ControlFamilyInstance<string, unknown>;\n frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<string, string>>;\n }> {\n // Auto-init if needed\n this.init();\n\n // Auto-connect if not connected and default connection is available\n if (!this.driver && this.defaultConnection !== undefined) {\n await this.connect(this.defaultConnection);\n }\n\n if (!this.driver || !this.familyInstance || !this.frameworkComponents) {\n throw new Error('Not connected. Call connect(connection) first.');\n }\n return {\n driver: this.driver,\n familyInstance: this.familyInstance,\n frameworkComponents: this.frameworkComponents,\n };\n }\n\n private async connectWithProgress(\n connection: unknown | undefined,\n action: ControlActionName,\n onProgress?: OnControlProgress,\n ): Promise<void> {\n if (connection === undefined) return;\n onProgress?.({\n action,\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(connection);\n onProgress?.({ action, kind: 'spanEnd', spanId: 'connect', outcome: 'ok' });\n } catch (error) {\n onProgress?.({ action, kind: 'spanEnd', spanId: 'connect', outcome: 'error' });\n throw error;\n }\n }\n\n async verify(options: VerifyOptions): Promise<VerifyDatabaseResult> {\n const { onProgress } = options;\n await this.connectWithProgress(options.connection, 'verify', onProgress);\n const { driver, familyInstance } = await this.ensureConnected();\n\n // Validate contract using family instance\n let contract: Contract;\n try {\n contract = familyInstance.deserializeContract(options.contract);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new ContractValidationError(message, error);\n }\n\n // Emit verify span\n onProgress?.({\n action: 'verify',\n kind: 'spanStart',\n spanId: 'verify',\n label: 'Verifying database marker...',\n });\n\n try {\n // Delegate to family instance verify method\n // Note: We pass empty strings for contractPath/configPath since the programmatic\n // API doesn't deal with file paths. The family instance accepts these as optional\n // metadata for error reporting.\n const result = await familyInstance.verify({\n driver,\n contract,\n expectedTargetId: this.options.target.targetId,\n contractPath: '',\n });\n\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'verify',\n outcome: result.ok ? 'ok' : 'error',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'verify',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult> {\n const { onProgress } = options;\n await this.connectWithProgress(options.connection, 'schemaVerify', onProgress);\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n // Validate contract using family instance\n let contract: Contract;\n try {\n contract = familyInstance.deserializeContract(options.contract);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new ContractValidationError(message, error);\n }\n\n // Emit schemaVerify span\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanStart',\n spanId: 'schemaVerify',\n label: 'Verifying database schema...',\n });\n\n try {\n // Introspect the live schema, then verify the contract against\n // it. Composing the two primitives here keeps the family\n // interface a single synchronous verifier and gives callers\n // (and tests) explicit control over the introspected schema.\n const schema = await familyInstance.introspect({ driver, contract });\n const result = familyInstance.verifySchema({\n contract,\n schema,\n strict: options.strict ?? false,\n frameworkComponents,\n });\n\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'schemaVerify',\n outcome: result.ok ? 'ok' : 'error',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'schemaVerify',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async sign(options: SignOptions): Promise<SignDatabaseResult> {\n const { onProgress } = options;\n await this.connectWithProgress(options.connection, 'sign', onProgress);\n const { driver, familyInstance } = await this.ensureConnected();\n\n // Validate contract using family instance\n let contract: Contract;\n try {\n contract = familyInstance.deserializeContract(options.contract);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new ContractValidationError(message, error);\n }\n\n // Emit sign span\n onProgress?.({\n action: 'sign',\n kind: 'spanStart',\n spanId: 'sign',\n label: 'Signing database...',\n });\n\n try {\n // Delegate to family instance sign method\n const result = await familyInstance.sign({\n driver,\n contract,\n contractPath: options.contractPath ?? '',\n ...ifDefined('configPath', options.configPath),\n });\n\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'sign',\n outcome: 'ok',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'sign',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async dbInit(options: DbInitOptions): Promise<DbInitResult> {\n const { onProgress } = options;\n await this.connectWithProgress(options.connection, 'dbInit', onProgress);\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n if (!hasMigrations(this.options.target)) {\n throw new Error(`Target \"${this.options.target.targetId}\" does not support migrations`);\n }\n\n let contract: Contract;\n try {\n contract = familyInstance.deserializeContract(options.contract);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new ContractValidationError(message, error);\n }\n\n return executeDbInit({\n driver,\n familyInstance,\n contract,\n mode: options.mode,\n migrations: this.options.target.migrations,\n frameworkComponents,\n migrationsDir: options.migrationsDir,\n targetId: this.options.target.targetId,\n extensionPacks: this.options.extensionPacks ?? [],\n ...ifDefined('onProgress', onProgress),\n });\n }\n\n async dbUpdate(options: DbUpdateOptions): Promise<DbUpdateResult> {\n const { onProgress } = options;\n await this.connectWithProgress(options.connection, 'dbUpdate', onProgress);\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n if (!hasMigrations(this.options.target)) {\n throw new Error(`Target \"${this.options.target.targetId}\" does not support migrations`);\n }\n\n let contract: Contract;\n try {\n contract = familyInstance.deserializeContract(options.contract);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new ContractValidationError(message, error);\n }\n\n return executeDbUpdate({\n driver,\n familyInstance,\n contract,\n mode: options.mode,\n migrations: this.options.target.migrations,\n frameworkComponents,\n migrationsDir: options.migrationsDir,\n targetId: this.options.target.targetId,\n extensionPacks: this.options.extensionPacks ?? [],\n ...ifDefined('acceptDataLoss', options.acceptDataLoss),\n ...ifDefined('onProgress', onProgress),\n });\n }\n\n async dbVerify(options: DbVerifyOptions): Promise<ExecuteDbVerifyResult> {\n const { onProgress } = options;\n await this.connectWithProgress(options.connection, 'dbVerify', onProgress);\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n return executeDbVerify({\n driver,\n familyInstance,\n contract: options.contract,\n migrationsDir: options.migrationsDir,\n targetId: this.options.target.targetId,\n extensionPacks: this.options.extensionPacks ?? [],\n frameworkComponents,\n mode: options.strict ? 'strict' : 'lenient',\n skipSchema: options.skipSchema,\n skipMarker: options.skipMarker,\n ...ifDefined('onProgress', onProgress),\n });\n }\n\n async readMarker(): Promise<ContractMarkerRecord | null> {\n const { driver, familyInstance } = await this.ensureConnected();\n // The CLI client's readMarker reads the app's marker. Per-extension\n // readers go through the orchestrator's per-space planner / runner\n // boundary, which threads the extension's space id through the\n // family interface explicitly.\n return familyInstance.readMarker({ driver, space: APP_SPACE_ID });\n }\n\n async readAllMarkers(): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const { driver, familyInstance } = await this.ensureConnected();\n return familyInstance.readAllMarkers({ driver });\n }\n\n async migrationApply(options: MigrationApplyOptions): Promise<MigrationApplyResult> {\n const { onProgress } = options;\n await this.connectWithProgress(options.connection, 'migrationApply', onProgress);\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n if (!hasMigrations(this.options.target)) {\n throw new Error(`Target \"${this.options.target.targetId}\" does not support migrations`);\n }\n\n let contract: Contract;\n try {\n contract = familyInstance.deserializeContract(options.contract);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new ContractValidationError(message, error);\n }\n\n return executeMigrationApply({\n driver,\n familyInstance,\n contract,\n migrations: this.options.target.migrations,\n frameworkComponents,\n migrationsDir: options.migrationsDir,\n extensionPacks: this.options.extensionPacks ?? [],\n targetId: this.options.target.targetId,\n ...ifDefined('refHash', options.refHash),\n ...ifDefined('refInvariants', options.refInvariants),\n ...ifDefined('refName', options.refName),\n ...ifDefined('onProgress', onProgress),\n });\n }\n\n async introspect(options?: IntrospectOptions): Promise<unknown> {\n const onProgress = options?.onProgress;\n await this.connectWithProgress(options?.connection, 'introspect', onProgress);\n const { driver, familyInstance } = await this.ensureConnected();\n\n // TODO: Pass schema option to familyInstance.introspect when schema filtering is implemented\n const _schema = options?.schema;\n void _schema;\n\n // Emit introspect span\n onProgress?.({\n action: 'introspect',\n kind: 'spanStart',\n spanId: 'introspect',\n label: 'Introspecting database schema...',\n });\n\n try {\n const result = await familyInstance.introspect({ driver });\n\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'introspect',\n outcome: 'ok',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'introspect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n toSchemaView(schemaIR: unknown): CoreSchemaView | undefined {\n this.init();\n if (this.familyInstance && hasSchemaView(this.familyInstance)) {\n return this.familyInstance.toSchemaView(schemaIR);\n }\n return undefined;\n }\n\n inferPslContract(schemaIR: unknown): PslDocumentAst | undefined {\n this.init();\n if (this.familyInstance && hasPslContractInfer(this.familyInstance)) {\n return this.familyInstance.inferPslContract(schemaIR);\n }\n return undefined;\n }\n\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview | undefined {\n this.init();\n if (this.familyInstance && hasOperationPreview(this.familyInstance)) {\n return this.familyInstance.toOperationPreview(operations);\n }\n return undefined;\n }\n\n async emit(options: EmitOptions): Promise<EmitResult> {\n const { onProgress, contractConfig } = options;\n\n // Ensure initialized (creates stack and family instance)\n // emit() does NOT require a database connection\n this.init();\n\n if (!this.familyInstance) {\n throw new Error('Family instance was not initialized. This is a bug.');\n }\n\n let contractRaw: unknown;\n onProgress?.({\n action: 'emit',\n kind: 'spanStart',\n spanId: 'resolveSource',\n label: 'Resolving contract source...',\n });\n\n try {\n const stack = this.stack!;\n const sourceContext = {\n composedExtensionPacks: stack.extensionPacks.map((p) => p.id),\n scalarTypeDescriptors: stack.scalarTypeDescriptors,\n authoringContributions: stack.authoringContributions,\n codecLookup: stack.codecLookup,\n controlMutationDefaults: stack.controlMutationDefaults,\n resolvedInputs: contractConfig.source.inputs ?? [],\n };\n const providerResult = await contractConfig.source.load(sourceContext);\n if (!providerResult.ok) {\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'resolveSource',\n outcome: 'error',\n });\n\n return notOk({\n code: 'CONTRACT_SOURCE_INVALID',\n summary: providerResult.failure.summary,\n why: providerResult.failure.summary,\n meta: providerResult.failure.meta,\n diagnostics: providerResult.failure,\n });\n }\n contractRaw = providerResult.value;\n\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'resolveSource',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'resolveSource',\n outcome: 'error',\n });\n\n const message = error instanceof Error ? error.message : String(error);\n return notOk({\n code: 'CONTRACT_SOURCE_INVALID',\n summary: 'Failed to resolve contract source',\n why: message,\n diagnostics: {\n summary: 'Contract source provider threw an exception',\n diagnostics: [\n {\n code: 'PROVIDER_THROW',\n message,\n },\n ],\n },\n meta: undefined,\n });\n }\n\n // Emit contract\n onProgress?.({\n action: 'emit',\n kind: 'spanStart',\n spanId: 'emit',\n label: 'Emitting contract...',\n });\n\n try {\n // Blind cast: `contractRaw` is the unverified provider\n // payload — `enrichContract` only adds capability + extension\n // metadata onto whatever shape it receives. The structural\n // check happens immediately afterwards via\n // `familyInstance.deserializeContract(enrichedIR)`, which is\n // the seam-of-record and the only thing that may surface\n // structural errors to the caller.\n const enrichedIR = enrichContract(\n contractRaw as unknown as Contract,\n this.frameworkComponents ?? [],\n );\n\n try {\n this.familyInstance.deserializeContract(enrichedIR);\n } catch (error) {\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'emit',\n outcome: 'error',\n });\n const message = error instanceof Error ? error.message : String(error);\n return notOk({\n code: 'CONTRACT_VALIDATION_FAILED',\n summary: 'Contract validation failed',\n why: message,\n meta: undefined,\n });\n }\n\n const result = await emitContractArtifacts(\n enrichedIR,\n this.stack!,\n this.options.family.emission,\n {\n serializeContract: (contract) =>\n this.options.target.contractSerializer.serializeContract(contract),\n },\n );\n\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'emit',\n outcome: 'ok',\n });\n\n return ok({\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n profileHash: result.profileHash,\n contractJson: result.contractJson,\n contractDts: result.contractDts,\n });\n } catch (error) {\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'emit',\n outcome: 'error',\n });\n\n return notOk({\n code: 'EMIT_FAILED',\n summary: 'Failed to emit contract',\n why: error instanceof Error ? error.message : String(error),\n meta: undefined,\n });\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"migration-graph-D7DVUElV.mjs","names":[],"sources":["../src/utils/formatters/migration-graph-layout.ts","../src/utils/formatters/migration-graph-rows.ts","../src/utils/formatters/migration-graph-tree-render.ts","../src/commands/migration-graph.ts"],"sourcesContent":["import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';\nimport type { ClassifiedEdge, MigrationGraphRowModel } from './migration-graph-rows';\nimport type { MigrationEdgeKind } from './migration-list-graph-topology';\n\nexport type EdgeAdjacency = 'adjacent' | 'node-skipping-forward' | 'node-skipping-rollback';\n\nexport type StructuralCell =\n | { readonly kind: 'empty' }\n | {\n readonly kind: 'node';\n readonly contractHash: string;\n readonly arcTee?: boolean;\n readonly arcLand?: boolean;\n }\n | { readonly kind: 'vertical-pass' }\n | { readonly kind: 'horizontal-pass' }\n | { readonly kind: 'branch-tee' }\n | { readonly kind: 'branch-corner' }\n | { readonly kind: 'merge-tee' }\n | { readonly kind: 'merge-corner' }\n | { readonly kind: 'arc-branch-corner' }\n | { readonly kind: 'arc-branch-tee' }\n | { readonly kind: 'arc-land-corner' }\n | { readonly kind: 'arc-crossing' }\n | { readonly kind: 'arc-land-bridge' }\n | {\n readonly kind: 'edge-lane';\n readonly migrationHash: string;\n readonly edgeKind: MigrationEdgeKind;\n readonly ownsLabel: boolean;\n readonly adjacency: EdgeAdjacency;\n };\n\nexport type GridRowKind =\n | 'node'\n | 'edge'\n | 'branch-connector'\n | 'merge-connector'\n | 'component-separator';\n\nexport interface MigrationGraphGridRow {\n readonly kind: GridRowKind;\n readonly contractHash?: string;\n readonly edge?: ClassifiedEdge;\n readonly laneIndex?: number;\n readonly passThroughLanes?: readonly number[];\n readonly startLane?: number;\n readonly endLane?: number;\n readonly branchCount?: number;\n readonly convergenceProducer?: boolean;\n readonly cells: readonly StructuralCell[];\n}\n\nexport interface MigrationGraphGridModel {\n readonly rows: readonly MigrationGraphGridRow[];\n readonly nodeColumn: ReadonlyMap<string, number>;\n readonly edgeColumn: ReadonlyMap<string, number>;\n}\n\n// ---------------------------------------------------------------------------\n// Edge bucketing helpers\n// ---------------------------------------------------------------------------\n\nfunction forwardEdges(edges: readonly ClassifiedEdge[]): ClassifiedEdge[] {\n return edges.filter((e) => e.kind === 'forward');\n}\n\nfunction buildForwardProducersByTo(\n edges: readonly ClassifiedEdge[],\n): Map<string, ClassifiedEdge[]> {\n const byTo = new Map<string, ClassifiedEdge[]>();\n for (const edge of edges) {\n if (edge.kind !== 'forward') continue;\n const bucket = byTo.get(edge.to);\n if (bucket) bucket.push(edge);\n else byTo.set(edge.to, [edge]);\n }\n return byTo;\n}\n\nfunction buildForwardOutDegree(edges: readonly ClassifiedEdge[]): Map<string, number> {\n const out = new Map<string, number>();\n for (const edge of edges) {\n if (edge.kind !== 'forward' || edge.from === edge.to) continue;\n out.set(edge.from, (out.get(edge.from) ?? 0) + 1);\n }\n return out;\n}\n\nfunction buildForwardInDegree(edges: readonly ClassifiedEdge[]): Map<string, number> {\n const indeg = new Map<string, number>();\n for (const edge of forwardEdges(edges)) {\n if (edge.from === edge.to) continue;\n indeg.set(edge.to, (indeg.get(edge.to) ?? 0) + 1);\n }\n return indeg;\n}\n\n/**\n * Distinct source contracts among a contract's forward producers. A contract is\n * a *convergence* when this count is >= 2. Multiple migrations sharing one\n * source (a multi-edge) count once — they stack in a single lane rather than\n * fanning into a convergence.\n */\nfunction buildDistinctSourceCountByTo(edges: readonly ClassifiedEdge[]): Map<string, number> {\n const sources = new Map<string, Set<string>>();\n for (const edge of edges) {\n if (edge.kind !== 'forward' || edge.from === edge.to) continue;\n const set = sources.get(edge.to);\n if (set) set.add(edge.from);\n else sources.set(edge.to, new Set([edge.from]));\n }\n const counts = new Map<string, number>();\n for (const [to, set] of sources) counts.set(to, set.size);\n return counts;\n}\n\nfunction splitComponents(nodes: readonly (string | null)[]): readonly (readonly string[])[] {\n const components: string[][] = [];\n let current: string[] = [];\n for (const node of nodes) {\n if (node === null) {\n if (current.length > 0) {\n components.push(current);\n current = [];\n }\n continue;\n }\n current.push(node);\n }\n if (current.length > 0) components.push(current);\n return components;\n}\n\n// ---------------------------------------------------------------------------\n// Adjacency refinement (operates on the emitted rows)\n// ---------------------------------------------------------------------------\n\nfunction classifyForwardShortConvergenceAdjacency(\n rows: readonly MigrationGraphGridRow[],\n edgeRowIndex: number,\n edge: ClassifiedEdge,\n laneIndex: number,\n): EdgeAdjacency {\n for (let index = edgeRowIndex + 1; index < rows.length; index++) {\n const row = rows[index];\n if (row === undefined) break;\n if (row.kind === 'component-separator' || row.kind === 'branch-connector') continue;\n if (row.kind === 'merge-connector') continue;\n if (row.kind === 'edge') {\n if (row.laneIndex === laneIndex) return 'node-skipping-forward';\n continue;\n }\n if (row.kind === 'node' && row.contractHash === edge.from) {\n return 'adjacent';\n }\n }\n return 'node-skipping-forward';\n}\n\nfunction convergenceProducerUsesShortAdjacency(\n edge: ClassifiedEdge,\n laneIndex: number,\n forwardProducersByTo: ReadonlyMap<string, readonly ClassifiedEdge[]>,\n producerLaneByHash: ReadonlyMap<string, number>,\n): boolean {\n const producers = (forwardProducersByTo.get(edge.to) ?? []).filter(\n (candidate) => candidate.kind === 'forward',\n );\n if (producers.length < 2) return false;\n\n const fanLanes = [\n ...new Set(\n producers\n .map((producer) => producerLaneByHash.get(producer.migrationHash))\n .filter((candidate): candidate is number => candidate !== undefined),\n ),\n ].sort((a, b) => a - b);\n const fanStart = fanLanes[0];\n if (fanStart === undefined) return false;\n\n return laneIndex === fanStart;\n}\n\nfunction classifyForwardLayoutAdjacency(\n rows: readonly MigrationGraphGridRow[],\n edgeRowIndex: number,\n edge: ClassifiedEdge,\n laneIndex: number,\n passThroughLanes: readonly number[],\n nodeColumn: ReadonlyMap<string, number>,\n convergenceProducer: boolean,\n divergenceBranchEdge: boolean,\n): EdgeAdjacency {\n let sawObstruction = false;\n const passThroughLaneSet = new Set(passThroughLanes);\n\n for (let index = edgeRowIndex + 1; index < rows.length; index++) {\n const row = rows[index];\n if (row === undefined) break;\n if (row.kind === 'component-separator') continue;\n if (row.kind === 'merge-connector') {\n if (convergenceProducer) {\n if (row.contractHash === edge.from) sawObstruction = true;\n } else if (!divergenceBranchEdge && row.contractHash !== edge.from) {\n sawObstruction = true;\n }\n continue;\n }\n if (row.kind === 'branch-connector') continue;\n if (row.kind === 'edge') {\n if (row.laneIndex === laneIndex) return 'node-skipping-forward';\n if (!divergenceBranchEdge && row.edge !== undefined && row.edge.to !== edge.to) {\n sawObstruction = true;\n }\n continue;\n }\n if (row.kind === 'node' && row.contractHash !== undefined) {\n if (row.contractHash === edge.from) {\n return sawObstruction ? 'node-skipping-forward' : 'adjacent';\n }\n const nodeCol = nodeColumn.get(row.contractHash) ?? 0;\n // A divergence-branch lane runs unobstructed to its convergence point;\n // sibling-branch nodes sit in parallel lanes and never block it.\n if (!divergenceBranchEdge && !passThroughLaneSet.has(nodeCol)) {\n sawObstruction = true;\n }\n }\n }\n\n return 'node-skipping-forward';\n}\n\nfunction classifyLayoutAdjacency(\n rows: readonly MigrationGraphGridRow[],\n edgeRowIndex: number,\n edge: ClassifiedEdge,\n laneIndex: number,\n passThroughLanes: readonly number[],\n nodeColumn: ReadonlyMap<string, number>,\n position: ReadonlyMap<string, number>,\n forwardInDegree: ReadonlyMap<string, number>,\n convergenceProducer: boolean,\n divergenceBranchEdge: boolean,\n): EdgeAdjacency {\n if (edge.kind === 'self') return 'adjacent';\n\n const fromPos = position.get(edge.from);\n const toPos = position.get(edge.to);\n\n if (edge.kind === 'forward') {\n const inDegree = forwardInDegree.get(edge.to) ?? 0;\n if (inDegree <= 1 && fromPos !== undefined && toPos !== undefined && fromPos === toPos + 1) {\n return 'adjacent';\n }\n return classifyForwardLayoutAdjacency(\n rows,\n edgeRowIndex,\n edge,\n laneIndex,\n passThroughLanes,\n nodeColumn,\n convergenceProducer,\n divergenceBranchEdge,\n );\n }\n\n if (fromPos !== undefined && toPos !== undefined && toPos === fromPos + 1) {\n return 'adjacent';\n }\n\n for (let index = edgeRowIndex + 1; index < rows.length; index++) {\n const row = rows[index];\n if (row === undefined) break;\n if (\n row.kind === 'component-separator' ||\n row.kind === 'branch-connector' ||\n row.kind === 'merge-connector'\n ) {\n continue;\n }\n if (row.kind === 'edge') continue;\n if (row.kind === 'node') {\n return row.contractHash === edge.to ? 'adjacent' : 'node-skipping-rollback';\n }\n }\n return 'node-skipping-rollback';\n}\n\nfunction refineAdjacency(\n rows: readonly MigrationGraphGridRow[],\n nodeColumn: ReadonlyMap<string, number>,\n position: ReadonlyMap<string, number>,\n forwardInDegree: ReadonlyMap<string, number>,\n forwardOutDegree: ReadonlyMap<string, number>,\n edges: readonly ClassifiedEdge[],\n producerLaneByHash: ReadonlyMap<string, number>,\n): MigrationGraphGridRow[] {\n const forwardProducersByTo = buildForwardProducersByTo(edges);\n function branchLaneForEdge(producer: ClassifiedEdge): number | undefined {\n const children = edges.filter(\n (edge) => edge.from === producer.from && edge.kind === 'forward' && edge.from !== edge.to,\n );\n if (children.length < 2) return undefined;\n const index = children.findIndex((child) => child.migrationHash === producer.migrationHash);\n return index >= 0 ? index : undefined;\n }\n\n return rows.map((row, rowIndex) => {\n if (row.kind !== 'edge' || row.edge === undefined || row.laneIndex === undefined) {\n return row;\n }\n const divergenceBranchEdge =\n row.edge.kind === 'forward' &&\n !(row.convergenceProducer ?? false) &&\n (forwardOutDegree.get(row.edge.from) ?? 0) >= 2 &&\n branchLaneForEdge(row.edge) !== undefined;\n const adjacency =\n row.convergenceProducer === true &&\n convergenceProducerUsesShortAdjacency(\n row.edge,\n row.laneIndex,\n forwardProducersByTo,\n producerLaneByHash,\n )\n ? classifyForwardShortConvergenceAdjacency(rows, rowIndex, row.edge, row.laneIndex)\n : classifyLayoutAdjacency(\n rows,\n rowIndex,\n row.edge,\n row.laneIndex,\n row.passThroughLanes ?? [],\n nodeColumn,\n position,\n forwardInDegree,\n row.convergenceProducer ?? false,\n divergenceBranchEdge,\n );\n return {\n ...row,\n cells: buildEdgeCells(\n row.edge,\n row.laneIndex,\n row.passThroughLanes ?? [],\n adjacency,\n row.cells.length,\n ),\n };\n });\n}\n\nfunction classifyEdgeAdjacency(\n edge: ClassifiedEdge,\n position: ReadonlyMap<string, number>,\n): EdgeAdjacency {\n if (edge.kind === 'self') return 'adjacent';\n\n const fromPos = position.get(edge.from);\n const toPos = position.get(edge.to);\n if (fromPos === undefined || toPos === undefined) return 'adjacent';\n\n if (edge.kind === 'forward') {\n if (toPos >= fromPos) return 'adjacent';\n return fromPos === toPos + 1 ? 'adjacent' : 'node-skipping-forward';\n }\n\n if (toPos <= fromPos) return 'adjacent';\n return toPos === fromPos + 1 ? 'adjacent' : 'node-skipping-rollback';\n}\n\n// ---------------------------------------------------------------------------\n// Cell builders\n// ---------------------------------------------------------------------------\n\nfunction emptyCells(width: number): StructuralCell[] {\n return Array.from({ length: width }, () => ({ kind: 'empty' as const }));\n}\n\nfunction buildBranchConnectorCells(\n startLane: number,\n endLane: number,\n activeLanes: ReadonlySet<number>,\n gridWidth: number,\n): StructuralCell[] {\n const cells = emptyCells(gridWidth);\n for (let lane = 0; lane < gridWidth; lane++) {\n if (activeLanes.has(lane) && (lane < startLane || lane > endLane)) {\n cells[lane] = { kind: 'vertical-pass' };\n continue;\n }\n if (lane === startLane) {\n cells[lane] = { kind: 'branch-tee' };\n } else if (lane === endLane) {\n cells[lane] = { kind: 'branch-corner' };\n } else if (lane > startLane && lane < endLane) {\n cells[lane] = { kind: 'branch-tee' };\n }\n }\n return cells;\n}\n\nfunction buildMergeConnectorCells(\n startLane: number,\n endLane: number,\n activeLanes: ReadonlySet<number>,\n gridWidth: number,\n): StructuralCell[] {\n const cells = emptyCells(gridWidth);\n for (let lane = 0; lane < gridWidth; lane++) {\n if (activeLanes.has(lane) && (lane < startLane || lane > endLane)) {\n cells[lane] = { kind: 'vertical-pass' };\n continue;\n }\n if (lane === startLane) {\n cells[lane] = { kind: 'merge-tee' };\n } else if (lane === endLane) {\n cells[lane] = { kind: 'merge-corner' };\n } else if (lane > startLane && lane < endLane) {\n cells[lane] = activeLanes.has(lane) ? { kind: 'merge-tee' } : { kind: 'horizontal-pass' };\n }\n }\n return cells;\n}\n\nfunction buildNodeCells(\n contractHash: string,\n nodeColumn: number,\n activeLanes: readonly number[],\n gridWidth: number,\n): StructuralCell[] {\n const cells = emptyCells(gridWidth);\n for (const lane of activeLanes) {\n if (lane !== nodeColumn && lane < gridWidth) {\n cells[lane] = { kind: 'vertical-pass' };\n }\n }\n if (nodeColumn < gridWidth) {\n cells[nodeColumn] = { kind: 'node', contractHash };\n }\n return cells;\n}\n\nfunction buildEdgeCells(\n edge: ClassifiedEdge,\n laneIndex: number,\n passThroughLanes: readonly number[],\n adjacency: EdgeAdjacency,\n gridWidth: number,\n): StructuralCell[] {\n const cells = emptyCells(gridWidth);\n for (const lane of passThroughLanes) {\n if (lane < gridWidth) cells[lane] = { kind: 'vertical-pass' };\n }\n if (laneIndex < gridWidth) {\n cells[laneIndex] = {\n kind: 'edge-lane',\n migrationHash: edge.migrationHash,\n edgeKind: edge.kind,\n ownsLabel: true,\n adjacency,\n };\n }\n return cells;\n}\n\n// ---------------------------------------------------------------------------\n// Vertical ordering: tips-first DFS post-order over forward edges\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the vertical node order for a component: tips at the top (index 0),\n * roots at the bottom. This is a DFS post-order over forward edges starting\n * from forward roots, visiting children in their input (insertion) order. A\n * node is emitted only after all of its forward children, so convergence nodes\n * sit below every branch that feeds them and the longest contiguous chain reads\n * top-to-bottom without braiding.\n */\nfunction computeVerticalOrder(\n componentNodes: readonly string[],\n forwardChildren: ReadonlyMap<string, readonly ClassifiedEdge[]>,\n forwardInDegree: ReadonlyMap<string, number>,\n): string[] {\n const WHITE = 0;\n const GRAY = 1;\n const BLACK = 2;\n const color = new Map<string, number>();\n for (const node of componentNodes) color.set(node, WHITE);\n\n const sortRoots = (roots: readonly string[]): string[] =>\n [...roots].sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n\n let roots = sortRoots(componentNodes.filter((n) => (forwardInDegree.get(n) ?? 0) === 0));\n if (roots.length === 0) roots = sortRoots(componentNodes);\n\n const result: string[] = [];\n\n interface Frame {\n node: string;\n children: readonly ClassifiedEdge[];\n index: number;\n }\n\n function runDfs(root: string): void {\n if (color.get(root) !== WHITE) return;\n const stack: Frame[] = [{ node: root, children: forwardChildren.get(root) ?? [], index: 0 }];\n color.set(root, GRAY);\n\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n if (frame === undefined) break;\n if (frame.index >= frame.children.length) {\n color.set(frame.node, BLACK);\n result.push(frame.node);\n stack.pop();\n continue;\n }\n const child = frame.children[frame.index];\n frame.index += 1;\n if (child === undefined) continue;\n if (color.get(child.to) === WHITE) {\n color.set(child.to, GRAY);\n stack.push({ node: child.to, children: forwardChildren.get(child.to) ?? [], index: 0 });\n }\n }\n }\n\n for (const root of roots) runDfs(root);\n // Nodes unreachable via forward edges (e.g. rollback-only sources) follow in\n // component order.\n for (const node of componentNodes) {\n if (color.get(node) === WHITE) runDfs(node);\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Routed back-arcs for node-skipping rollbacks\n// ---------------------------------------------------------------------------\n\ninterface SkipRollbackRoute {\n readonly edge: ClassifiedEdge;\n readonly backLane: number;\n}\n\nfunction rollbackSpan(\n edge: ClassifiedEdge,\n position: ReadonlyMap<string, number>,\n): { readonly top: number; readonly bottom: number } {\n const top = position.get(edge.from) ?? 0;\n const bottom = position.get(edge.to) ?? top;\n return { top, bottom };\n}\n\nfunction spansOverlap(\n a: { readonly top: number; readonly bottom: number },\n b: { readonly top: number; readonly bottom: number },\n): boolean {\n return a.top <= b.bottom && b.top <= a.bottom;\n}\n\nfunction forwardMaxLane(\n rows: readonly MigrationGraphGridRow[],\n skipMigrationHashes: ReadonlySet<string>,\n): number {\n let max = 0;\n for (const row of rows) {\n if (\n row.kind === 'edge' &&\n row.edge !== undefined &&\n skipMigrationHashes.has(row.edge.migrationHash)\n ) {\n continue;\n }\n max = Math.max(max, row.laneIndex ?? 0);\n for (const lane of row.passThroughLanes ?? []) {\n max = Math.max(max, lane);\n }\n if (row.startLane !== undefined) {\n max = Math.max(max, row.startLane, row.endLane ?? row.startLane);\n }\n }\n return max;\n}\n\nfunction allocateSkipRollbackBackLanes(\n skipRollbacks: readonly ClassifiedEdge[],\n position: ReadonlyMap<string, number>,\n forwardMax: number,\n): Map<string, number> {\n const sorted = [...skipRollbacks].sort((a, b) => {\n const aTop = position.get(a.from) ?? 0;\n const bTop = position.get(b.from) ?? 0;\n if (aTop !== bTop) return aTop - bTop;\n return b.dirName.localeCompare(a.dirName);\n });\n\n const occupied: { readonly top: number; readonly bottom: number; readonly lane: number }[] = [];\n const lanes = new Map<string, number>();\n let nextLane = forwardMax + 1;\n\n for (const edge of sorted) {\n const span = rollbackSpan(edge, position);\n let lane = nextLane;\n while (occupied.some((entry) => entry.lane === lane && spansOverlap(entry, span))) {\n lane += 1;\n }\n occupied.push({ ...span, lane });\n lanes.set(edge.migrationHash, lane);\n nextLane = Math.max(nextLane, lane + 1);\n }\n\n return lanes;\n}\n\nfunction findNodeRowIndex(rows: readonly MigrationGraphGridRow[], contractHash: string): number {\n return rows.findIndex((row) => row.kind === 'node' && row.contractHash === contractHash);\n}\n\nfunction findEdgeRowIndex(rows: readonly MigrationGraphGridRow[], migrationHash: string): number {\n return rows.findIndex((row) => row.kind === 'edge' && row.edge?.migrationHash === migrationHash);\n}\n\n// A grid row with a mutable `cells` array. The routing pass clones the\n// immutable rows into this shape so it can paint arc cells in place without\n// stripping `readonly` with a cast.\ntype MutableGridRow = Omit<MigrationGraphGridRow, 'cells'> & { cells: StructuralCell[] };\n\nfunction ensureCellWidth(cells: StructuralCell[], width: number): void {\n while (cells.length < width) {\n cells.push({ kind: 'empty' });\n }\n}\n\nfunction cloneRow(row: MigrationGraphGridRow): MutableGridRow {\n return { ...row, cells: [...row.cells] };\n}\n\nfunction routeCrossesRow(\n route: SkipRollbackRoute,\n rowIndex: number,\n rows: readonly MigrationGraphGridRow[],\n): boolean {\n const sourceRow = findNodeRowIndex(rows, route.edge.from);\n const targetRow = findNodeRowIndex(rows, route.edge.to);\n if (sourceRow < 0 || targetRow < 0) return false;\n return rowIndex > sourceRow && rowIndex <= targetRow;\n}\n\nfunction applySkipRollbackRouting(\n rows: readonly MigrationGraphGridRow[],\n skipRollbacks: readonly ClassifiedEdge[],\n position: ReadonlyMap<string, number>,\n nodeColumn: ReadonlyMap<string, number>,\n edgeColumn: Map<string, number>,\n): MigrationGraphGridRow[] {\n if (skipRollbacks.length === 0) return [...rows];\n\n const skipHashes = new Set(skipRollbacks.map((edge) => edge.migrationHash));\n const forwardMax = forwardMaxLane(rows, skipHashes);\n const backLaneByHash = allocateSkipRollbackBackLanes(skipRollbacks, position, forwardMax);\n const routes: SkipRollbackRoute[] = skipRollbacks.map((edge) => ({\n edge,\n backLane: backLaneByHash.get(edge.migrationHash) ?? forwardMax + 1,\n }));\n\n const result = rows.map(cloneRow);\n\n for (const route of routes) {\n const { edge, backLane } = route;\n const nodeCol = nodeColumn.get(edge.from) ?? 0;\n const targetCol = nodeColumn.get(edge.to) ?? 0;\n const sourceRowIndex = findNodeRowIndex(result, edge.from);\n const targetRowIndex = findNodeRowIndex(result, edge.to);\n const edgeRowIndex = findEdgeRowIndex(result, edge.migrationHash);\n if (sourceRowIndex < 0 || targetRowIndex < 0 || edgeRowIndex < 0) continue;\n\n edgeColumn.set(edge.migrationHash, backLane);\n\n // Back-lanes of arcs that tee off this same source node. They share the\n // node's tee row, so each inner lane reads as a `┬` junction and only the\n // outermost gets the closing `╮`.\n const coSourcedLanes = routes\n .filter((other) => other.edge.from === edge.from)\n .map((other) => other.backLane);\n const maxCoSourcedLane = Math.max(...coSourcedLanes);\n\n const sourceRow = result[sourceRowIndex];\n if (sourceRow !== undefined) {\n const cells = sourceRow.cells;\n ensureCellWidth(cells, backLane + 1);\n const contractHash = sourceRow.contractHash ?? EMPTY_CONTRACT_HASH;\n cells[nodeCol] = { kind: 'node', contractHash, arcTee: true };\n for (let lane = nodeCol + 1; lane < backLane; lane += 1) {\n if (coSourcedLanes.includes(lane)) {\n cells[lane] = { kind: 'arc-branch-tee' };\n continue;\n }\n const existing = cells[lane];\n const occupied =\n existing !== undefined &&\n existing.kind !== 'empty' &&\n existing.kind !== 'horizontal-pass' &&\n existing.kind !== 'arc-land-bridge';\n const crossed =\n occupied ||\n routes.some(\n (other) =>\n other.edge.migrationHash !== edge.migrationHash &&\n other.backLane === lane &&\n routeCrossesRow(other, sourceRowIndex, result),\n );\n cells[lane] = crossed ? { kind: 'arc-crossing' } : { kind: 'horizontal-pass' };\n }\n cells[backLane] =\n backLane < maxCoSourcedLane ? { kind: 'arc-branch-tee' } : { kind: 'arc-branch-corner' };\n }\n\n const edgeRow = result[edgeRowIndex];\n if (edgeRow !== undefined) {\n // Mutate in place rather than rebuild from empty: a co-sourced arc's body\n // lane may already cross this row, and rebuilding would clobber it.\n const cells = edgeRow.cells;\n ensureCellWidth(cells, backLane + 1);\n cells[nodeCol] = { kind: 'vertical-pass' };\n cells[backLane] = {\n kind: 'edge-lane',\n migrationHash: edge.migrationHash,\n edgeKind: edge.kind,\n ownsLabel: true,\n adjacency: 'node-skipping-rollback',\n };\n result[edgeRowIndex] = { ...edgeRow, laneIndex: backLane, passThroughLanes: [nodeCol] };\n }\n\n // Fill the arc body vertically from just below the source tee down to the\n // row above the landing, skipping the rollback's own labelled edge row.\n // Starting below the source (rather than below the edge row) keeps a\n // co-sourced arc's lane connected across an earlier co-sourced edge row.\n for (let index = sourceRowIndex + 1; index < targetRowIndex; index += 1) {\n if (index === edgeRowIndex) continue;\n const row = result[index];\n if (row === undefined) continue;\n const cells = row.cells;\n ensureCellWidth(cells, backLane + 1);\n const existing = cells[backLane];\n if (\n existing?.kind !== 'arc-land-corner' &&\n existing?.kind !== 'arc-land-bridge' &&\n existing?.kind !== 'arc-branch-corner' &&\n existing?.kind !== 'arc-branch-tee' &&\n existing?.kind !== 'arc-crossing'\n ) {\n cells[backLane] = { kind: 'vertical-pass' };\n }\n }\n\n const targetRow = result[targetRowIndex];\n if (targetRow !== undefined) {\n const cells = targetRow.cells;\n ensureCellWidth(cells, backLane + 1);\n const contractHash = targetRow.contractHash ?? EMPTY_CONTRACT_HASH;\n cells[targetCol] = { kind: 'node', contractHash, arcLand: true };\n for (let lane = targetCol + 1; lane < backLane; lane += 1) {\n // A bridged lane that carries another arc OR a forward vertical still\n // active at this row must cross over it (`┼`) rather than overwrite it\n // with a bare bridge (`──`).\n const existing = cells[lane];\n const occupied =\n existing !== undefined &&\n existing.kind !== 'empty' &&\n existing.kind !== 'horizontal-pass' &&\n existing.kind !== 'arc-land-bridge';\n const crossed =\n occupied ||\n routes.some(\n (other) =>\n other.edge.migrationHash !== edge.migrationHash &&\n other.backLane === lane &&\n routeCrossesRow(other, targetRowIndex, result),\n );\n cells[lane] = crossed ? { kind: 'arc-crossing' } : { kind: 'arc-land-bridge' };\n }\n cells[backLane] = { kind: 'arc-land-corner' };\n for (const other of routes) {\n if (other.backLane <= backLane) continue;\n if (!routeCrossesRow(other, targetRowIndex, result)) continue;\n ensureCellWidth(cells, other.backLane + 1);\n const existing = cells[other.backLane];\n if (\n existing?.kind !== 'arc-land-corner' &&\n existing?.kind !== 'arc-land-bridge' &&\n existing?.kind !== 'node'\n ) {\n cells[other.backLane] = { kind: 'vertical-pass' };\n }\n }\n }\n }\n\n return result;\n}\n\nfunction collectNodeSkippingRollbacks(\n edges: readonly ClassifiedEdge[],\n position: ReadonlyMap<string, number>,\n): ClassifiedEdge[] {\n return edges.filter(\n (edge) =>\n edge.kind === 'rollback' &&\n classifyEdgeAdjacency(edge, position) === 'node-skipping-rollback',\n );\n}\n\n// ---------------------------------------------------------------------------\n// Lane allocation: one rule for all topologies\n// ---------------------------------------------------------------------------\n\ninterface DownwardGroup {\n readonly target: string;\n readonly edges: ClassifiedEdge[];\n}\n\nfunction layoutComponent(\n componentNodes: readonly string[],\n allEdges: readonly ClassifiedEdge[],\n): {\n rows: MigrationGraphGridRow[];\n nodeColumn: Map<string, number>;\n edgeColumn: Map<string, number>;\n} {\n const componentSet = new Set(componentNodes);\n const edges = allEdges.filter((e) => componentSet.has(e.from) && componentSet.has(e.to));\n\n const forwardChildren = new Map<string, ClassifiedEdge[]>();\n const producersByTo = new Map<string, ClassifiedEdge[]>();\n const rollbacksByFrom = new Map<string, ClassifiedEdge[]>();\n const selfByFrom = new Map<string, ClassifiedEdge[]>();\n for (const edge of edges) {\n if (edge.kind === 'self' || edge.from === edge.to) {\n const bucket = selfByFrom.get(edge.from);\n if (bucket) bucket.push(edge);\n else selfByFrom.set(edge.from, [edge]);\n continue;\n }\n if (edge.kind === 'forward') {\n const children = forwardChildren.get(edge.from);\n if (children) children.push(edge);\n else forwardChildren.set(edge.from, [edge]);\n const producers = producersByTo.get(edge.to);\n if (producers) producers.push(edge);\n else producersByTo.set(edge.to, [edge]);\n continue;\n }\n // rollback\n const bucket = rollbacksByFrom.get(edge.from);\n if (bucket) bucket.push(edge);\n else rollbacksByFrom.set(edge.from, [edge]);\n }\n\n const forwardInDegree = buildForwardInDegree(edges);\n const forwardOutDegree = buildForwardOutDegree(edges);\n const distinctSourceCountByTo = buildDistinctSourceCountByTo(edges);\n\n const order = computeVerticalOrder(componentNodes, forwardChildren, forwardInDegree);\n const position = new Map<string, number>();\n for (let index = 0; index < order.length; index++) {\n const node = order[index];\n if (node !== undefined) position.set(node, index);\n }\n\n const lanes: (string | null)[] = [];\n const rows: MigrationGraphGridRow[] = [];\n const nodeColumn = new Map<string, number>();\n const edgeColumn = new Map<string, number>();\n const producerLaneByHash = new Map<string, number>();\n let gridWidth = 1;\n\n function ensureGridWidth(minWidth: number): void {\n if (minWidth > gridWidth) gridWidth = minWidth;\n }\n\n function setLane(index: number, want: string | null): void {\n while (lanes.length <= index) lanes.push(null);\n lanes[index] = want;\n if (want !== null) ensureGridWidth(index + 1);\n }\n\n function activeLaneIndices(): number[] {\n const indices: number[] = [];\n for (let index = 0; index < lanes.length; index++) {\n if (lanes[index] !== null) indices.push(index);\n }\n return indices;\n }\n\n function passThroughExcept(lane: number): number[] {\n return activeLaneIndices().filter((index) => index !== lane);\n }\n\n function leftmostFreeLane(): number {\n for (let index = 0; index < lanes.length; index++) {\n if (lanes[index] === null) return index;\n }\n return lanes.length;\n }\n\n function lanesWanting(contract: string): number[] {\n const indices: number[] = [];\n for (let index = 0; index < lanes.length; index++) {\n if (lanes[index] === contract) indices.push(index);\n }\n return indices;\n }\n\n function emitMergeConnector(contractHash: string, laneIndices: readonly number[]): number {\n const startLane = Math.min(...laneIndices);\n const endLane = Math.max(...laneIndices);\n ensureGridWidth(endLane + 1);\n const activeLanes = new Set(activeLaneIndices());\n rows.push({\n kind: 'merge-connector',\n contractHash,\n startLane,\n endLane,\n branchCount: laneIndices.length,\n cells: buildMergeConnectorCells(startLane, endLane, activeLanes, gridWidth),\n });\n for (const index of laneIndices) {\n if (index !== startLane) setLane(index, null);\n }\n return startLane;\n }\n\n function emitBranchConnector(\n contractHash: string,\n startLane: number,\n endLane: number,\n branchCount: number,\n ): void {\n ensureGridWidth(endLane + 1);\n const activeLanes = new Set(activeLaneIndices());\n rows.push({\n kind: 'branch-connector',\n contractHash,\n startLane,\n endLane,\n branchCount,\n cells: buildBranchConnectorCells(startLane, endLane, activeLanes, gridWidth),\n });\n }\n\n function emitEdgeRow(edge: ClassifiedEdge, lane: number, convergenceProducer: boolean): void {\n const passThrough = passThroughExcept(lane);\n const adjacency = classifyEdgeAdjacency(edge, position);\n ensureGridWidth(Math.max(lane, ...passThrough, 0) + 1);\n const row: MigrationGraphGridRow = {\n kind: 'edge',\n edge,\n laneIndex: lane,\n passThroughLanes: passThrough,\n cells: buildEdgeCells(edge, lane, passThrough, adjacency, gridWidth),\n };\n rows.push(convergenceProducer ? { ...row, convergenceProducer: true } : row);\n edgeColumn.set(edge.migrationHash, lane);\n if (convergenceProducer) producerLaneByHash.set(edge.migrationHash, lane);\n }\n\n function emitNodeRow(contractHash: string, column: number): void {\n ensureGridWidth(column + 1);\n const passThrough = activeLaneIndices().filter((index) => index !== column);\n rows.push({\n kind: 'node',\n contractHash,\n cells: buildNodeCells(contractHash, column, passThrough, gridWidth),\n });\n nodeColumn.set(contractHash, column);\n }\n\n function producerGroups(node: string): DownwardGroup[] {\n const byTarget = new Map<string, DownwardGroup>();\n for (const producer of producersByTo.get(node) ?? []) {\n const group = byTarget.get(producer.from);\n if (group) group.edges.push(producer);\n else byTarget.set(producer.from, { target: producer.from, edges: [producer] });\n }\n const groups = [...byTarget.values()];\n // Lanes are ordered by where their target node lands vertically (soonest →\n // leftmost), which keeps lanes from crossing.\n groups.sort((a, b) => (position.get(a.target) ?? 0) - (position.get(b.target) ?? 0));\n for (const group of groups) {\n group.edges.sort((a, b) => b.dirName.localeCompare(a.dirName));\n }\n return groups;\n }\n\n function processNode(node: string): void {\n const wanting = lanesWanting(node);\n let column: number;\n if (wanting.length >= 2) {\n column = emitMergeConnector(node, wanting);\n } else if (wanting.length === 1) {\n column = wanting[0] ?? 0;\n } else {\n column = leftmostFreeLane();\n }\n\n // Self-edges sit immediately above their node, in its column.\n const selfEdges = [...(selfByFrom.get(node) ?? [])].sort((a, b) =>\n b.dirName.localeCompare(a.dirName),\n );\n for (const selfEdge of selfEdges) emitEdgeRow(selfEdge, column, false);\n\n emitNodeRow(node, column);\n\n const rollbacks = [...(rollbacksByFrom.get(node) ?? [])].sort((a, b) =>\n b.dirName.localeCompare(a.dirName),\n );\n const skipRollbacks: ClassifiedEdge[] = [];\n const adjacentRollbacks: ClassifiedEdge[] = [];\n for (const rollback of rollbacks) {\n if (classifyEdgeAdjacency(rollback, position) === 'node-skipping-rollback') {\n skipRollbacks.push(rollback);\n } else {\n adjacentRollbacks.push(rollback);\n }\n }\n for (const rollback of skipRollbacks) {\n emitEdgeRow(rollback, column, false);\n }\n\n const groups = producerGroups(node);\n const isConvergence = (distinctSourceCountByTo.get(node) ?? 0) >= 2;\n const laneForGroup: number[] = [];\n for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {\n const group = groups[groupIndex];\n if (group === undefined) continue;\n const lane = groupIndex === 0 ? column : leftmostFreeLane();\n laneForGroup[groupIndex] = lane;\n setLane(lane, group.target);\n }\n\n if (groups.length >= 2) {\n const endLane = Math.max(...laneForGroup);\n emitBranchConnector(node, column, endLane, groups.length);\n }\n\n for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {\n const group = groups[groupIndex];\n const lane = laneForGroup[groupIndex];\n if (group === undefined || lane === undefined) continue;\n for (const edge of group.edges) {\n emitEdgeRow(edge, lane, isConvergence);\n }\n }\n\n for (const rollback of adjacentRollbacks) {\n emitEdgeRow(rollback, column, false);\n }\n\n if (groups.length === 0) {\n // A root / leaf: its column lane terminates here.\n setLane(column, null);\n }\n }\n\n for (const node of order) processNode(node);\n\n const refined = refineAdjacency(\n rows,\n nodeColumn,\n position,\n forwardInDegree,\n forwardOutDegree,\n edges,\n producerLaneByHash,\n );\n const skipRollbacks = collectNodeSkippingRollbacks(edges, position);\n const routed = applySkipRollbackRouting(refined, skipRollbacks, position, nodeColumn, edgeColumn);\n\n return {\n rows: routed,\n nodeColumn,\n edgeColumn,\n };\n}\n\nexport function buildMigrationGraphLayout(\n rowModel: MigrationGraphRowModel,\n): MigrationGraphGridModel {\n if (rowModel.nodes.length === 0) {\n return { rows: [], nodeColumn: new Map(), edgeColumn: new Map() };\n }\n\n const components = splitComponents(rowModel.nodes);\n const allRows: MigrationGraphGridRow[] = [];\n const nodeColumn = new Map<string, number>();\n const edgeColumn = new Map<string, number>();\n\n for (let componentIndex = 0; componentIndex < components.length; componentIndex++) {\n if (componentIndex > 0) {\n allRows.push({ kind: 'component-separator', cells: [] });\n }\n\n const component = components[componentIndex];\n if (component === undefined || component.length === 0) continue;\n\n const result = layoutComponent(component, rowModel.edges);\n allRows.push(...result.rows);\n for (const [hash, column] of result.nodeColumn) nodeColumn.set(hash, column);\n for (const [hash, column] of result.edgeColumn) edgeColumn.set(hash, column);\n }\n\n return { rows: allRows, nodeColumn, edgeColumn };\n}\n","import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';\nimport type { MigrationGraph } from '@prisma-next/migration-tools/graph';\nimport {\n classifyMigrationGraphTopology,\n type MigrationEdgeKind,\n type MigrationListGraphTopology,\n} from './migration-list-graph-topology';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * A migration edge with its forward/rollback/self classification resolved.\n * `from` and `to` are contract hashes (EMPTY_CONTRACT_HASH for the baseline).\n */\nexport interface ClassifiedEdge {\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly dirName: string;\n readonly kind: MigrationEdgeKind;\n}\n\n/**\n * The pure-data output of the row-model stage.\n *\n * `nodes` is the vertical ordering of contract nodes: index 0 is the topmost\n * row (the tip), the last non-null entry is the bottommost root. `null`\n * sentinels separate disjoint components (the blank row in the rendered\n * output). Ordering within each component is deterministic: longest forward-\n * path rank from forward roots (tips at rank max, roots at 0), with lex-\n * ascending tie-break among same-rank siblings.\n *\n * `edges` carries every classified migration. `edgesByFrom` and `edgesByTo`\n * are pre-built lookup maps for the column allocator.\n */\nexport interface MigrationGraphRowModel {\n readonly nodes: readonly (string | null)[];\n readonly edges: readonly ClassifiedEdge[];\n readonly edgesByFrom: ReadonlyMap<string, readonly ClassifiedEdge[]>;\n readonly edgesByTo: ReadonlyMap<string, readonly ClassifiedEdge[]>;\n}\n\nexport interface BuildMigrationGraphRowsOptions {\n readonly contractHash?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Weak connectivity — identify disjoint components\n// ---------------------------------------------------------------------------\n\n/**\n * Return the weakly-connected components of `graph` as an array of node sets,\n * ordered so the component containing EMPTY_CONTRACT_HASH comes first (if\n * present), with remaining components sorted by their lex-smallest node hash.\n */\nfunction weaklyConnectedComponents(graph: MigrationGraph): readonly ReadonlySet<string>[] {\n const visited = new Set<string>();\n const adjacency = new Map<string, string[]>();\n\n function addAdjacent(a: string, b: string): void {\n const aList = adjacency.get(a);\n if (aList) aList.push(b);\n else adjacency.set(a, [b]);\n const bList = adjacency.get(b);\n if (bList) bList.push(a);\n else adjacency.set(b, [a]);\n }\n\n for (const edges of graph.forwardChain.values()) {\n for (const edge of edges) {\n if (edge.from !== edge.to) {\n addAdjacent(edge.from, edge.to);\n }\n }\n }\n\n // Ensure all nodes (including isolated self-loops) are reachable\n for (const node of graph.nodes) {\n if (!adjacency.has(node)) {\n adjacency.set(node, []);\n }\n }\n\n const components: Set<string>[] = [];\n\n function bfsComponent(start: string): Set<string> {\n const component = new Set<string>();\n const queue = [start];\n while (queue.length > 0) {\n const node = queue.shift();\n if (node === undefined || visited.has(node)) continue;\n visited.add(node);\n component.add(node);\n for (const neighbor of adjacency.get(node) ?? []) {\n if (!visited.has(neighbor)) {\n queue.push(neighbor);\n }\n }\n }\n return component;\n }\n\n // Deterministic: visit nodes in a fixed order (EMPTY first, then lex)\n const allNodes = [...graph.nodes].sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n\n for (const node of allNodes) {\n if (!visited.has(node)) {\n components.push(bfsComponent(node));\n }\n }\n\n // Order: EMPTY component first, others by lex-smallest node hash\n components.sort((a, b) => {\n const aHasEmpty = a.has(EMPTY_CONTRACT_HASH);\n const bHasEmpty = b.has(EMPTY_CONTRACT_HASH);\n if (aHasEmpty && !bHasEmpty) return -1;\n if (!aHasEmpty && bHasEmpty) return 1;\n const aMin = [...a].sort((x, y) => x.localeCompare(y))[0] ?? '';\n const bMin = [...b].sort((x, y) => x.localeCompare(y))[0] ?? '';\n return aMin.localeCompare(bMin);\n });\n\n return components;\n}\n\n// ---------------------------------------------------------------------------\n// Longest forward-path node ordering within a component\n// ---------------------------------------------------------------------------\n\nfunction forwardRootsInComponent(\n componentNodes: ReadonlySet<string>,\n topology: MigrationListGraphTopology,\n): readonly string[] {\n const roots: string[] = [];\n for (const node of componentNodes) {\n if ((topology.forwardInDegree.get(node) ?? 0) === 0) {\n roots.push(node);\n }\n }\n roots.sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n if (roots.length > 0) return roots;\n\n return [...componentNodes].sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n}\n\nfunction compareNodesTipsFirst(a: string, b: string, rank: ReadonlyMap<string, number>): number {\n const rankA = rank.get(a) ?? 0;\n const rankB = rank.get(b) ?? 0;\n if (rankA !== rankB) return rankB - rankA;\n if (a === EMPTY_CONTRACT_HASH) return 1;\n if (b === EMPTY_CONTRACT_HASH) return -1;\n return a.localeCompare(b);\n}\n\n/**\n * Layer nodes by longest forward-path rank from forward roots within the\n * component. Rank 0 is the root (bottom row); the maximum rank is the tip\n * (top row). Emits rank-descending with lex-ascending tie-break among siblings\n * at the same rank — stable across edge-insertion order and correct under\n * diamonds, cross-links, and rollbacks.\n */\nfunction layerNodesByLongestForwardPath(\n componentNodes: ReadonlySet<string>,\n topology: MigrationListGraphTopology,\n graph: MigrationGraph,\n): readonly string[] {\n const forwardOut = new Map<string, string[]>();\n\n for (const node of componentNodes) {\n forwardOut.set(node, []);\n }\n\n for (const edges of graph.forwardChain.values()) {\n for (const edge of edges) {\n if (!componentNodes.has(edge.from) || !componentNodes.has(edge.to)) continue;\n if (edge.from === edge.to) continue;\n if (topology.kindByMigrationHash.get(edge.migrationHash) !== 'forward') continue;\n const bucket = forwardOut.get(edge.from);\n if (bucket) bucket.push(edge.to);\n }\n }\n\n const roots = forwardRootsInComponent(componentNodes, topology);\n const rank = new Map<string, number>();\n for (const root of roots) {\n rank.set(root, 0);\n }\n\n const maxPasses = componentNodes.size;\n for (let pass = 0; pass < maxPasses; pass++) {\n let changed = false;\n for (const node of componentNodes) {\n const base = rank.get(node);\n if (base === undefined) continue;\n for (const to of forwardOut.get(node) ?? []) {\n const next = base + 1;\n const prev = rank.get(to) ?? -1;\n if (next > prev) {\n rank.set(to, next);\n changed = true;\n }\n }\n }\n if (!changed) break;\n }\n\n for (const node of componentNodes) {\n if (!rank.has(node)) {\n rank.set(node, 0);\n }\n }\n\n return [...componentNodes].sort((a, b) => compareNodesTipsFirst(a, b, rank));\n}\n\n// ---------------------------------------------------------------------------\n// Public builder\n// ---------------------------------------------------------------------------\n\n/**\n * Build the row model from a tolerant `MigrationGraph`.\n *\n * The row model is the first pure-data stage of the `migration graph` render\n * pipeline. It:\n * - classifies every edge as `forward`, `rollback`, or `self`;\n * - produces a deterministic vertical node ordering (tips at index 0, roots\n * at the end) within each weakly-connected component;\n * - separates disjoint components with `null` sentinels;\n * - optionally prepends a detached current contract as its own single-node\n * component when `contractHash` is not already in the graph.\n *\n * No columns, no lane allocation, no glyphs, no rendering.\n */\n/**\n * Resolve the detached current contract, if any: a real contract (not the\n * empty baseline) that no migration on disk produces, so it is absent from\n * the graph. Such a contract renders as a floating node rather than\n * decorating an existing one. Returns the hash when detached, else undefined.\n */\nfunction detachedContractHash(\n graph: MigrationGraph,\n contractHash: string | undefined,\n): string | undefined {\n return contractHash !== undefined &&\n contractHash !== EMPTY_CONTRACT_HASH &&\n !graph.nodes.has(contractHash)\n ? contractHash\n : undefined;\n}\n\nexport function buildMigrationGraphRows(\n graph: MigrationGraph,\n options: BuildMigrationGraphRowsOptions = {},\n): MigrationGraphRowModel {\n const emptyModel: MigrationGraphRowModel = {\n nodes: [],\n edges: [],\n edgesByFrom: new Map(),\n edgesByTo: new Map(),\n };\n\n if (graph.nodes.size === 0) {\n const detached = detachedContractHash(graph, options.contractHash);\n return detached !== undefined ? { ...emptyModel, nodes: [detached] } : emptyModel;\n }\n\n // 1. Classify all edges (shared classifier: DFS plus a peel pass that demotes\n // node-skipping rollbacks, so the forward subgraph is acyclic)\n const topology = classifyMigrationGraphTopology(graph);\n\n // 2. Build classified edge list\n const edges: ClassifiedEdge[] = [];\n const edgesByFrom = new Map<string, ClassifiedEdge[]>();\n const edgesByTo = new Map<string, ClassifiedEdge[]>();\n\n for (const edgeList of graph.forwardChain.values()) {\n for (const edge of edgeList) {\n const kind = topology.kindByMigrationHash.get(edge.migrationHash) ?? 'forward';\n const classified: ClassifiedEdge = {\n migrationHash: edge.migrationHash,\n from: edge.from,\n to: edge.to,\n dirName: edge.dirName,\n kind,\n };\n edges.push(classified);\n\n const fromBucket = edgesByFrom.get(edge.from);\n if (fromBucket) fromBucket.push(classified);\n else edgesByFrom.set(edge.from, [classified]);\n\n const toBucket = edgesByTo.get(edge.to);\n if (toBucket) toBucket.push(classified);\n else edgesByTo.set(edge.to, [classified]);\n }\n }\n\n // 3. Find weakly-connected components (ordered: EMPTY first, then lex)\n const components = weaklyConnectedComponents(graph);\n\n // 4. Layer nodes by longest forward path per component, separate with null\n const nodes: (string | null)[] = [];\n for (let i = 0; i < components.length; i++) {\n if (i > 0) nodes.push(null);\n const component = components[i];\n if (component === undefined) continue;\n const ordered = layerNodesByLongestForwardPath(component, topology, graph);\n for (const node of ordered) {\n nodes.push(node);\n }\n }\n\n const detached = detachedContractHash(graph, options.contractHash);\n if (detached !== undefined) {\n if (nodes.length > 0) {\n nodes.unshift(null);\n }\n nodes.unshift(detached);\n }\n\n return { nodes, edges, edgesByFrom, edgesByTo };\n}\n","import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';\nimport { bold } from 'colorette';\nimport stringWidth from 'string-width';\nimport type { GlyphMode } from '../glyph-mode';\nimport type {\n MigrationGraphGridModel,\n MigrationGraphGridRow,\n StructuralCell,\n} from './migration-graph-layout';\nimport type { ClassifiedEdge } from './migration-graph-rows';\nimport {\n MIGRATION_LIST_HASH_WIDTH,\n migrationListEmptySource,\n migrationListForwardArrow,\n} from './migration-list-data-column';\nimport type { MigrationEdgeKind } from './migration-list-graph-topology';\nimport type { MigrationListStyler } from './migration-list-render';\nimport { CONTRACT_MARKER_NAME, createAnsiMigrationListStyler } from './migration-list-styler';\n\nconst LABEL_GAP = 2;\n\n/**\n * The live-database overlay marker. Just another ref as far as styling goes —\n * the only emphasized markers are the active ref and the `contract`\n * desired-state marker (see {@link CONTRACT_MARKER_NAME}).\n */\nconst DB_MARKER_NAME = 'db';\n\nexport interface RenderMigrationGraphTreeOptions {\n readonly refsByHash?: ReadonlyMap<string, readonly string[]>;\n readonly dbHash?: string;\n readonly contractHash?: string;\n readonly activeRefName?: string;\n readonly hashLength?: number;\n readonly colorize: boolean;\n readonly glyphMode?: GlyphMode;\n}\n\ninterface MigrationGraphTreeGlyphPalette {\n readonly node: string;\n readonly arcLand: string;\n readonly arcTee: string;\n readonly verticalPass: string;\n readonly branchTee: string;\n readonly mergeTee: string;\n readonly branchCorner: string;\n readonly mergeCorner: string;\n readonly arcBranchCorner: string;\n readonly arcBranchTee: string;\n readonly arcLandCorner: string;\n readonly arcCrossing: string;\n readonly arcLandBridge: string;\n readonly horizontalPass: string;\n readonly connectorBranchTee: string;\n readonly connectorBranchTeeCo: string;\n readonly connectorMergeTeeCo: string;\n readonly edgeArrow: Readonly<Record<MigrationEdgeKind, string>>;\n readonly forwardArrow: string;\n readonly emptySource: string;\n}\n\nconst UNICODE_PALETTE: MigrationGraphTreeGlyphPalette = {\n node: '○ ',\n arcLand: '○◂',\n arcTee: '○─',\n verticalPass: '│ ',\n branchTee: '├─',\n mergeTee: '├─',\n branchCorner: '╮ ',\n mergeCorner: '╯ ',\n arcBranchCorner: '╮ ',\n arcBranchTee: '┬─',\n arcLandCorner: '╯ ',\n arcCrossing: '┼─',\n arcLandBridge: '──',\n horizontalPass: '──',\n connectorBranchTee: '├─',\n connectorBranchTeeCo: '┬─',\n connectorMergeTeeCo: '┴─',\n edgeArrow: { forward: '↑', rollback: '↓', self: '⟲' },\n forwardArrow: migrationListForwardArrow('unicode'),\n emptySource: migrationListEmptySource('unicode'),\n};\n\nconst ASCII_PALETTE: MigrationGraphTreeGlyphPalette = {\n node: '* ',\n arcLand: '*<',\n arcTee: '*-',\n verticalPass: '| ',\n branchTee: '+-',\n mergeTee: '+-',\n branchCorner: '\\\\ ',\n mergeCorner: '/ ',\n arcBranchCorner: '\\\\ ',\n arcBranchTee: '+-',\n arcLandCorner: '/ ',\n arcCrossing: '+-',\n arcLandBridge: '--',\n horizontalPass: '--',\n connectorBranchTee: '+-',\n connectorBranchTeeCo: '+-',\n connectorMergeTeeCo: '+-',\n edgeArrow: { forward: '^', rollback: 'v', self: '@' },\n forwardArrow: migrationListForwardArrow('ascii'),\n emptySource: migrationListEmptySource('ascii'),\n};\n\nfunction paletteFor(mode: GlyphMode): MigrationGraphTreeGlyphPalette {\n return mode === 'ascii' ? ASCII_PALETTE : UNICODE_PALETTE;\n}\n\nfunction arrowForEdgeKind(\n kind: MigrationEdgeKind,\n palette: MigrationGraphTreeGlyphPalette,\n): string {\n return palette.edgeArrow[kind];\n}\n\n/**\n * A node-marker glyph pair (`○◂`, `○─`, `*<`, `*-`) is the contract node\n * marker (`○` / `*`) followed by an arc connector (`◂` / `─` / `<` / `-`).\n * The marker is the signal and stays bright (`style.kind`); the connector is\n * gutter and stays dim (`style.lane`) — consistent with the plain node marker,\n * which is never dimmed.\n */\nfunction renderNodeMarkerPair(pair: string, style: MigrationListStyler): string {\n return style.kind(pair.slice(0, 1)) + style.lane(pair.slice(1));\n}\n\nfunction renderCellPair(\n cell: StructuralCell,\n style: MigrationListStyler,\n palette: MigrationGraphTreeGlyphPalette,\n): string {\n switch (cell.kind) {\n case 'node':\n if (cell.arcLand === true) return renderNodeMarkerPair(palette.arcLand, style);\n if (cell.arcTee === true) return renderNodeMarkerPair(palette.arcTee, style);\n return style.kind(palette.node);\n case 'vertical-pass':\n return style.lane(palette.verticalPass);\n case 'edge-lane':\n // The lane stays dim; the direction arrow (↑ / ↓ / ⟲) is the signal and\n // stays bright, like the contract-node marker.\n return cell.ownsLabel\n ? style.lane(palette.verticalPass.trimEnd()) +\n style.kind(arrowForEdgeKind(cell.edgeKind, palette))\n : style.lane(palette.verticalPass);\n case 'branch-tee':\n return style.lane(palette.branchTee);\n case 'merge-tee':\n return style.lane(palette.mergeTee);\n case 'branch-corner':\n return style.lane(palette.branchCorner);\n case 'merge-corner':\n return style.lane(palette.mergeCorner);\n case 'arc-branch-corner':\n return style.lane(palette.arcBranchCorner);\n case 'arc-branch-tee':\n return style.lane(palette.arcBranchTee);\n case 'arc-land-corner':\n return style.lane(palette.arcLandCorner);\n case 'arc-crossing':\n return style.lane(palette.arcCrossing);\n case 'arc-land-bridge':\n return style.lane(palette.arcLandBridge);\n case 'horizontal-pass':\n return style.lane(palette.horizontalPass);\n case 'empty':\n return ' ';\n }\n}\n\nfunction renderConnectorRow(\n row: MigrationGraphGridRow,\n gridWidth: number,\n style: MigrationListStyler,\n palette: MigrationGraphTreeGlyphPalette,\n): string {\n const isMerge = row.kind === 'merge-connector';\n if (row.cells.length > 0) {\n let seenTee = false;\n let out = '';\n for (const cell of row.cells) {\n switch (cell.kind) {\n case 'branch-tee':\n out += style.lane(seenTee ? palette.connectorBranchTeeCo : palette.connectorBranchTee);\n seenTee = true;\n break;\n case 'merge-tee':\n out += style.lane(seenTee ? palette.connectorMergeTeeCo : palette.connectorBranchTee);\n seenTee = true;\n break;\n case 'branch-corner':\n out += style.lane(palette.branchCorner);\n break;\n case 'merge-corner':\n out += style.lane(palette.mergeCorner);\n break;\n case 'vertical-pass':\n out += style.lane(palette.verticalPass);\n break;\n case 'horizontal-pass':\n out += style.lane(palette.horizontalPass);\n break;\n default:\n out += ' ';\n }\n }\n // The cells array is sized to the grid width at emit time; a back-arc lane\n // allocated by a later row can push the grid wider afterwards, so pad any\n // trailing columns rather than dropping the lanes that pass through here.\n for (let column = row.cells.length; column < gridWidth; column++) {\n out += ' ';\n }\n return out;\n }\n\n const start = row.startLane ?? 0;\n const end = row.endLane ?? start;\n let out = '';\n for (let column = 0; column < gridWidth; column++) {\n if (column < start || column > end) out += ' ';\n else if (column === start) out += style.lane(palette.connectorBranchTee);\n else if (column === end)\n out += style.lane(isMerge ? palette.mergeCorner : palette.branchCorner);\n else out += style.lane(isMerge ? palette.connectorMergeTeeCo : palette.connectorBranchTeeCo);\n }\n return out;\n}\n\nfunction abbreviateHash(hash: string, hashLength: number, emptySource: string): string {\n if (hash === EMPTY_CONTRACT_HASH) {\n return emptySource;\n }\n const stripped = hash.startsWith('sha256:') ? hash.slice(7) : hash;\n return stripped.slice(0, hashLength);\n}\n\nconst MIN_HASH_DATA_COLUMN = 25;\n\nfunction overlayNamesForContract(\n contractHash: string,\n opts: RenderMigrationGraphTreeOptions,\n): readonly string[] {\n const names: string[] = [];\n const userRefs = opts.refsByHash?.get(contractHash);\n if (userRefs) {\n names.push(...[...userRefs].sort((a, b) => a.localeCompare(b)));\n }\n if (opts.dbHash === contractHash) {\n names.push(DB_MARKER_NAME);\n }\n if (opts.contractHash === contractHash && contractHash !== EMPTY_CONTRACT_HASH) {\n names.push(CONTRACT_MARKER_NAME);\n }\n return names;\n}\n\nfunction createTreeStyler(opts: RenderMigrationGraphTreeOptions): MigrationListStyler {\n const base = createAnsiMigrationListStyler({ useColor: opts.colorize });\n const activeRefName = opts.activeRefName;\n if (!opts.colorize || activeRefName === undefined) {\n return base;\n }\n return {\n ...base,\n refs: (names) => {\n const styledNames = names.map((name) => (name === activeRefName ? bold(name) : name));\n return base.refs(styledNames);\n },\n };\n}\n\nfunction formatEdgeHashColumn(\n edge: ClassifiedEdge,\n style: MigrationListStyler,\n hashLength: number,\n palette: MigrationGraphTreeGlyphPalette,\n): string {\n if (edge.kind === 'self') {\n const hash = abbreviateHash(edge.from, hashLength, palette.emptySource);\n return `${style.sourceHash(hash)} ${style.glyph(palette.forwardArrow)} ${style.destHash(hash)}`;\n }\n const source =\n edge.from === EMPTY_CONTRACT_HASH\n ? style.glyph(palette.emptySource) +\n ' '.repeat(Math.max(0, hashLength - palette.emptySource.length))\n : style.sourceHash(abbreviateHash(edge.from, hashLength, palette.emptySource));\n const arrow = style.glyph(palette.forwardArrow);\n const dest = style.destHash(abbreviateHash(edge.to, hashLength, palette.emptySource));\n return `${source} ${arrow} ${dest}`;\n}\n\nfunction padVisible(text: string, targetWidth: number): string {\n const padding = Math.max(0, targetWidth - stringWidth(text));\n return text + ' '.repeat(padding);\n}\n\nfunction gridWidthForModel(rows: readonly MigrationGraphGridRow[]): number {\n return rows.reduce(\n (max, row) =>\n row.kind === 'node' || row.kind === 'edge' ? Math.max(max, row.cells.length) : max,\n 1,\n );\n}\n\nfunction maxDirNameLength(edges: readonly ClassifiedEdge[]): number {\n if (edges.length === 0) return 0;\n return Math.max(...edges.map((edge) => edge.dirName.length));\n}\n\nfunction rowDirNameWidth(labelColumn: number, maxDirNameLen: number, dirNameGap: number): number {\n return Math.max(maxDirNameLen + dirNameGap, MIN_HASH_DATA_COLUMN - labelColumn);\n}\n\nfunction gridUsesSkipRollbackArcs(rows: readonly MigrationGraphGridRow[]): boolean {\n return rows.some((row) =>\n row.cells.some(\n (cell) => cell.kind === 'edge-lane' && cell.adjacency === 'node-skipping-rollback',\n ),\n );\n}\n\nfunction edgeLabelColumn(row: MigrationGraphGridRow, wideLabelColumn: number | undefined): number {\n if (wideLabelColumn !== undefined) {\n return wideLabelColumn;\n }\n const laneIndex = row.laneIndex ?? 0;\n if (row.edge?.from === EMPTY_CONTRACT_HASH && laneIndex === 0) {\n return (laneIndex + 1) * 2 + LABEL_GAP;\n }\n const usesFullRowGutter = row.cells.some(\n (cell, index) => index > laneIndex && cell.kind === 'vertical-pass',\n );\n return usesFullRowGutter ? row.cells.length * 2 + LABEL_GAP : (laneIndex + 1) * 2 + LABEL_GAP;\n}\n\nfunction nodeHasArcDecoration(row: MigrationGraphGridRow): boolean {\n return row.cells.some(\n (cell) => cell.kind === 'node' && (cell.arcTee === true || cell.arcLand === true),\n );\n}\n\nexport function renderMigrationGraphTree(\n model: MigrationGraphGridModel,\n opts: RenderMigrationGraphTreeOptions,\n): string {\n const glyphMode = opts.glyphMode ?? 'unicode';\n const palette = paletteFor(glyphMode);\n const style = createTreeStyler(opts);\n const hashLength = opts.hashLength ?? MIGRATION_LIST_HASH_WIDTH;\n const gridWidth = gridWidthForModel(model.rows);\n const wideLabelColumn = gridUsesSkipRollbackArcs(model.rows) ? gridWidth * 2 + 4 : undefined;\n const dirNameGap = wideLabelColumn !== undefined ? 3 : LABEL_GAP;\n const allEdges = model.rows\n .filter(\n (row): row is MigrationGraphGridRow & { edge: ClassifiedEdge } =>\n row.kind === 'edge' && row.edge !== undefined,\n )\n .map((row) => row.edge);\n const maxDirNameLen = maxDirNameLength(allEdges);\n\n const lines: string[] = [];\n\n for (let rowIndex = 0; rowIndex < model.rows.length; rowIndex++) {\n const row = model.rows[rowIndex];\n if (row === undefined) continue;\n\n if (row.kind === 'component-separator') {\n lines.push('');\n continue;\n }\n\n if (row.kind === 'branch-connector' || row.kind === 'merge-connector') {\n lines.push(renderConnectorRow(row, gridWidth, style, palette).replace(/\\s+$/, ''));\n continue;\n }\n\n let gutter = row.cells.map((cell) => renderCellPair(cell, style, palette)).join('');\n const prevRow = model.rows[rowIndex - 1];\n let laneSpan = row.cells.length;\n if (row.kind === 'node') {\n const contractHash = row.contractHash ?? EMPTY_CONTRACT_HASH;\n if (prevRow?.kind === 'merge-connector' || contractHash === EMPTY_CONTRACT_HASH) {\n laneSpan = 1;\n } else {\n laneSpan = row.cells.length;\n }\n }\n const labelColumn =\n row.kind === 'edge'\n ? edgeLabelColumn(row, wideLabelColumn)\n : wideLabelColumn !== undefined &&\n (nodeHasArcDecoration(row) || row.contractHash !== undefined)\n ? wideLabelColumn\n : laneSpan * 2 + LABEL_GAP;\n if (\n row.kind === 'edge' &&\n row.edge?.from === EMPTY_CONTRACT_HASH &&\n (row.laneIndex ?? 0) === 0\n ) {\n gutter = row.cells\n .slice(0, 1)\n .map((cell) => renderCellPair(cell, style, palette))\n .join('');\n } else if (row.kind === 'node' && laneSpan < row.cells.length && !nodeHasArcDecoration(row)) {\n gutter = row.cells\n .slice(0, laneSpan)\n .map((cell) => renderCellPair(cell, style, palette))\n .join('');\n } else if (gutter.length < laneSpan * 2) {\n gutter = gutter.padEnd(laneSpan * 2, ' ');\n }\n const dirNameWidth = rowDirNameWidth(labelColumn, maxDirNameLen, dirNameGap);\n const dataColumn = labelColumn + dirNameWidth;\n const gutterPad = padVisible(gutter, labelColumn);\n\n if (row.kind === 'node') {\n const contractHash = row.contractHash ?? EMPTY_CONTRACT_HASH;\n if (contractHash === EMPTY_CONTRACT_HASH) {\n const trailingLanes = row.cells\n .slice(1)\n .map((cell) => renderCellPair(cell, style, palette))\n .join('');\n const emptyGutter = palette.emptySource.padEnd(2, ' ') + trailingLanes;\n const overlayNames = overlayNamesForContract(contractHash, opts);\n if (overlayNames.length === 0) {\n lines.push(emptyGutter.replace(/\\s+$/, ''));\n continue;\n }\n const overlay = style.refs(overlayNames);\n lines.push(`${padVisible(emptyGutter, dataColumn)}${overlay}`.replace(/\\s+$/, ''));\n continue;\n }\n const hashText = style.sourceHash(\n abbreviateHash(contractHash, hashLength, palette.emptySource),\n );\n const overlayNames = overlayNamesForContract(contractHash, opts);\n const overlayPad =\n overlayNames.length > 0\n ? ' '.repeat(Math.max(0, dataColumn - labelColumn - stringWidth(hashText)))\n : '';\n const overlay = overlayNames.length > 0 ? style.refs(overlayNames) : '';\n lines.push(`${gutterPad}${hashText}${overlayPad}${overlay}`.replace(/\\s+$/, ''));\n continue;\n }\n\n const edge = row.edge;\n if (edge === undefined) continue;\n\n const dirNamePadding = ' '.repeat(Math.max(0, dirNameWidth - edge.dirName.length));\n const dirName = `${style.dirName(edge.dirName)}${dirNamePadding}`;\n const hashColumn = formatEdgeHashColumn(edge, style, hashLength, palette);\n lines.push(`${gutterPad}${dirName}${hashColumn}`.replace(/\\s+$/, ''));\n }\n\n return lines.join('\\n');\n}\n","import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';\nimport type { MigrationGraph } from '@prisma-next/migration-tools/graph';\nimport { ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport type { CliStructuredError } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n} from '../utils/command-helpers';\nimport { buildReadAggregate } from '../utils/contract-space-aggregate-loader';\nimport { migrationGraphToRenderInput } from '../utils/formatters/graph-migration-mapper';\nimport { graphRenderer } from '../utils/formatters/graph-render';\nimport { buildMigrationGraphLayout } from '../utils/formatters/migration-graph-layout';\nimport { buildMigrationGraphRows } from '../utils/formatters/migration-graph-rows';\nimport { renderMigrationGraphTree } from '../utils/formatters/migration-graph-tree-render';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport type { StatusRef } from '../utils/migration-types';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationGraphOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly dot?: boolean;\n readonly tree?: boolean;\n readonly ascii?: boolean;\n}\n\nexport interface MigrationGraphResult {\n readonly ok: true;\n readonly graph: MigrationGraph;\n readonly contractHash: string | null;\n readonly refs: readonly StatusRef[];\n readonly summary: string;\n}\n\nexport async function executeMigrationGraphCommand(\n options: MigrationGraphOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationGraphResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, appMigrationsRelative, migrationsDir } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n if (!flags.json && !flags.quiet) {\n const header = formatStyledHeader({\n command: 'migration graph',\n description: 'Show the migration graph topology',\n details: [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ],\n flags,\n });\n ui.stderr(header);\n }\n\n const loaded = await buildReadAggregate(config, { migrationsDir });\n if (!loaded.ok) {\n return loaded;\n }\n\n const { aggregate, contractHash } = loaded.value;\n const graph = aggregate.app.graph();\n const refs: readonly StatusRef[] = Object.entries(aggregate.app.refs).map(([name, entry]) => ({\n name,\n hash: entry.hash,\n active: false,\n }));\n\n return ok({\n ok: true,\n graph,\n contractHash,\n refs,\n summary: `${graph.nodes.size} node(s), ${graph.migrationByHash.size} edge(s)`,\n });\n}\n\nexport function createMigrationGraphCommand(): Command {\n const command = new Command('graph');\n setCommandDescriptions(\n command,\n 'Show the migration graph topology',\n 'Renders the migration graph topology. Offline — does not consult\\n' +\n 'the database. Use --tree for the condensed annotated tree\\n' +\n '(--ascii swaps box-drawing for pipe-friendly ASCII glyphs),\\n' +\n '--json for machine-readable output, or --dot for Graphviz DOT\\n' +\n 'format.',\n );\n setCommandExamples(command, [\n 'prisma-next migration graph',\n 'prisma-next migration graph --json',\n 'prisma-next migration graph --dot',\n 'prisma-next migration graph --tree',\n 'prisma-next migration graph --tree --ascii',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration log', oneLiner: 'Show executed migration history' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration show', oneLiner: 'Display migration package contents' },\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--dot', 'Output in Graphviz DOT format')\n .option('--tree', 'Experimental condensed annotated tree renderer')\n .option('--ascii', 'Use ASCII glyphs for --tree (pipe-friendly)')\n .action(async (options: MigrationGraphOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n const result = await executeMigrationGraphCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (graphResult) => {\n // Explicit format flags win over the auto-JSON default. `flags.json`\n // is auto-enabled when stdout is non-TTY (per CLI Style Guide §\n // JSON Semantics); without this ordering, `migration graph --dot |\n // dot -Tsvg` pipes JSON into the GraphViz binary, which then\n // errors. `--dot` is the more specific instruction; honour it.\n if (options.dot) {\n const lines = ['digraph migrations {'];\n for (const edge of graphResult.graph.migrationByHash.values()) {\n const from = edge.from.slice(0, 12);\n const to = edge.to.slice(0, 12);\n lines.push(` \"${from}\" -> \"${to}\" [label=\"${edge.dirName}\"];`);\n }\n lines.push('}');\n ui.output(lines.join('\\n'));\n } else if (flags.json) {\n const nodes = [...graphResult.graph.nodes];\n const edges = [...graphResult.graph.migrationByHash.values()].map((e) => ({\n dirName: e.dirName,\n from: e.from,\n to: e.to,\n migrationHash: e.migrationHash,\n }));\n ui.output(\n JSON.stringify({ ok: true, nodes, edges, summary: graphResult.summary }, null, 2),\n );\n } else if (!flags.quiet) {\n if (options.tree) {\n const refsByHash = new Map<string, string[]>();\n for (const ref of graphResult.refs) {\n const existing = refsByHash.get(ref.hash);\n refsByHash.set(ref.hash, existing ? [...existing, ref.name] : [ref.name]);\n }\n const rowModel = buildMigrationGraphRows(graphResult.graph, {\n ...(graphResult.contractHash !== null\n ? { contractHash: graphResult.contractHash }\n : {}),\n });\n const layout = buildMigrationGraphLayout(rowModel);\n const activeRef = graphResult.refs.find((ref) => ref.active);\n const treeOutput = renderMigrationGraphTree(layout, {\n refsByHash,\n ...(graphResult.contractHash !== null\n ? { contractHash: graphResult.contractHash }\n : {}),\n ...(activeRef !== undefined ? { activeRefName: activeRef.name } : {}),\n colorize: flags.color !== false,\n glyphMode: ui.resolveGlyphMode(options.ascii === true),\n });\n // Emit the rendered tree to stdout (same stream as flat `migration list`),\n // not through clack's `log.message` rail: the graph is the command's\n // result (and its own box-drawing is the only vertical structure it\n // should carry), not a status line that needs the prompt gutter.\n ui.output(treeOutput);\n ui.output(`\\n${graphResult.summary}`);\n } else {\n const renderInput = migrationGraphToRenderInput({\n graph: graphResult.graph,\n mode: 'offline',\n markerHash: undefined,\n contractHash: graphResult.contractHash ?? EMPTY_CONTRACT_HASH,\n refs: graphResult.refs,\n activeRefHash: undefined,\n activeRefName: undefined,\n edgeStatuses: [],\n });\n const graphOutput = graphRenderer.render(renderInput.graph, {\n ...renderInput.options,\n colorize: flags.color !== false,\n });\n ui.log(graphOutput);\n ui.log(`\\n${graphResult.summary}`);\n }\n }\n });\n process.exit(exitCode);\n });\n return command;\n}\n"],"mappings":"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"}