prisma-next 0.8.0-dev.9 → 0.9.0-dev.1
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.
- package/dist/cli.mjs +5 -5
- package/dist/{client-XkUw4xD0.mjs → client-Brv4qlfB.mjs} +13 -19
- package/dist/client-Brv4qlfB.mjs.map +1 -0
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +2 -2
- package/dist/commands/db-schema.mjs +1 -1
- package/dist/commands/db-sign.mjs +1 -1
- package/dist/commands/db-update.mjs +2 -2
- package/dist/commands/db-verify.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +12 -4
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-log.mjs +1 -1
- package/dist/commands/migration-new.mjs +9 -9
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +7 -7
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +2 -2
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +5 -5
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/{contract-emit-GpxW5RLe.mjs → contract-emit-C3STUIBg.mjs} +2 -2
- package/dist/{contract-emit-GpxW5RLe.mjs.map → contract-emit-C3STUIBg.mjs.map} +1 -1
- package/dist/{contract-emit-CgoFk9AU.mjs → contract-emit-iynA3BCA.mjs} +2 -2
- package/dist/{contract-emit-CgoFk9AU.mjs.map → contract-emit-iynA3BCA.mjs.map} +1 -1
- package/dist/{contract-infer-D8edZOCi.mjs → contract-infer-Cnj8G1E2.mjs} +2 -2
- package/dist/{contract-infer-D8edZOCi.mjs.map → contract-infer-Cnj8G1E2.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-D68YpuPR.mjs → contract-space-aggregate-loader-pAc8CDfY.mjs} +2 -2
- package/dist/{contract-space-aggregate-loader-D68YpuPR.mjs.map → contract-space-aggregate-loader-pAc8CDfY.mjs.map} +1 -1
- package/dist/{db-verify-DtRB9iHJ.mjs → db-verify-D7cyH_zz.mjs} +7 -4
- package/dist/db-verify-D7cyH_zz.mjs.map +1 -0
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/index.mjs.map +1 -1
- package/dist/{init-BU2G31T8.mjs → init-Bqg5JWg7.mjs} +3 -3
- package/dist/{init-BU2G31T8.mjs.map → init-Bqg5JWg7.mjs.map} +1 -1
- package/dist/{inspect-live-schema-CPPqCips.mjs → inspect-live-schema-CWLK_lgs.mjs} +2 -2
- package/dist/{inspect-live-schema-CPPqCips.mjs.map → inspect-live-schema-CWLK_lgs.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-B_ezTTwX.mjs → migration-command-scaffold-CmXXC1UZ.mjs} +2 -2
- package/dist/{migration-command-scaffold-B_ezTTwX.mjs.map → migration-command-scaffold-CmXXC1UZ.mjs.map} +1 -1
- package/dist/{migration-plan-DWB-NTxH.mjs → migration-plan-CHyUlBV0.mjs} +34 -27
- package/dist/migration-plan-CHyUlBV0.mjs.map +1 -0
- package/dist/{types-BS_wpjAY.d.mts → types-0aS865QN.d.mts} +13 -7
- package/dist/types-0aS865QN.d.mts.map +1 -0
- package/package.json +10 -10
- package/dist/client-XkUw4xD0.mjs.map +0 -1
- package/dist/db-verify-DtRB9iHJ.mjs.map +0 -1
- package/dist/migration-plan-DWB-NTxH.mjs.map +0 -1
- package/dist/types-BS_wpjAY.d.mts.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-XkUw4xD0.mjs","names":["SPAN_IDS","emitContractArtifacts"],"sources":["../src/control-api/errors.ts","../src/control-api/operations/apply-aggregate.ts","../src/control-api/operations/migration-helpers.ts","../src/control-api/operations/db-apply-aggregate.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 MultiSpaceCapableRunner,\n MultiSpaceRunnerPerSpaceOptions,\n TargetMigrationsCapability,\n} from '@prisma-next/framework-components/control';\nimport { hasMultiSpaceRunner } from '@prisma-next/framework-components/control';\nimport type {\n AggregatePerSpacePlan,\n ContractSpaceAggregate,\n} from '@prisma-next/migration-tools/aggregate';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { errorRunnerFailed } from '../../utils/cli-errors';\nimport type { AggregatePerSpaceExecutionEntry, OnControlProgress } 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 AggregateApplyAction = 'dbInit' | 'dbUpdate' | 'migrationApply';\n\n/**\n * Failure variant emitted by {@link applyAggregate} when the multi-space\n * runner 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 AggregateApplyRunnerFailure {\n readonly summary: string;\n readonly why?: string;\n readonly meta: Record<string, unknown>;\n}\n\nexport interface ApplyAggregateInputs<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 planAggregate} 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, AggregatePerSpacePlan>;\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 `MultiSpaceRunnerFailure.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: AggregateApplyAction;\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Resolved per-space plan in canonical schedule order. Surfaced from\n * {@link applyAggregate} 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: AggregatePerSpacePlan;\n}\n\nexport interface ApplyAggregateValue {\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 AggregatePerSpaceExecutionEntry[];\n}\n\nexport type ApplyAggregateResult = Result<ApplyAggregateValue, AggregateApplyRunnerFailure>;\n\n/**\n * Runner-driving tail shared by every aggregate 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 multi-space 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 `executeAcrossSpaces` 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 applyAggregate<TFamilyId extends string, TTargetId extends string>(\n inputs: ApplyAggregateInputs<TFamilyId, TTargetId>,\n): Promise<ApplyAggregateResult> {\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 if (!hasMultiSpaceRunner(runner)) {\n throw errorRunnerFailed(\n `Runner for target \"${aggregate.targetId}\" does not implement \\`executeAcrossSpaces\\``,\n {\n why: `${labelForAction(action)} requires multi-space-capable runners (today: every SQL family runner).`,\n },\n );\n }\n\n onProgress?.({\n action,\n kind: 'spanStart',\n spanId: APPLY_SPAN_ID,\n label: progressLabelForAction(action),\n });\n\n const perSpaceOptions: MultiSpaceRunnerPerSpaceOptions<TFamilyId, TTargetId>[] =\n 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 // SQL family runners read `strictVerification` via structural\n // typing.\n strictVerification: false,\n })) as MultiSpaceRunnerPerSpaceOptions<TFamilyId, TTargetId>[];\n\n const runnerResult = await (\n runner as MultiSpaceCapableRunner<TFamilyId, TTargetId>\n ).executeAcrossSpaces({ 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 },\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 * `AggregatePerSpaceExecutionEntry[]` 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 applyAggregate} 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 AggregatePerSpaceExecutionEntry[] {\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: AggregatePerSpaceExecutionEntry = {\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, AggregatePerSpacePlan>,\n): readonly OrderedResolution[] {\n return applyOrder.map((spaceId) => {\n const entry = perSpace.get(spaceId);\n if (!entry) {\n throw new Error(`Aggregate 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. `applyAggregate` 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: AggregateApplyAction): 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\nfunction labelForAction(action: AggregateApplyAction): string {\n switch (action) {\n case 'dbInit':\n return 'db init';\n case 'dbUpdate':\n return 'db update';\n case 'migrationApply':\n return 'migrate';\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 AggregatePlannerError,\n type ContractSpaceAggregate,\n planAggregate,\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 AggregatePerSpaceExecutionEntry,\n DbInitFailure,\n DbInitResult,\n DbInitSuccess,\n DbUpdateFailure,\n DbUpdateResult,\n DbUpdateSuccess,\n OnControlProgress,\n} from '../types';\nimport { applyAggregate, buildPerSpaceBreakdown, collectOrdered } from './apply-aggregate';\nimport { stripOperations } from './migration-helpers';\n\n/**\n * Span IDs emitted via `onProgress` during the aggregate 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 applyAggregate} 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` aggregate 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 ExecuteAggregateApplyOptions<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 planAggregate} 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 `executeAcrossSpaces` — one outer\n * transaction across every space; failure on any space rolls back\n * every space's writes.\n */\nexport async function executeAggregateApply<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteAggregateApplyOptions<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 validateContract: (json) => familyInstance.validateContract(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 planAggregate<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 `applyAggregate` 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 planAggregate here; graph-walk\n // only for migrate). Each caller produces perSpacePlans differently;\n // this helper handles the shared apply tail.\n const applied = await applyAggregate({\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: AggregatePlannerError): 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 AggregatePerSpaceExecutionEntry[];\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 AggregatePerSpaceExecutionEntry[];\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 { executeAggregateApply } from './db-apply-aggregate';\n\n/**\n * Options for executing the `db init` operation.\n *\n * `db init` runs the loader → planner → runner pipeline:\n *\n * 1. {@link executeAggregateApply} 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 `executeAcrossSpaces` 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 executeAggregateApply<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 { executeAggregateApply } from './db-apply-aggregate';\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 executeAggregateApply<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 executeAggregateApply<TFamilyId, TTargetId>>[0], 'mode'>,\n): Promise<DbUpdateResult | null> {\n const planResult = (await executeAggregateApply<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 AggregateVerifierOutput,\n type ContractSpaceMember,\n verifyAggregate,\n} from '@prisma-next/migration-tools/aggregate';\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 verifyAggregate} 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 = verifyAggregate({\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 validateContract: (json) => options.familyInstance.validateContract(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 */\nfunction 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 AggregateVerifierOutput} 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: AggregateVerifierOutput<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 profileHash = (member.contract as { profileHash?: string }).profileHash;\n return {\n ok: true,\n summary: 'Schema verification skipped',\n contract: {\n storageHash: member.headRef.hash,\n ...(profileHash ? { profileHash } : {}),\n },\n target: { expected: member.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 AggregatePerSpacePlan,\n type ContractMarkerRecordLike,\n type ContractSpaceAggregate,\n type ContractSpaceMember,\n graphWalkStrategy,\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 type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\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 AggregatePerSpaceExecutionEntry,\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n MigrationApplyResult,\n MigrationApplySuccess,\n OnControlProgress,\n} from '../types';\nimport { applyAggregate, buildPerSpaceBreakdown } from './apply-aggregate';\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 * Already-loaded app-space migration packages. The CLI command\n * loads these via `loadMigrationPackages(appMigrationsDir)`; the\n * operation hydrates the app member's graph with them. Required\n * because the framework-neutral aggregate loader doesn't know how\n * to read the user's `migrations/` directory layout (it's family-\n * aware: ops.json shape, manifest keys, etc.).\n */\n readonly appMigrationPackages: ReadonlyArray<OnDiskMigrationPackage>;\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 * Sub-spec § `--ref <hash>` semantics under multi-space.\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 applyAggregate} (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 appMigrationPackages,\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 validateContract: (json) => familyInstance.validateContract(json),\n appMigrationPackages,\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, AggregatePerSpacePlan>();\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, AggregatePerSpacePlan>();\n for (const member of allMembers) {\n const isAppMember = member.spaceId === aggregate.app.spaceId;\n const targetHash = isAppMember && refHash !== undefined ? refHash : member.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.migrations.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 : member.headRef.invariants;\n const targetMember: ContractSpaceMember =\n targetHash === member.headRef.hash && targetInvariants === member.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.migrations.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 applyAggregate({\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 AggregatePerSpacePlan} 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}): AggregatePerSpacePlan {\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, AggregatePerSpacePlan>,\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: AggregatePerSpacePlan;\n }>;\n readonly perSpace: ReadonlyArray<AggregatePerSpaceExecutionEntry>;\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 (today's single-space `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 ?? args.aggregate.app.headRef.hash;\n\n // Per-migration entries (one per authored edge) preserve the\n // single-space `migrationsApplied` count semantics for back-compat\n // with existing JSON-shape consumers (e.g. `parsed.applied.length`\n // in integration tests). The aggregate per-space breakdown lives on\n // `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\nfunction buildNeverPlannedFailure(spaceId: string, targetHash: string): 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}\". Run \\`prisma-next migration plan\\` first to materialise the path.`,\n meta: { spaceId, target: targetHash, kind: 'neverPlanned' },\n };\n}\n\nfunction buildPathNotFoundFailure(\n spaceId: string,\n marker: ContractMarkerRecordLike | null,\n targetHash: string,\n): MigrationApplyFailure {\n const fromHash = marker?.storageHash ?? '<empty>';\n // The single-space-degenerate phrasing names the user-visible\n // condition (a contract has been emitted that no on-disk\n // migration reaches) so the error reads naturally for the\n // single-space app case. Multi-space callers see the same\n // 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: `Cannot reach target \"${targetHash}\" from current marker \"${fromHash}\" in space \"${spaceId}\". The on-disk migration graph for this space does not connect the two states. Run \\`prisma-next migration plan\\` to materialise the path.`,\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.validateContract(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.validateContract(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.validateContract(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.validateContract(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.validateContract(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 let contract: Contract;\n try {\n contract = familyInstance.validateContract(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 executeDbVerify({\n driver,\n familyInstance,\n 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.validateContract(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 appMigrationPackages: options.appMigrationPackages,\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 const enrichedIR = enrichContract(contractRaw as Contract, this.frameworkComponents ?? []);\n\n try {\n this.familyInstance.validateContract(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":"db-verify-DtRB9iHJ.mjs","names":[],"sources":["../src/utils/combine-schema-results.ts","../src/commands/db-verify.ts"],"sourcesContent":["import type { VerifyDatabaseSchemaResult } from '@prisma-next/framework-components/control';\n\n/**\n * Collapse the aggregate verifier's per-space schema results into a\n * single {@link VerifyDatabaseSchemaResult} for the existing CLI\n * display surface. Concatenates issues across members; sums counts;\n * uses the app member's result as the structural envelope (storage\n * hash, target).\n *\n * **Summary policy.** Preserve the per-family phrasing whenever the\n * combined `ok` flag agrees with the app member's `ok` flag — this is\n * the common case (single-family deployments, single-app deployments)\n * and the family's \"satisfies / does not satisfy contract\" phrasing\n * stays user-visible. When the app passes but an extension fails (or\n * vice versa) the app's summary contradicts the envelope, so fall back\n * to the first failing member's summary. This keeps family phrasing\n * intact and the envelope internally consistent (`ok: false` ↔ failure\n * summary).\n */\nexport function combineSchemaResults(\n perSpace: ReadonlyMap<string, VerifyDatabaseSchemaResult>,\n appSpaceId: string,\n strict: boolean,\n): VerifyDatabaseSchemaResult {\n const appResult = perSpace.get(appSpaceId) ?? perSpace.values().next().value;\n if (appResult === undefined) {\n throw new Error('Aggregate verifier returned no schema results — this is a wiring bug.');\n }\n\n let okAll = true;\n let firstFailure: VerifyDatabaseSchemaResult | undefined;\n let issues: VerifyDatabaseSchemaResult['schema']['issues'] = [];\n const counts = { pass: 0, warn: 0, fail: 0, totalNodes: 0 };\n const childRoots: Array<VerifyDatabaseSchemaResult['schema']['root']> = [];\n for (const [, result] of perSpace) {\n if (!result.ok) {\n okAll = false;\n if (firstFailure === undefined) firstFailure = result;\n }\n issues = [...issues, ...result.schema.issues];\n counts.pass += result.schema.counts.pass;\n counts.warn += result.schema.counts.warn;\n counts.fail += result.schema.counts.fail;\n counts.totalNodes += result.schema.counts.totalNodes;\n childRoots.push(result.schema.root);\n }\n\n // When `okAll !== appResult.ok`, exactly one shape is reachable: app passes\n // (`appResult.ok === true`) and at least one other member failed\n // (`okAll === false`). In that shape the failure was assigned to\n // `firstFailure` during iteration, so non-null assertion is safe. The mirror\n // shape (app fails while every member passes) is impossible because\n // `appResult` either *is* a member of `perSpace` or is the first iterator\n // value; either way its `ok` flag participates in `okAll`.\n const summary =\n okAll === appResult.ok\n ? appResult.summary\n : (firstFailure as VerifyDatabaseSchemaResult).summary;\n\n return {\n ok: okAll,\n ...(okAll ? {} : { code: appResult.code ?? 'PN-RUN-3010' }),\n summary,\n contract: appResult.contract,\n target: appResult.target,\n schema: {\n issues,\n root: {\n status: okAll ? 'pass' : 'fail',\n kind: 'aggregate',\n name: 'aggregate',\n contractPath: '',\n code: 'AGGREGATE',\n message: okAll ? 'Aggregate schema matches' : 'Aggregate schema mismatch',\n expected: undefined,\n actual: undefined,\n children: childRoots,\n },\n counts,\n },\n meta: { strict },\n timings: { total: 0 },\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type {\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorHashMismatch,\n errorMarkerMissing,\n errorRuntime,\n errorTargetMismatch,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { combineSchemaResults } from '../utils/combine-schema-results';\nimport {\n addGlobalOptions,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport {\n type DbVerifyCommandSuccessResult,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatVerifyJson,\n formatVerifyOutput,\n} from '../utils/formatters/verify';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface DbVerifyOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly markerOnly?: boolean;\n readonly schemaOnly?: boolean;\n readonly strict?: boolean;\n}\n\ntype DbVerifyMode = 'full' | 'marker-only' | 'schema-only';\n\n/**\n * Maps a VerifyDatabaseResult failure to a CliStructuredError.\n */\nfunction mapVerifyFailure(verifyResult: VerifyDatabaseResult): CliStructuredError {\n if (!verifyResult.ok && verifyResult.code) {\n if (verifyResult.code === VERIFY_CODE_MARKER_MISSING) {\n return errorMarkerMissing();\n }\n if (verifyResult.code === VERIFY_CODE_HASH_MISMATCH) {\n const storageMatch = verifyResult.marker?.storageHash === verifyResult.contract.storageHash;\n const profileMatch =\n !verifyResult.contract.profileHash ||\n verifyResult.marker?.profileHash === verifyResult.contract.profileHash;\n\n if (!storageMatch) {\n return errorHashMismatch({\n why: 'Contract storageHash does not match database marker',\n expected: verifyResult.contract.storageHash,\n ...ifDefined('actual', verifyResult.marker?.storageHash),\n });\n }\n\n return errorHashMismatch({\n why: profileMatch\n ? 'Contract hash does not match database marker'\n : 'Contract profileHash does not match database marker',\n ...ifDefined('expected', verifyResult.contract.profileHash),\n ...ifDefined('actual', verifyResult.marker?.profileHash),\n });\n }\n if (verifyResult.code === VERIFY_CODE_TARGET_MISMATCH) {\n return errorTargetMismatch(\n verifyResult.target.expected,\n verifyResult.target.actual ?? 'unknown',\n );\n }\n // Unknown code - fall through to runtime error\n }\n return errorRuntime(verifyResult.summary);\n}\n\ntype DbVerifyFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\nfunction errorInvalidVerifyMode(options: {\n readonly why: string;\n readonly fix: string;\n}): CliStructuredError {\n return new CliStructuredError('4012', 'Invalid verify mode', {\n domain: 'CLI',\n why: options.why,\n fix: options.fix,\n docsUrl: 'https://pris.ly/db-verify',\n });\n}\n\nfunction resolveDbVerifyMode(options: DbVerifyOptions): Result<DbVerifyMode, CliStructuredError> {\n if (options.markerOnly && options.schemaOnly) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--marker-only` and `--schema-only` cannot be used together',\n fix: 'Choose one mode: omit both to check the marker and schema, use `--marker-only` to check only the marker, or use `--schema-only` to check only the live schema.',\n }),\n );\n }\n\n if (options.markerOnly && options.strict) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--strict` requires schema verification, but `--marker-only` skips it',\n fix: 'Remove `--strict`, or use `db verify` / `db verify --schema-only` when you want to check the live schema in strict mode.',\n }),\n );\n }\n\n if (options.schemaOnly) {\n return ok('schema-only');\n }\n\n if (options.markerOnly) {\n return ok('marker-only');\n }\n\n return ok('full');\n}\n\nfunction formatDbVerifyModeLabel(mode: DbVerifyMode, strict: boolean): string {\n if (mode === 'marker-only') {\n return 'marker only';\n }\n\n if (mode === 'schema-only') {\n return `schema only (${strict ? 'strict' : 'tolerant'})`;\n }\n\n return `full (marker + schema, ${strict ? 'strict' : 'tolerant'})`;\n}\n\nfunction formatDbVerifyInvocation(mode: DbVerifyMode, strict: boolean): string {\n const args = ['db verify'];\n\n if (mode === 'marker-only') {\n args.push('--marker-only');\n }\n\n if (mode === 'schema-only') {\n args.push('--schema-only');\n }\n\n if (strict) {\n args.push('--strict');\n }\n\n return args.join(' ');\n}\n\nfunction createDbVerifyConnectionRequiredError(options: {\n readonly configPath: string;\n readonly mode: DbVerifyMode;\n readonly strict: boolean;\n}): CliStructuredError {\n const invocation = formatDbVerifyInvocation(options.mode, options.strict);\n return errorDatabaseConnectionRequired({\n why: `Database connection is required for ${invocation} (set db.connection in ${options.configPath}, or pass --db <url>)`,\n retryCommand: `prisma-next ${invocation} --db <url>`,\n });\n}\n\nfunction renderVerifyHeader(\n paths: { configPath: string; contractPath: string },\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n flags: GlobalFlags,\n ui: TerminalUI,\n): void {\n if (flags.json || flags.quiet) return;\n\n const description =\n mode === 'schema-only'\n ? 'Check whether the live database schema matches your contract'\n : mode === 'marker-only'\n ? 'Check whether the database marker matches your contract'\n : 'Check whether the database marker and live schema match your contract';\n\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: paths.configPath },\n { label: 'contract', value: paths.contractPath },\n { label: 'mode', value: formatDbVerifyModeLabel(mode, options.strict ?? false) },\n ];\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n }\n\n ui.stderr(\n formatStyledHeader({\n command: 'db verify',\n description,\n url: 'https://pris.ly/db-verify',\n details,\n flags,\n }),\n );\n}\n\nasync function resolveVerifyPaths(options: DbVerifyOptions) {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n return { config, configPath, contractPathAbsolute, contractPath };\n}\n\ntype VerifyPaths = Awaited<ReturnType<typeof resolveVerifyPaths>>;\n\ninterface VerifySetup extends VerifyPaths {\n readonly contractJson: Record<string, unknown>;\n readonly dbConnection: string;\n}\n\nasync function resolveVerifySetup(\n paths: VerifyPaths,\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n): Promise<Result<VerifySetup, CliStructuredError>> {\n const { config, configPath, contractPathAbsolute, contractPath } = paths;\n\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const dbConnection = options.db ?? config.db?.connection;\n if (typeof dbConnection !== 'string' || dbConnection.length === 0) {\n return notOk(\n createDbVerifyConnectionRequiredError({\n configPath,\n mode,\n strict: options.strict ?? false,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: `Config.driver is required for ${formatDbVerifyInvocation(mode, options.strict ?? false)}`,\n }),\n );\n }\n\n return ok({ ...paths, contractJson, dbConnection });\n}\n\nfunction createVerifyClient(setup: VerifySetup) {\n return createControlClient({\n family: setup.config.family,\n target: setup.config.target,\n adapter: setup.config.adapter,\n driver: setup.config.driver!,\n extensionPacks: setup.config.extensionPacks ?? [],\n });\n}\n\nfunction wrapVerifyError(\n error: unknown,\n contractPathAbsolute: string,\n modeLabel: string,\n): Result<never, CliStructuredError> {\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during ${modeLabel}: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n}\n\n/**\n * Executes the db verify command and returns a structured Result.\n */\nasync function executeDbVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n mode: Extract<DbVerifyMode, 'full' | 'marker-only'>,\n): Promise<Result<DbVerifyCommandSuccessResult, DbVerifyFailure>> {\n const startTime = Date.now();\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, mode, flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, mode);\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Single-contract marker verification preserved for the existing\n // marker / target / hash failure surface (`PN-RUN-3001/3002/3003`).\n // The aggregate verifier (run below for the per-space marker /\n // schema checks) does not duplicate this: it concerns itself with\n // marker-vs-on-disk and orphan-marker drift, not the\n // hash-mismatch-against-the-app-contract lane that today's\n // `client.verify` covers.\n const verifyResult = await client.verify({\n contract: contractJson,\n connection: dbConnection,\n onProgress,\n });\n\n if (!verifyResult.ok) {\n return notOk(mapVerifyFailure(verifyResult));\n }\n\n // Aggregate verifier (loader → verifier pipeline). Runs the layout\n // precheck, marker-aware per-space verifier, and (full mode only)\n // per-space pre-projected schema verification (closes F23).\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: mode === 'marker-only',\n skipMarker: false,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n if (mode === 'marker-only') {\n return ok({\n ok: true,\n mode: 'marker-only',\n summary: 'Database marker matches contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n warning: 'Schema verification skipped because --marker-only was provided',\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'skipped',\n },\n timings: { total: Date.now() - startTime },\n });\n }\n\n const combined = combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n );\n if (!combined.ok) {\n return notOk(combined);\n }\n\n return ok({\n ok: true,\n mode: 'full',\n summary: 'Database marker and schema match contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n schema: {\n summary: combined.summary,\n counts: combined.schema.counts,\n strict: combined.meta?.strict ?? false,\n },\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'performed',\n },\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify');\n } finally {\n await client.close();\n }\n}\n\nasync function executeDbSchemaOnlyVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<VerifyDatabaseSchemaResult, CliStructuredError>> {\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, 'schema-only', flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, 'schema-only');\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n await client.connect(dbConnection);\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: false,\n skipMarker: true,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n return ok(\n combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n ),\n );\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify --schema-only');\n } finally {\n await client.close();\n }\n}\n\nexport function createDbVerifyCommand(): Command {\n const command = new Command('verify');\n setCommandDescriptions(\n command,\n 'Check whether the database marker and live schema match your contract',\n 'Verifies the database marker first, then checks the database schema matches your contract.\\n' +\n 'Use `--marker-only` for marker-only verification, `--schema-only` to skip marker checks and\\n' +\n 'inspect only the live schema, and `--strict` to fail if the database includes elements\\n' +\n 'not present in the contract.',\n );\n setCommandExamples(command, [\n 'prisma-next db verify --db $DATABASE_URL',\n 'prisma-next db verify --db $DATABASE_URL --strict',\n 'prisma-next db verify --db $DATABASE_URL --schema-only',\n 'prisma-next db verify --db $DATABASE_URL --schema-only --strict',\n 'prisma-next db verify --db $DATABASE_URL --marker-only',\n 'prisma-next db verify --db $DATABASE_URL --json',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--marker-only', 'Skip schema verification and only check the database marker')\n .option(\n '--schema-only',\n 'Skip marker verification and only check whether the live schema satisfies the contract',\n )\n .option(\n '--strict',\n 'Strict mode: schema elements not present in the contract are considered an error',\n false,\n )\n .action(async (options: DbVerifyOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const modeResult = resolveDbVerifyMode(options);\n if (!modeResult.ok) {\n const exitCode = handleResult(modeResult as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n const mode = modeResult.value;\n\n if (mode === 'schema-only') {\n const result = await executeDbSchemaOnlyVerifyCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (schemaVerifyResult) => {\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(schemaVerifyResult));\n } else {\n const output = formatSchemaVerifyOutput(schemaVerifyResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n\n if (result.ok && !result.value.ok) {\n process.exit(1);\n }\n\n process.exit(exitCode);\n }\n\n const result = await executeDbVerifyCommand(options, flags, ui, mode);\n\n if (result.ok) {\n if (flags.json) {\n ui.output(formatVerifyJson(result.value));\n } else {\n const output = formatVerifyOutput(result.value, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(0);\n }\n\n if (CliStructuredError.is(result.failure)) {\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(result.failure));\n } else {\n // Always show schema-drift failures, even in quiet mode — exiting 1 without\n // diagnostics is unhelpful.\n const output = formatSchemaVerifyOutput(result.failure, { ...flags, quiet: false });\n if (output) {\n ui.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migration-plan-DWB-NTxH.mjs","names":[],"sources":["../src/utils/contract-space-seed-phase.ts","../src/commands/migration-plan.ts"],"sourcesContent":["import { materialiseExtensionMigrationPackageIfMissing } from '@prisma-next/migration-tools/io';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport type { MigrationOps } from '@prisma-next/migration-tools/package';\nimport {\n emitContractSpaceArtefacts,\n planAllSpaces,\n readContractSpaceHeadRef,\n type SpacePlanOutput,\n spaceMigrationDirectory,\n} from '@prisma-next/migration-tools/spaces';\n\n/**\n * In-memory authored migration package shipped by an extension descriptor.\n * Mirrors `MigrationPackage` from `@prisma-next/migration-tools/io` (the\n * on-disk shape minus `dirPath`); redeclared structurally here so the\n * CLI helper does not couple to any family's `ExtensionMigrationPackage`\n * type — any family that ships pre-built migration packages can pass\n * them through unchanged.\n */\nexport interface DescriptorMigrationPackage {\n readonly dirName: string;\n readonly metadata: MigrationMetadata;\n readonly ops: MigrationOps;\n}\n\n/**\n * Minimal descriptor view consumed by the seed phase. Mirrors the shape\n * the SQL family ships on each declared extension entry; only the fields\n * the seed phase needs are surfaced.\n */\nexport interface SeedPhaseExtensionInput {\n readonly id: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: { readonly hash: string; readonly invariants: readonly string[] };\n readonly migrations: readonly DescriptorMigrationPackage[];\n };\n}\n\nexport interface ContractSpaceSeedPhaseInputs {\n readonly migrationsDir: string;\n readonly extensionPacks: ReadonlyArray<SeedPhaseExtensionInput>;\n}\n\n/**\n * One per-space record describing what the seed phase did for an\n * extension contract space. Surfaced verbatim by the caller (typically\n * `migration plan`) so users see a single line per touched extension.\n *\n * - `action: 'updated'` — either the on-disk head pointer changed, or\n * one or more new descriptor-shipped migration packages were\n * materialised into `migrations/<spaceId>/<dirName>/`.\n * - `action: 'unchanged'` — the on-disk head already matched the\n * descriptor and no new migration packages needed to be written.\n *\n * Either way, the artefacts (`contract.json`, `contract.d.ts`,\n * `refs/head.json`) are re-emitted: the framework owns those files and\n * makes the re-emit observably idempotent at the byte level.\n */\nexport interface ContractSpaceSeedPhaseRecord {\n readonly spaceId: string;\n readonly action: 'updated' | 'unchanged';\n readonly priorHash: string | null;\n readonly newHash: string;\n readonly newMigrationDirs: readonly string[];\n}\n\nexport interface ContractSpaceSeedPhaseResult {\n readonly seeded: readonly ContractSpaceSeedPhaseRecord[];\n}\n\n/**\n * Phase-1 of the two-phase `migration plan` pipeline (sub-spec § 4).\n *\n * For every extension that exposes a `contractSpace`:\n *\n * 1. Read the on-disk head ref (returns `null` on first emit).\n * 2. Re-emit `contract.json` / `contract.d.ts` / `refs/head.json`\n * unconditionally via {@link emitContractSpaceArtefacts}. The\n * framework owns these files; re-emit is the contract.\n * 3. Materialise any descriptor-shipped migration packages not yet on\n * disk via {@link materialiseExtensionMigrationPackageIfMissing}.\n * Existing packages are left untouched (by-existence skip).\n *\n * The return value lets the caller render a per-space status line and\n * lets the phase-2 aggregate loader run on a now-consistent disk state\n * (every loaded extension is guaranteed to have its head ref pinned\n * to the descriptor's hash and to ship every package the descriptor\n * declares).\n *\n * Output ordering is deterministic and alphabetical by spaceId (via\n * {@link planAllSpaces}, which also detects duplicate spaceIds). This\n * matches the canonical sort order used by every other aggregate\n * surface (`migrate`, `migration status`, the runner).\n */\nexport async function runContractSpaceSeedPhase(\n inputs: ContractSpaceSeedPhaseInputs,\n): Promise<ContractSpaceSeedPhaseResult> {\n const planInputs = inputs.extensionPacks\n .filter(\n (\n pack,\n ): pack is SeedPhaseExtensionInput & {\n contractSpace: NonNullable<SeedPhaseExtensionInput['contractSpace']>;\n } => pack.contractSpace !== undefined,\n )\n .map((pack) => ({\n spaceId: pack.id,\n priorContract: null,\n newContract: pack.contractSpace.contractJson,\n __pack: pack.contractSpace,\n }));\n\n // `planAllSpaces` brings deterministic alphabetical ordering and\n // duplicate-spaceId detection. The \"planner\" callback is a no-op\n // pass-through that simply returns the descriptor's pre-built\n // migration packages.\n const planned: readonly SpacePlanOutput<DescriptorMigrationPackage>[] = planAllSpaces(\n planInputs,\n (input) =>\n (\n input as typeof input & {\n readonly __pack: NonNullable<SeedPhaseExtensionInput['contractSpace']>;\n }\n ).__pack.migrations,\n );\n\n // Reassemble a spaceId → descriptor lookup so the loop below can read\n // the contractJson / headRef without leaking the typed-cast back into\n // `planAllSpaces`'s output shape.\n const descriptorBySpace = new Map<\n string,\n NonNullable<SeedPhaseExtensionInput['contractSpace']>\n >();\n for (const pack of inputs.extensionPacks) {\n if (pack.contractSpace !== undefined) descriptorBySpace.set(pack.id, pack.contractSpace);\n }\n\n const seeded: ContractSpaceSeedPhaseRecord[] = [];\n for (const space of planned) {\n const descriptor = descriptorBySpace.get(space.spaceId);\n if (descriptor === undefined) continue;\n\n const onDiskHeadRef = await readContractSpaceHeadRef(inputs.migrationsDir, space.spaceId);\n const priorHash = onDiskHeadRef?.hash ?? null;\n\n await emitContractSpaceArtefacts(inputs.migrationsDir, space.spaceId, {\n contract: descriptor.contractJson,\n contractDts: buildPlaceholderContractDts(space.spaceId),\n headRef: { hash: descriptor.headRef.hash, invariants: descriptor.headRef.invariants },\n });\n\n const spaceDir = spaceMigrationDirectory(inputs.migrationsDir, space.spaceId);\n const newMigrationDirs: string[] = [];\n for (const pkg of space.migrationPackages) {\n const { written } = await materialiseExtensionMigrationPackageIfMissing(spaceDir, pkg);\n if (written) newMigrationDirs.push(pkg.dirName);\n }\n\n const action: ContractSpaceSeedPhaseRecord['action'] =\n priorHash !== descriptor.headRef.hash || newMigrationDirs.length > 0\n ? 'updated'\n : 'unchanged';\n\n seeded.push({\n spaceId: space.spaceId,\n action,\n priorHash,\n newHash: descriptor.headRef.hash,\n newMigrationDirs,\n });\n }\n\n return { seeded };\n}\n\n/**\n * Placeholder `.d.ts` content for an extension space's on-disk mirror.\n *\n * Rendering a fully-typed `.d.ts` for an extension contract requires\n * the SQL-family renderer with the codec / typemap registry threaded\n * through; until that integration ships, the on-disk `.d.ts` is a\n * stub `export {};` module that documents how consumers should\n * validate the sibling `contract.json`. The stub typechecks on its\n * own and does not need any TypeScript suppressions.\n */\nfunction buildPlaceholderContractDts(spaceId: string): string {\n return [\n '/**',\n ` * Placeholder \\`.d.ts\\` for extension space \"${spaceId}\".`,\n ' *',\n ' * The framework re-emits this file on every `migration plan` run',\n ' * alongside `contract.json` and `refs/head.json`. A typed `.d.ts`',\n ' * rendering pass for extension contracts is tracked separately;',\n ' * until that ships, consumers should import `contract.json`',\n ' * and pass it through the target descriptor’s `contractSerializer`.',\n ' */',\n 'export {};',\n '',\n ].join('\\n');\n}\n","import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport {\n createControlStack,\n hasOperationPreview,\n type MigrationPlanOperation,\n type OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { computeMigrationHash } from '@prisma-next/migration-tools/hash';\nimport { deriveProvidedInvariants } from '@prisma-next/migration-tools/invariants';\nimport {\n copyFilesWithRename,\n formatMigrationDirName,\n writeMigrationPackage,\n} from '@prisma-next/migration-tools/io';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport { findLatestMigration } from '@prisma-next/migration-tools/migration-graph';\nimport { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { readRefs } from '@prisma-next/migration-tools/refs';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join, relative } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport {\n type CliErrorConflict,\n CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorMigrationPlanningFailed,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n getTargetMigrations,\n loadMigrationPackages,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { buildContractSpaceAggregate } from '../utils/contract-space-aggregate-loader';\nimport { runContractSpaceSeedPhase } from '../utils/contract-space-seed-phase';\nimport { toExtensionInputs } from '../utils/extension-pack-inputs';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationPlanOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly name?: string;\n readonly from?: string;\n}\n\n/**\n * Load a predecessor migration's destination contract from its sibling\n * `end-contract.json` on disk. The manifest no longer inlines the\n * contract; the planner reads it from the canonical on-disk artefact\n * authored by a previous `migration plan` run.\n *\n * Throws `CliStructuredError` with `errorFileNotFound` when the\n * sibling file is missing — the user has likely deleted or never\n * authored the snapshot, and the message names the file and points\n * them at re-emitting from the source.\n */\nasync function readPredecessorEndContract(migrationDir: string): Promise<Contract> {\n const path = join(migrationDir, 'end-contract.json');\n let raw: string;\n try {\n raw = await readFile(path, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n throw errorFileNotFound(path, {\n why: `Predecessor migration is missing its destination contract snapshot at ${path}`,\n fix: 'Re-emit the predecessor migration (`prisma-next migration plan` from its source) so its sibling `end-contract.json` is restored, then re-run this command.',\n });\n }\n throw error;\n }\n return JSON.parse(raw) as Contract;\n}\n\nexport interface MigrationPlanResult {\n readonly ok: boolean;\n readonly noOp: boolean;\n readonly from: string | null;\n readonly to: string;\n readonly dir?: string;\n /**\n * Extension-space migration packages materialised onto disk during this\n * `plan` run. Each entry names a `migrations/<spaceId>/<dirName>/`\n * tree the framework wrote alongside the app-space migration directory.\n * Empty when the project has no extension packs declaring a contract\n * space, or when every extension-space package is already on disk.\n *\n * Surfacing these in the result (rather than only via `ui.step` log\n * lines) makes the cross-space side effect explicit to JSON consumers\n * and the success-summary renderer — the same multi-space side effect\n * that `migrate` will replay.\n */\n readonly emittedExtensionDirs: readonly { readonly spaceId: string; readonly dirName: string }[];\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the migration plan operations.\n * Replaces the previous `sql?: readonly string[]` field; consumers should\n * read `result.preview?.statements`.\n */\n readonly preview?: OperationPreview;\n readonly summary: string;\n /**\n * When true, `migration.ts` was written but contains unfilled\n * `placeholder(...)` calls. The user must edit the file and then run\n * `node migration.ts` to self-emit `ops.json` / `migration.json`.\n */\n readonly pendingPlaceholders?: boolean;\n readonly timings: {\n readonly total: number;\n };\n}\n\nasync function executeMigrationPlanCommand(\n options: MigrationPlanOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrationPlanResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative } =\n resolveMigrationPaths(options.config, config);\n\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (options.from) {\n details.push({ label: 'from', value: options.from });\n }\n if (options.name) {\n details.push({ label: 'name', value: options.name });\n }\n const header = formatStyledHeader({\n command: 'migration plan',\n description: 'Plan a migration from contract changes',\n url: 'https://pris.ly/migration-plan',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n // Load contract file (the \"to\" contract)\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let toContractJson: Contract;\n try {\n toContractJson = JSON.parse(contractJsonContent) as Contract;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const rawStorageHash = toContractJson.storage?.storageHash;\n if (typeof rawStorageHash !== 'string') {\n return notOk(\n errorContractValidationFailed('Contract is missing storageHash', {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n const toStorageHash = rawStorageHash;\n\n // Read existing migrations and determine \"from\" contract\n let fromContract: Contract | null = null;\n let fromHash: string | null = null;\n let fromContractSourceDir: string | null = null;\n\n try {\n const { bundles, graph } = await loadMigrationPackages(appMigrationsDir);\n\n if (options.from) {\n const refs = await readRefs(resolveMigrationPaths(options.config, config).refsDir);\n const refResult = parseContractRef(options.from, { graph, refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n fromHash = refResult.value.hash;\n const matchingBundle = bundles.find((p) => p.metadata.to === fromHash);\n if (!matchingBundle) {\n return notOk(\n errorUnexpected(\n `No migration bundle found for --from \"${options.from}\" (resolved hash: ${fromHash})`,\n {\n why: `The ref resolved successfully but no on-disk migration package has an end-contract hash matching ${fromHash}.`,\n fix: 'Provide a ref or hash that corresponds to an existing migration package, or run `migration list` to see available migrations.',\n },\n ),\n );\n }\n fromContractSourceDir = matchingBundle.dirPath;\n fromContract = await readPredecessorEndContract(fromContractSourceDir);\n } else {\n const latestMigration = findLatestMigration(graph);\n if (latestMigration) {\n fromHash = latestMigration.to;\n const leafPkg = bundles.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n if (leafPkg) {\n fromContractSourceDir = leafPkg.dirPath;\n fromContract = await readPredecessorEndContract(fromContractSourceDir);\n }\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n // `readPredecessorEndContract` raises a `CliStructuredError` directly\n // for the missing-snapshot case so the operator gets a precise\n // why/fix; pass it through unchanged rather than re-wrapping.\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n // Wrap unexpected (non-MigrationToolsError) failures from the migration\n // load phase in a structured CLI envelope. Letting them throw would\n // bypass `handleResult()` and crash the command — see CLI structured-\n // errors guideline (CliStructuredError + Result pattern).\n const message = error instanceof Error ? error.message : String(error);\n return notOk(\n errorUnexpected(message, {\n why: `Unexpected error while loading migrations: ${message}`,\n }),\n );\n }\n\n // Phase 1 — seed: unconditionally re-emit per-space pinned artefacts\n // (contract.json / contract.d.ts / refs/head.json) and materialise any\n // descriptor-shipped migration packages not yet on disk. Runs before\n // the no-op check so that an extension bump alone (with no structural\n // app-space change) still re-pins extension artefacts on disk.\n const canonicalExtensionInputs = toExtensionInputs(config.extensionPacks ?? []);\n const seedResult = await runContractSpaceSeedPhase({\n migrationsDir,\n extensionPacks: canonicalExtensionInputs,\n });\n if (!flags.json && !flags.quiet) {\n for (const record of seedResult.seeded) {\n if (record.action === 'updated') {\n const pkgSuffix =\n record.newMigrationDirs.length > 0\n ? `; ${record.newMigrationDirs.length} new migration package(s) materialised`\n : '';\n ui.step(`Updated ${record.spaceId} to ${record.newHash}${pkgSuffix}`);\n }\n }\n }\n const emittedExtensionDirs = seedResult.seeded.flatMap((r) =>\n r.newMigrationDirs.map((dirName) => ({ spaceId: r.spaceId, dirName })),\n );\n\n // Check for no-op (same hash means no changes)\n if (fromHash === toStorageHash) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: true,\n from: fromHash,\n to: toStorageHash,\n operations: [],\n emittedExtensionDirs,\n summary: 'No changes detected between contracts',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n // Check target supports migrations\n const migrations = getTargetMigrations(config.target);\n if (!migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n // Phase 2 — load: build the aggregate against the now-consistent disk\n // state that phase 1 just seeded. The seed phase guarantees every\n // declared extension has its head ref pinned, so the loader's\n // declaredButUnmigrated precheck always passes here.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n let validatedAppContract: Contract;\n try {\n validatedAppContract = familyInstance.validateContract(toContractJson);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract validation failed: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n const aggregateResult = await buildContractSpaceAggregate({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: validatedAppContract,\n extensionPacks: config.extensionPacks ?? [],\n validateContract: (json: unknown) => familyInstance.validateContract(json),\n });\n if (!aggregateResult.ok) {\n return notOk(aggregateResult.failure);\n }\n const aggregate = aggregateResult.value;\n\n const frameworkComponents = assertFrameworkComponentsCompatible(\n config.family.familyId,\n config.target.targetId,\n [config.target, config.adapter, ...(config.extensionPacks ?? [])],\n );\n\n // Build manifest and write migration package\n const timestamp = new Date();\n const slug = options.name ?? 'migration';\n const dirName = formatMigrationDirName(timestamp, slug);\n const packageDir = join(appMigrationsDir, dirName);\n\n const baseMetadata: Omit<MigrationMetadata, 'migrationHash' | 'providedInvariants'> = {\n from: fromHash,\n to: toStorageHash,\n hints: {\n used: [],\n applied: [],\n plannerVersion: '2.0.0',\n },\n labels: [],\n createdAt: timestamp.toISOString(),\n };\n\n try {\n const planner = migrations.createPlanner(familyInstance);\n const fromSchema = migrations.contractToSchema(fromContract, frameworkComponents);\n const plannerResult = planner.plan({\n contract: aggregate.app.contract,\n schema: fromSchema,\n policy: { allowedOperationClasses: ['additive', 'widening', 'destructive', 'data'] },\n fromContract,\n frameworkComponents,\n spaceId: aggregate.app.spaceId,\n });\n if (plannerResult.kind === 'failure') {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: plannerResult.conflicts as readonly CliErrorConflict[],\n }),\n );\n }\n\n // Accessing .operations triggers toOp() on each call. If any call\n // is a DataTransformCall with an unfilled placeholder stub, toOp()\n // throws PN-MIG-2001. We catch that here so the migration can still\n // be scaffolded with `ops: []`; the user fills the placeholder, then\n // re-runs `node migration.ts` to attest with the real ops.\n let plannedOps: readonly MigrationPlanOperation[] = [];\n let hasPlaceholders = false;\n try {\n plannedOps = plannerResult.plan.operations;\n if (plannedOps.length === 0) {\n return notOk(\n errorMigrationPlanningFailed({\n conflicts: [\n {\n kind: 'unsupportedChange',\n summary:\n 'Contract changed but planner produced no operations. ' +\n 'This indicates unsupported or ignored changes.',\n },\n ],\n }),\n );\n }\n } catch (e) {\n if (CliStructuredError.is(e) && e.domain === 'MIG' && e.code === '2001') {\n hasPlaceholders = true;\n } else {\n throw e;\n }\n }\n\n const migrationTsContent = plannerResult.plan.renderTypeScript();\n\n // Always-attest: compute migrationHash over (metadata, ops). When\n // placeholders blocked lowering, ops is `[]` and the hash is computed\n // over the empty list — re-emitting after the user fills the placeholder\n // produces a different hash (over the real ops). This is intentional;\n // there is no on-disk \"draft\" state.\n const opsForWrite = hasPlaceholders ? [] : plannedOps;\n const metadataWithInvariants: Omit<MigrationMetadata, 'migrationHash'> = {\n ...baseMetadata,\n providedInvariants: deriveProvidedInvariants(opsForWrite),\n };\n const metadata: MigrationMetadata = {\n ...metadataWithInvariants,\n migrationHash: computeMigrationHash(metadataWithInvariants, opsForWrite),\n };\n\n await writeMigrationPackage(packageDir, metadata, opsForWrite);\n const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);\n await copyFilesWithRename(packageDir, [\n { sourcePath: destinationArtifacts.jsonPath, destName: 'end-contract.json' },\n { sourcePath: destinationArtifacts.dtsPath, destName: 'end-contract.d.ts' },\n ]);\n if (fromContractSourceDir !== null) {\n const sourceArtifacts = getEmittedArtifactPaths(\n join(fromContractSourceDir, 'end-contract.json'),\n );\n await copyFilesWithRename(packageDir, [\n { sourcePath: sourceArtifacts.jsonPath, destName: 'start-contract.json' },\n { sourcePath: sourceArtifacts.dtsPath, destName: 'start-contract.d.ts' },\n ]);\n }\n await writeMigrationTs(packageDir, migrationTsContent);\n\n if (hasPlaceholders) {\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), packageDir),\n operations: [],\n emittedExtensionDirs,\n pendingPlaceholders: true,\n summary:\n 'Planned migration with placeholder(s) — edit migration.ts then run `node migration.ts` to self-emit',\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n }\n\n const preview = hasOperationPreview(familyInstance)\n ? familyInstance.toOperationPreview(plannedOps)\n : undefined;\n const result: MigrationPlanResult = {\n ok: true,\n noOp: false,\n from: fromHash,\n to: toStorageHash,\n dir: relative(process.cwd(), packageDir),\n operations: plannedOps.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n emittedExtensionDirs,\n ...(preview !== undefined ? { preview } : {}),\n summary: buildPlanSummary(plannedOps.length, emittedExtensionDirs.length),\n timings: { total: Date.now() - startTime },\n };\n return ok(result);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n const message = error instanceof Error ? error.message : String(error);\n return notOk(\n errorUnexpected(message, {\n why: `Unexpected error during migration plan: ${message}`,\n }),\n );\n }\n}\n\nexport function createMigrationPlanCommand(): Command {\n const command = new Command('plan');\n setCommandDescriptions(\n command,\n 'Plan a migration from contract changes',\n 'Compares the emitted contract against the latest on-disk migration state and\\n' +\n 'produces a new migration package with the required operations. No database\\n' +\n 'connection is needed — this is a fully offline operation.',\n );\n setCommandExamples(command, [\n 'prisma-next migration plan',\n 'prisma-next migration plan --name add-users-table',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--name <slug>', 'Name slug for the migration directory', 'migration')\n .option(\n '--from <contract>',\n 'Starting contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .action(async (options: MigrationPlanOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const result = await executeMigrationPlanCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (planResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(planResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationPlanOutput(planResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n\n/**\n * Compose the success-line summary so the cross-space side effect\n * (extension-space migration packages materialised on disk during\n * this `plan` run) is visible in the top line — not just in the\n * step log above it.\n *\n * Example outputs:\n * - `Planned 3 operation(s)` (app-space-only project)\n * - `Planned 3 operation(s); materialised 1 extension-space migration` (one extension)\n * - `Planned 3 operation(s); materialised 2 extension-space migrations` (two extensions)\n *\n * Locks AC3 at the summary-line level: a reader of the success line\n * can tell that something happened beyond the app space.\n */\nfunction buildPlanSummary(plannedOpsCount: number, emittedExtensionDirsCount: number): string {\n const base = `Planned ${plannedOpsCount} operation(s)`;\n if (emittedExtensionDirsCount === 0) return base;\n const noun =\n emittedExtensionDirsCount === 1 ? 'extension-space migration' : 'extension-space migrations';\n return `${base}; materialised ${emittedExtensionDirsCount} ${noun}`;\n}\n\nexport function formatMigrationPlanOutput(result: MigrationPlanResult, flags: GlobalFlags): string {\n const lines: string[] = [];\n const useColor = flags.color !== false;\n\n const green_ = useColor ? (s: string) => `\\x1b[32m${s}\\x1b[0m` : (s: string) => s;\n const yellow_ = useColor ? (s: string) => `\\x1b[33m${s}\\x1b[0m` : (s: string) => s;\n const dim_ = useColor ? (s: string) => `\\x1b[2m${s}\\x1b[0m` : (s: string) => s;\n\n // Renders the extension-space materialisation block + canonical apply-step\n // hint shared by the no-op, placeholder, and full-plan branches. The app\n // space short-circuits do not skip it: an extension-only bump emits new\n // `migrations/<spaceId>/<dirName>/` directories on disk that the user\n // still has to apply, so the success line must surface them.\n function appendEmittedExtensions(): void {\n if (result.emittedExtensionDirs.length === 0) return;\n lines.push('');\n lines.push(dim_('Emitted extension migrations:'));\n for (const entry of result.emittedExtensionDirs) {\n lines.push(dim_(` ${entry.spaceId} → migrations/${entry.spaceId}/${entry.dirName}`));\n }\n lines.push('');\n lines.push(\n `Next: review the extension migrations above, then run ${green_('prisma-next migrate')}.`,\n );\n }\n\n if (result.noOp) {\n lines.push(`${green_('✔')} No changes detected`);\n lines.push(dim_(` from: ${result.from}`));\n lines.push(dim_(` to: ${result.to}`));\n appendEmittedExtensions();\n return lines.join('\\n');\n }\n\n if (result.pendingPlaceholders) {\n lines.push(`${yellow_('⚠')} ${result.summary}`);\n lines.push('');\n lines.push(dim_(`from: ${result.from}`));\n lines.push(dim_(`to: ${result.to}`));\n if (result.dir) {\n lines.push(dim_(`dir: ${result.dir}`));\n }\n lines.push('');\n lines.push(\n 'Open migration.ts and replace each `placeholder(...)` call with your actual query.',\n );\n lines.push(`Then run: ${green_(`node ${result.dir ?? '<dir>'}/migration.ts`)}`);\n appendEmittedExtensions();\n return lines.join('\\n');\n }\n\n lines.push(`${green_('✔')} ${result.summary}`);\n lines.push('');\n\n if (result.operations.length > 0) {\n lines.push(dim_('│'));\n for (let i = 0; i < result.operations.length; i++) {\n const op = result.operations[i]!;\n const isLast = i === result.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n // operationClass tag is intentionally NOT inlined per spec:\n // a destructive footer warning still surfaces below this list.\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${yellow_('(destructive)')}` : '';\n lines.push(`${dim_(treeChar)}─ ${op.label}${destructiveMarker}`);\n }\n\n const hasDestructive = result.operations.some((op) => op.operationClass === 'destructive');\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${yellow_('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n lines.push('');\n }\n\n lines.push(dim_(`from: ${result.from}`));\n lines.push(dim_(`to: ${result.to}`));\n if (result.dir) {\n lines.push(dim_(`App space → ${result.dir}`));\n }\n // Per-space block: surface the extension-space directories materialised\n // alongside the app-space migration. Without this block the cross-space\n // side effect is invisible in the success summary (e2e finding F1).\n for (const entry of result.emittedExtensionDirs) {\n lines.push(\n dim_(`Extension space ${entry.spaceId} → migrations/${entry.spaceId}/${entry.dirName}`),\n );\n }\n\n lines.push('');\n // The \"Next:\" hint always points at the canonical apply path\n // (`prisma-next migrate`) regardless of how many spaces were\n // materialised — `db update` is a dev-time convenience, not the\n // canonical replay step.\n lines.push(\n `Next: review ${green_(result.dir ?? '<dir>')} if needed, then run ${green_('prisma-next migrate')}.`,\n );\n\n if (result.preview && result.preview.statements.length > 0) {\n // The non-empty length is already guaranteed by the surrounding check, so\n // a plain `every` here is equivalent to the helper in formatters/migrations.ts.\n const allSql = result.preview.statements.every((s) => s.language === 'sql');\n lines.push('');\n lines.push(dim_(allSql ? 'DDL preview' : 'Operation preview'));\n lines.push('');\n for (const statement of result.preview.statements) {\n const trimmed = statement.text.trim();\n if (!trimmed) continue;\n const line = statement.language === 'sql' && !trimmed.endsWith(';') ? `${trimmed};` : trimmed;\n lines.push(line);\n }\n }\n\n if (flags.verbose && result.timings) {\n lines.push('');\n lines.push(dim_(`Total time: ${result.timings.total}ms`));\n }\n\n return lines.join('\\n');\n}\n\nexport type PrefixResolutionFailure =\n | { reason: 'ambiguous'; count: number }\n | { reason: 'not-found' };\n\n/**\n * Resolve a migration package by **target contract hash** (`metadata.to`)\n * using exact match or prefix match.\n *\n * Note: matches `metadata.to` (the contract hash this migration produces),\n * not `metadata.migrationHash` (the package's content-addressed identity).\n * Tries exact match first, then prefix match (auto-prepending `sha256:` when\n * the needle omits the scheme). Returns the matched package on success, or a\n * discriminated failure indicating whether the prefix was ambiguous or simply\n * not found.\n *\n * @internal Exported for testing only.\n */\nexport function resolveBundleByPrefix<T extends { metadata: { to: string } }>(\n bundles: readonly T[],\n needle: string,\n): Result<T, PrefixResolutionFailure> {\n const exact = bundles.find((p) => p.metadata.to === needle);\n if (exact) return ok(exact);\n\n const prefixWithScheme = needle.startsWith('sha256:') ? needle : `sha256:${needle}`;\n const candidates = bundles.filter((p) => p.metadata.to.startsWith(prefixWithScheme));\n\n if (candidates.length === 1) return ok(candidates[0]!);\n if (candidates.length > 1) return notOk({ reason: 'ambiguous', count: candidates.length });\n return notOk({ reason: 'not-found' });\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types-BS_wpjAY.d.mts","names":[],"sources":["../src/control-api/operations/db-verify.ts","../src/control-api/types.ts"],"mappings":"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"}
|