prisma-next 0.12.0-dev.27 → 0.12.0-dev.28
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 +11 -11
- package/dist/{client-V7BkIQrQ.mjs → client-nygCs15r.mjs} +22 -11
- package/dist/client-nygCs15r.mjs.map +1 -0
- package/dist/{command-helpers-DlrUCI7s.mjs → command-helpers-D7TK5Y9e.mjs} +239 -2
- package/dist/command-helpers-D7TK5Y9e.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 +4 -5
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +4 -4
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +10 -7
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.mjs +5 -6
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.mjs +1 -1
- package/dist/commands/migration-graph.d.mts +4 -4
- package/dist/commands/migration-graph.mjs +3 -3
- package/dist/commands/migration-list.d.mts +4 -4
- package/dist/commands/migration-list.mjs +3 -3
- package/dist/commands/migration-log.d.mts +3 -3
- package/dist/commands/migration-log.mjs +1 -1
- package/dist/commands/migration-new.mjs +3 -3
- package/dist/commands/migration-plan.d.mts +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +1 -1
- package/dist/commands/migration-show.mjs +3 -4
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +2 -2
- package/dist/commands/migration-status.mjs +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +3 -3
- package/dist/commands/telemetry/index.mjs +1 -1
- package/dist/{contract-at-errors-DlZHXSkI.mjs → contract-at-errors-CK3qoqZf.mjs} +2 -2
- package/dist/{contract-at-errors-DlZHXSkI.mjs.map → contract-at-errors-CK3qoqZf.mjs.map} +1 -1
- package/dist/{contract-emit-CaKp92-Q.mjs → contract-emit-DwlIz5Zg.mjs} +3 -3
- package/dist/{contract-emit-CaKp92-Q.mjs.map → contract-emit-DwlIz5Zg.mjs.map} +1 -1
- package/dist/{contract-emit-S53EyBRV.mjs → contract-emit-Dzf73HdD.mjs} +3 -3
- package/dist/{contract-emit-S53EyBRV.mjs.map → contract-emit-Dzf73HdD.mjs.map} +1 -1
- package/dist/{contract-infer-Cebb-_Qx.mjs → contract-infer-Bzh___GO.mjs} +3 -3
- package/dist/{contract-infer-Cebb-_Qx.mjs.map → contract-infer-Bzh___GO.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-Dvl1SJ4C.mjs → contract-space-aggregate-loader-5zmOENc4.mjs} +3 -3
- package/dist/{contract-space-aggregate-loader-Dvl1SJ4C.mjs.map → contract-space-aggregate-loader-5zmOENc4.mjs.map} +1 -1
- package/dist/{db-verify-B1OoWEWn.mjs → db-verify-CNz036sw.mjs} +4 -4
- package/dist/{db-verify-B1OoWEWn.mjs.map → db-verify-CNz036sw.mjs.map} +1 -1
- 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/init-output.mjs +1 -1
- package/dist/{framework-components-DCAT1uUC.mjs → framework-components-CyM_xYCY.mjs} +2 -2
- package/dist/{framework-components-DCAT1uUC.mjs.map → framework-components-CyM_xYCY.mjs.map} +1 -1
- package/dist/{global-flags-DG4uY5tV.d.mts → global-flags-DEHjV8_s.d.mts} +1 -1
- package/dist/{global-flags-DG4uY5tV.d.mts.map → global-flags-DEHjV8_s.d.mts.map} +1 -1
- package/dist/{init-Kf3T4A4W.mjs → init-DJsQpr_6.mjs} +4 -4
- package/dist/{init-Kf3T4A4W.mjs.map → init-DJsQpr_6.mjs.map} +1 -1
- package/dist/{inspect-live-schema-DTqflZ8X.mjs → inspect-live-schema-DE76Ou4D.mjs} +3 -3
- package/dist/{inspect-live-schema-DTqflZ8X.mjs.map → inspect-live-schema-DE76Ou4D.mjs.map} +1 -1
- package/dist/{migration-check-Ccyd0QKb.mjs → migration-check-CL2MzDRX.mjs} +2 -2
- package/dist/{migration-check-Ccyd0QKb.mjs.map → migration-check-CL2MzDRX.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-DI7_SFL0.mjs → migration-command-scaffold-194pA8F5.mjs} +3 -3
- package/dist/{migration-command-scaffold-DI7_SFL0.mjs.map → migration-command-scaffold-194pA8F5.mjs.map} +1 -1
- package/dist/{migration-graph-tree-render-DyDBuJEX.mjs → migration-graph-tree-render-CVmV9sWr.mjs} +1 -1
- package/dist/{migration-graph-tree-render-DyDBuJEX.mjs.map → migration-graph-tree-render-CVmV9sWr.mjs.map} +1 -1
- package/dist/{migration-list-types-DV9PBc7Z.d.mts → migration-list-types-DS63IdFd.d.mts} +1 -1
- package/dist/{migration-list-types-DV9PBc7Z.d.mts.map → migration-list-types-DS63IdFd.d.mts.map} +1 -1
- package/dist/{migration-log-Des4seHP.mjs → migration-log-CP6skD5b.mjs} +4 -4
- package/dist/{migration-log-Des4seHP.mjs.map → migration-log-CP6skD5b.mjs.map} +1 -1
- package/dist/{migration-plan-DxDTBzGS.mjs → migration-plan-D61N1hID.mjs} +5 -5
- package/dist/{migration-plan-DxDTBzGS.mjs.map → migration-plan-D61N1hID.mjs.map} +1 -1
- package/dist/{migration-status-CCwqA-vi.mjs → migration-status--ejfYqWS.mjs} +5 -5
- package/dist/{migration-status-CCwqA-vi.mjs.map → migration-status--ejfYqWS.mjs.map} +1 -1
- package/dist/{migration-types-CAQ-0TEE.d.mts → migration-types-D2FW63pr.d.mts} +1 -1
- package/dist/{migration-types-CAQ-0TEE.d.mts.map → migration-types-D2FW63pr.d.mts.map} +1 -1
- package/dist/{output-CF_hqzI-.mjs → output-B60Gw5fu.mjs} +1 -1
- package/dist/{output-CF_hqzI-.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
- package/dist/{ref-advancement-DUZqsue6.mjs → ref-advancement-V1o-9LVK.mjs} +1 -1
- package/dist/{ref-advancement-DUZqsue6.mjs.map → ref-advancement-V1o-9LVK.mjs.map} +1 -1
- package/dist/{telemetry-LFFQmqHd.mjs → telemetry-CnfdMrpv.mjs} +2 -2
- package/dist/{telemetry-LFFQmqHd.mjs.map → telemetry-CnfdMrpv.mjs.map} +1 -1
- package/dist/{terminal-ui-C3xGyxW-.d.mts → terminal-ui-5Y6mrg93.d.mts} +1 -1
- package/dist/{terminal-ui-C3xGyxW-.d.mts.map → terminal-ui-5Y6mrg93.d.mts.map} +1 -1
- package/dist/{types-BdS8PoKM.d.mts → types-BYwWOyYJ.d.mts} +5 -1
- package/dist/types-BYwWOyYJ.d.mts.map +1 -0
- package/dist/{verify-C0TARc6h.mjs → verify-By66Zu3y.mjs} +2 -2
- package/dist/{verify-C0TARc6h.mjs.map → verify-By66Zu3y.mjs.map} +1 -1
- package/package.json +11 -11
- package/dist/client-V7BkIQrQ.mjs.map +0 -1
- package/dist/command-helpers-DlrUCI7s.mjs.map +0 -1
- package/dist/migrations-B3H6RTXb.mjs +0 -228
- package/dist/migrations-B3H6RTXb.mjs.map +0 -1
- package/dist/types-BdS8PoKM.d.mts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-init.mjs","names":[],"sources":["../../src/commands/db-init.ts"],"sourcesContent":["import { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { ContractValidationError } from '../control-api/errors';\nimport type { DbInitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorMigrationPlanningFailed,\n errorRunnerFailed,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport type { MigrationCommandOptions } from '../utils/command-helpers';\nimport {\n resolveMigrationPaths,\n sanitizeErrorMessage,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport {\n formatMigrationApplyOutput,\n formatMigrationJson,\n formatMigrationPlanOutput,\n type MigrationCommandResult,\n} from '../utils/formatters/migrations';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport {\n addMigrationCommandOptions,\n prepareMigrationContext,\n} from '../utils/migration-command-scaffold';\nimport {\n buildRefAdvancementFields,\n computeRefAdvancementName,\n type RefAdvancementFields,\n readContractIR,\n} from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface DbInitOptions extends MigrationCommandOptions {\n readonly advanceRef?: string;\n}\n\n/**\n * Maps a DbInitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapDbInitFailure(failure: DbInitFailure): CliStructuredError {\n if (failure.code === 'PLANNING_FAILED') {\n return errorMigrationPlanningFailed({ conflicts: failure.conflicts ?? [] });\n }\n\n if (failure.code === 'MARKER_ORIGIN_MISMATCH') {\n const mismatchParts: string[] = [];\n if (\n failure.marker?.storageHash !== failure.destination?.storageHash &&\n failure.marker?.storageHash &&\n failure.destination?.storageHash\n ) {\n mismatchParts.push(\n `storageHash (marker: ${failure.marker.storageHash}, destination: ${failure.destination.storageHash})`,\n );\n }\n if (\n failure.marker?.profileHash !== failure.destination?.profileHash &&\n failure.marker?.profileHash &&\n failure.destination?.profileHash\n ) {\n mismatchParts.push(\n `profileHash (marker: ${failure.marker.profileHash}, destination: ${failure.destination.profileHash})`,\n );\n }\n\n return errorRuntime(\n `Existing database signature does not match plan destination.${mismatchParts.length > 0 ? ` Mismatch in ${mismatchParts.join(' and ')}.` : ''}`,\n {\n why: 'Database has an existing signature (marker) that does not match the target contract',\n fix: 'If bootstrapping, drop/reset the database then re-run `prisma-next db init`; otherwise reconcile schema/marker using your migration workflow',\n meta: {\n code: 'MARKER_ORIGIN_MISMATCH',\n ...ifDefined('markerStorageHash', failure.marker?.storageHash),\n ...ifDefined('destinationStorageHash', failure.destination?.storageHash),\n ...ifDefined('markerProfileHash', failure.marker?.profileHash),\n ...ifDefined('destinationProfileHash', failure.destination?.profileHash),\n },\n },\n );\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n const runnerCode =\n typeof failure.meta?.['runnerErrorCode'] === 'string'\n ? failure.meta['runnerErrorCode']\n : undefined;\n const fix =\n runnerCode === 'LEGACY_MARKER_SHAPE'\n ? 'Legacy marker-table shape detected. Drop `prisma_contract.marker` (Postgres) or `_prisma_marker` (SQLite) and re-run `prisma-next db init` to recreate it with the current per-space schema.'\n : 'Fix the schema mismatch (db init is additive-only), or drop/reset the database and re-run `prisma-next db init`';\n return errorRunnerFailed(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix,\n ...(failure.meta\n ? { meta: { code: 'RUNNER_FAILED', ...failure.meta } }\n : { meta: { code: 'RUNNER_FAILED' } }),\n });\n }\n\n // Exhaustive check - TypeScript will error if a new code is added but not handled\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled DbInitFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the db init command and returns a structured Result.\n */\nasync function executeDbInitCommand(\n options: DbInitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrationCommandResult, CliStructuredError>> {\n // Prepare shared migration context (config, contract, connection, client)\n const ctxResult = await prepareMigrationContext(options, flags, ui, {\n commandName: 'db init',\n description: 'Bootstrap a database to match the current contract',\n url: 'https://pris.ly/db-init',\n });\n if (!ctxResult.ok) {\n return ctxResult;\n }\n const { client, config, contractJson, dbConnection, onProgress, contractPathAbsolute } =\n ctxResult.value;\n\n // The aggregate loader (loader → planner → runner pipeline) catches\n // layout / drift / disjointness violations on its own; the legacy\n // per-space precheck + marker-check helpers are no longer needed at\n // this surface. Marker-vs-on-disk drift surfaces through the planner's\n // graph-walk strategy.\n const { migrationsDir, refsDir } = resolveMigrationPaths(options.config, config);\n\n try {\n await client.connect(dbConnection);\n\n const result = await client.dbInit({\n contract: contractJson,\n mode: options.dryRun ? 'plan' : 'apply',\n migrationsDir,\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapDbInitFailure(result.failure));\n }\n\n const advancementHash =\n result.value.mode === 'apply'\n ? (result.value.marker?.storageHash ?? result.value.destination.storageHash)\n : result.value.destination.storageHash;\n\n let refAdvancementFields: RefAdvancementFields = {\n advancedRef: null,\n plannedAdvanceRef: null,\n };\n if (\n computeRefAdvancementName({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n }) !== null\n ) {\n try {\n const contractIR = await readContractIR(contractJson, contractPathAbsolute);\n refAdvancementFields = await buildRefAdvancementFields({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n refsDir,\n contractIR,\n mode: result.value.mode,\n hash: advancementHash,\n });\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n // Convert success result to CLI output format\n const dbInitResult: MigrationCommandResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: ctxResult.value.config.target.targetId,\n destination: {\n storageHash: result.value.destination.storageHash,\n ...ifDefined('profileHash', result.value.destination.profileHash),\n },\n operations: result.value.plan.operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n ...ifDefined('preview', result.value.plan.preview),\n },\n ...(result.value.execution\n ? {\n execution: {\n operationsPlanned: result.value.execution.operationsPlanned,\n operationsExecuted: result.value.execution.operationsExecuted,\n },\n }\n : {}),\n ...(result.value.marker\n ? {\n marker: {\n storageHash: result.value.marker.storageHash,\n ...ifDefined('profileHash', result.value.marker.profileHash),\n },\n }\n : {}),\n ...ifDefined('perSpace', result.value.perSpace),\n advancedRef: refAdvancementFields.advancedRef,\n plannedAdvanceRef: refAdvancementFields.plannedAdvanceRef,\n summary: result.value.summary,\n timings: { total: Date.now() - startTime },\n };\n\n return ok(dbInitResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during db init: ${safeMessage}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbInitCommand(): Command {\n const command = new Command('init');\n setCommandDescriptions(\n command,\n 'Bootstrap a database to match the current contract and sign it',\n 'Initializes a database to match your emitted contract using additive-only operations.\\n' +\n 'Creates any missing tables, columns, indexes, and constraints defined in your contract.\\n' +\n 'Leaves existing compatible structures in place, surfaces conflicts when destructive changes\\n' +\n 'would be required, and signs the database to track contract state. Use --dry-run to\\n' +\n 'preview changes without applying.',\n );\n setCommandExamples(command, [\n 'prisma-next db init --db $DATABASE_URL',\n 'prisma-next db init --db $DATABASE_URL --dry-run',\n ]);\n addMigrationCommandOptions(command);\n command.option('--advance-ref <name>', 'Ref to advance to the post-command contract hash');\n command.action(async (options: DbInitOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n const result = await executeDbInitCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (dbInitResult) => {\n if (flags.json) {\n ui.output(formatMigrationJson(dbInitResult));\n } else {\n const output =\n dbInitResult.mode === 'plan'\n ? formatMigrationPlanOutput(dbInitResult, flags)\n : formatMigrationApplyOutput(dbInitResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"db-init.mjs","names":[],"sources":["../../src/commands/db-init.ts"],"sourcesContent":["import { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { ContractValidationError } from '../control-api/errors';\nimport type { DbInitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorMigrationPlanningFailed,\n errorRunnerFailed,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport type { MigrationCommandOptions } from '../utils/command-helpers';\nimport {\n resolveMigrationPaths,\n sanitizeErrorMessage,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport {\n formatMigrationApplyOutput,\n formatMigrationJson,\n formatMigrationPlanOutput,\n type MigrationCommandResult,\n} from '../utils/formatters/migrations';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport {\n addMigrationCommandOptions,\n prepareMigrationContext,\n} from '../utils/migration-command-scaffold';\nimport {\n buildRefAdvancementFields,\n computeRefAdvancementName,\n type RefAdvancementFields,\n readContractIR,\n} from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface DbInitOptions extends MigrationCommandOptions {\n readonly advanceRef?: string;\n}\n\n/**\n * Maps a DbInitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapDbInitFailure(failure: DbInitFailure): CliStructuredError {\n if (failure.code === 'PLANNING_FAILED') {\n return errorMigrationPlanningFailed({ conflicts: failure.conflicts ?? [] });\n }\n\n if (failure.code === 'MARKER_ORIGIN_MISMATCH') {\n const mismatchParts: string[] = [];\n if (\n failure.marker?.storageHash !== failure.destination?.storageHash &&\n failure.marker?.storageHash &&\n failure.destination?.storageHash\n ) {\n mismatchParts.push(\n `storageHash (marker: ${failure.marker.storageHash}, destination: ${failure.destination.storageHash})`,\n );\n }\n if (\n failure.marker?.profileHash !== failure.destination?.profileHash &&\n failure.marker?.profileHash &&\n failure.destination?.profileHash\n ) {\n mismatchParts.push(\n `profileHash (marker: ${failure.marker.profileHash}, destination: ${failure.destination.profileHash})`,\n );\n }\n\n return errorRuntime(\n `Existing database signature does not match plan destination.${mismatchParts.length > 0 ? ` Mismatch in ${mismatchParts.join(' and ')}.` : ''}`,\n {\n why: 'Database has an existing signature (marker) that does not match the target contract',\n fix: 'If bootstrapping, drop/reset the database then re-run `prisma-next db init`; otherwise reconcile schema/marker using your migration workflow',\n meta: {\n code: 'MARKER_ORIGIN_MISMATCH',\n ...ifDefined('markerStorageHash', failure.marker?.storageHash),\n ...ifDefined('destinationStorageHash', failure.destination?.storageHash),\n ...ifDefined('markerProfileHash', failure.marker?.profileHash),\n ...ifDefined('destinationProfileHash', failure.destination?.profileHash),\n },\n },\n );\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n const runnerCode =\n typeof failure.meta?.['runnerErrorCode'] === 'string'\n ? failure.meta['runnerErrorCode']\n : undefined;\n const fix =\n runnerCode === 'LEGACY_MARKER_SHAPE'\n ? 'Legacy marker-table shape detected. Drop `prisma_contract.marker` (Postgres) or `_prisma_marker` (SQLite) and re-run `prisma-next db init` to recreate it with the current per-space schema.'\n : 'Fix the schema mismatch (db init is additive-only), or drop/reset the database and re-run `prisma-next db init`';\n return errorRunnerFailed(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix,\n ...(failure.meta\n ? { meta: { code: 'RUNNER_FAILED', ...failure.meta } }\n : { meta: { code: 'RUNNER_FAILED' } }),\n });\n }\n\n // Exhaustive check - TypeScript will error if a new code is added but not handled\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled DbInitFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the db init command and returns a structured Result.\n */\nasync function executeDbInitCommand(\n options: DbInitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrationCommandResult, CliStructuredError>> {\n // Prepare shared migration context (config, contract, connection, client)\n const ctxResult = await prepareMigrationContext(options, flags, ui, {\n commandName: 'db init',\n description: 'Bootstrap a database to match the current contract',\n url: 'https://pris.ly/db-init',\n });\n if (!ctxResult.ok) {\n return ctxResult;\n }\n const { client, config, contractJson, dbConnection, onProgress, contractPathAbsolute } =\n ctxResult.value;\n\n // The aggregate loader (loader → planner → runner pipeline) catches\n // layout / drift / disjointness violations on its own; the legacy\n // per-space precheck + marker-check helpers are no longer needed at\n // this surface. Marker-vs-on-disk drift surfaces through the planner's\n // graph-walk strategy.\n const { migrationsDir, refsDir } = resolveMigrationPaths(options.config, config);\n\n try {\n await client.connect(dbConnection);\n\n const result = await client.dbInit({\n contract: contractJson,\n mode: options.dryRun ? 'plan' : 'apply',\n migrationsDir,\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapDbInitFailure(result.failure));\n }\n\n const advancementHash =\n result.value.mode === 'apply'\n ? (result.value.marker?.storageHash ?? result.value.destination.storageHash)\n : result.value.destination.storageHash;\n\n let refAdvancementFields: RefAdvancementFields = {\n advancedRef: null,\n plannedAdvanceRef: null,\n };\n if (\n computeRefAdvancementName({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n }) !== null\n ) {\n try {\n const contractIR = await readContractIR(contractJson, contractPathAbsolute);\n refAdvancementFields = await buildRefAdvancementFields({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n refsDir,\n contractIR,\n mode: result.value.mode,\n hash: advancementHash,\n });\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n // Convert success result to CLI output format\n const dbInitResult: MigrationCommandResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: ctxResult.value.config.target.targetId,\n destination: {\n storageHash: result.value.destination.storageHash,\n ...ifDefined('profileHash', result.value.destination.profileHash),\n },\n operations: result.value.plan.operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n ...ifDefined('preview', result.value.plan.preview),\n },\n ...(result.value.execution\n ? {\n execution: {\n operationsPlanned: result.value.execution.operationsPlanned,\n operationsExecuted: result.value.execution.operationsExecuted,\n },\n }\n : {}),\n ...(result.value.marker\n ? {\n marker: {\n storageHash: result.value.marker.storageHash,\n ...ifDefined('profileHash', result.value.marker.profileHash),\n },\n }\n : {}),\n ...ifDefined('perSpace', result.value.perSpace),\n advancedRef: refAdvancementFields.advancedRef,\n plannedAdvanceRef: refAdvancementFields.plannedAdvanceRef,\n summary: result.value.summary,\n timings: { total: Date.now() - startTime },\n };\n\n return ok(dbInitResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during db init: ${safeMessage}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbInitCommand(): Command {\n const command = new Command('init');\n setCommandDescriptions(\n command,\n 'Bootstrap a database to match the current contract and sign it',\n 'Initializes a database to match your emitted contract using additive-only operations.\\n' +\n 'Creates any missing tables, columns, indexes, and constraints defined in your contract.\\n' +\n 'Leaves existing compatible structures in place, surfaces conflicts when destructive changes\\n' +\n 'would be required, and signs the database to track contract state. Use --dry-run to\\n' +\n 'preview changes without applying.',\n );\n setCommandExamples(command, [\n 'prisma-next db init --db $DATABASE_URL',\n 'prisma-next db init --db $DATABASE_URL --dry-run',\n ]);\n addMigrationCommandOptions(command);\n command.option('--advance-ref <name>', 'Ref to advance to the post-command contract hash');\n command.action(async (options: DbInitOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n const result = await executeDbInitCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (dbInitResult) => {\n if (flags.json) {\n ui.output(formatMigrationJson(dbInitResult));\n } else {\n const output =\n dbInitResult.mode === 'plan'\n ? formatMigrationPlanOutput(dbInitResult, flags)\n : formatMigrationApplyOutput(dbInitResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as createTerminalUI, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "../command-helpers-
|
|
2
|
-
import { t as inspectLiveSchema } from "../inspect-live-schema-
|
|
3
|
-
import { n as formatIntrospectOutput, t as formatIntrospectJson } from "../verify-
|
|
1
|
+
import { _ as createTerminalUI, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "../command-helpers-D7TK5Y9e.mjs";
|
|
2
|
+
import { t as inspectLiveSchema } from "../inspect-live-schema-DE76Ou4D.mjs";
|
|
3
|
+
import { n as formatIntrospectOutput, t as formatIntrospectJson } from "../verify-By66Zu3y.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
//#region src/commands/db-schema.ts
|
|
6
6
|
function toIntrospectSchemaResult(result) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as formatStyledHeader, B as errorDatabaseConnectionRequired, F as CliStructuredError, H as errorDriverRequired, U as errorFileNotFound, _ as createTerminalUI, ct as mapRefResolutionError, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, l as setCommandDescriptions, o as resolveContractPath, ot as errorUnexpected, s as resolveMigrationPaths, st as mapMigrationToolsError, t as addGlobalOptions, tt as errorRuntime, u as setCommandExamples, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-D7TK5Y9e.mjs";
|
|
3
3
|
import { t as createProgressAdapter } from "../progress-adapter-C644QK8l.mjs";
|
|
4
|
-
import { a as ContractValidationError, t as createControlClient } from "../client-
|
|
5
|
-
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-
|
|
6
|
-
import { a as formatSignJson, i as formatSchemaVerifyOutput, o as formatSignOutput, r as formatSchemaVerifyJson } from "../verify-
|
|
4
|
+
import { a as ContractValidationError, t as createControlClient } from "../client-nygCs15r.mjs";
|
|
5
|
+
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-5zmOENc4.mjs";
|
|
6
|
+
import { a as formatSignJson, i as formatSchemaVerifyOutput, o as formatSignOutput, r as formatSchemaVerifyJson } from "../verify-By66Zu3y.mjs";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
9
9
|
import { join, relative, resolve } from "pathe";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-update.d.mts","names":[],"sources":["../../src/commands/db-update.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"db-update.d.mts","names":[],"sources":["../../src/commands/db-update.ts"],"mappings":";;;iBAuRgB,qBAAA,CAAA,GAAyB,OAAO"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as ContractValidationError } from "../client-
|
|
3
|
-
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import { i as readContractIR, n as computeRefAdvancementName, t as buildRefAdvancementFields } from "../ref-advancement-DUZqsue6.mjs";
|
|
1
|
+
import { C as formatMigrationApplyOutput, F as CliStructuredError, I as ERROR_CODE_DESTRUCTIVE_CHANGES, J as errorMigrationPlanningFailed, T as formatMigrationPlanOutput, V as errorDestructiveChanges, _ as createTerminalUI, c as sanitizeErrorMessage, ct as mapRefResolutionError, et as errorRunnerFailed, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, ot as errorUnexpected, s as resolveMigrationPaths, st as mapMigrationToolsError, u as setCommandExamples, w as formatMigrationJson, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-D7TK5Y9e.mjs";
|
|
2
|
+
import { a as ContractValidationError } from "../client-nygCs15r.mjs";
|
|
3
|
+
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-5zmOENc4.mjs";
|
|
4
|
+
import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-194pA8F5.mjs";
|
|
5
|
+
import { i as readContractIR, n as computeRefAdvancementName, t as buildRefAdvancementFields } from "../ref-advancement-V1o-9LVK.mjs";
|
|
7
6
|
import { Command } from "commander";
|
|
8
7
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
9
8
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -22,7 +21,10 @@ function mapDbUpdateFailure(failure) {
|
|
|
22
21
|
return errorRunnerFailed(failure.summary, {
|
|
23
22
|
why: failure.why ?? "Migration runner failed",
|
|
24
23
|
fix,
|
|
25
|
-
|
|
24
|
+
meta: {
|
|
25
|
+
...failure.meta,
|
|
26
|
+
...failure.warnings && failure.warnings.length > 0 ? { plannerWarnings: failure.warnings } : {}
|
|
27
|
+
}
|
|
26
28
|
});
|
|
27
29
|
}
|
|
28
30
|
if (failure.code === "DESTRUCTIVE_CHANGES") return errorDestructiveChanges(failure.summary, {
|
|
@@ -130,6 +132,7 @@ async function executeDbUpdateCommand(options, flags, ui, startTime) {
|
|
|
130
132
|
...ifDefined("profileHash", result.value.marker.profileHash)
|
|
131
133
|
} : void 0),
|
|
132
134
|
...ifDefined("perSpace", result.value.perSpace),
|
|
135
|
+
...ifDefined("warnings", result.value.warnings),
|
|
133
136
|
advancedRef: refAdvancementFields.advancedRef,
|
|
134
137
|
plannedAdvanceRef: refAdvancementFields.plannedAdvanceRef,
|
|
135
138
|
summary: result.value.summary,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-update.mjs","names":[],"sources":["../../src/commands/db-update.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join } from 'pathe';\nimport { ContractValidationError } from '../control-api/errors';\nimport type { DbUpdateFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n ERROR_CODE_DESTRUCTIVE_CHANGES,\n errorContractValidationFailed,\n errorDestructiveChanges,\n errorMigrationPlanningFailed,\n errorRunnerFailed,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport type { MigrationCommandOptions } from '../utils/command-helpers';\nimport {\n resolveMigrationPaths,\n sanitizeErrorMessage,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { buildReadAggregate } from '../utils/contract-space-aggregate-loader';\nimport {\n formatMigrationApplyOutput,\n formatMigrationJson,\n formatMigrationPlanOutput,\n type MigrationCommandResult,\n} from '../utils/formatters/migrations';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport {\n addMigrationCommandOptions,\n prepareMigrationContext,\n} from '../utils/migration-command-scaffold';\nimport {\n buildRefAdvancementFields,\n computeRefAdvancementName,\n type RefAdvancementFields,\n readContractIR,\n} from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface DbUpdateOptions extends MigrationCommandOptions {\n readonly to?: string;\n readonly advanceRef?: string;\n}\n\n/**\n * Maps a DbUpdateFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapDbUpdateFailure(failure: DbUpdateFailure): CliStructuredError {\n if (failure.code === 'PLANNING_FAILED') {\n return errorMigrationPlanningFailed({ conflicts: failure.conflicts ?? [] });\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n const runnerCode =\n typeof failure.meta?.['runnerErrorCode'] === 'string'\n ? failure.meta['runnerErrorCode']\n : undefined;\n const fix =\n runnerCode === 'LEGACY_MARKER_SHAPE'\n ? 'Legacy marker-table shape detected. Drop `prisma_contract.marker` (Postgres) or `_prisma_marker` (SQLite) and re-run `prisma-next db init` to recreate it with the current per-space schema.'\n : 'Inspect the reported conflict, reconcile schema drift if needed, then re-run `prisma-next db update`';\n return errorRunnerFailed(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix,\n ...ifDefined('meta', failure.meta),\n });\n }\n\n if (failure.code === 'DESTRUCTIVE_CHANGES') {\n return errorDestructiveChanges(failure.summary, {\n ...ifDefined('why', failure.why),\n fix: 'Re-run with `-y` to apply destructive changes, or use `--dry-run` to preview first',\n ...ifDefined('meta', failure.meta),\n });\n }\n\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled DbUpdateFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the db update command and returns a structured Result.\n */\nasync function executeDbUpdateCommand(\n options: DbUpdateOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrationCommandResult, CliStructuredError>> {\n // Prepare shared migration context (config, contract, connection, client)\n const ctxResult = await prepareMigrationContext(options, flags, ui, {\n commandName: 'db update',\n description: 'Update your database schema to match your contract',\n url: 'https://pris.ly/db-update',\n });\n if (!ctxResult.ok) {\n return ctxResult;\n }\n const { client, config, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;\n let { contractJson } = ctxResult.value;\n let contractJsonPathForSnapshot = contractPathAbsolute;\n const { migrationsDir, refsDir } = resolveMigrationPaths(options.config, config);\n\n if (options.to) {\n try {\n const loaded = await buildReadAggregate(config, { migrationsDir });\n if (!loaded.ok) {\n return notOk(loaded.failure);\n }\n const graph = loaded.value.aggregate.app.graph();\n const bundles = loaded.value.aggregate.app.packages;\n const refs = loaded.value.aggregate.app.refs;\n const refResult = parseContractRef(options.to, { graph, refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n const targetHash = refResult.value.hash;\n const matchingBundle = bundles.find((p) => p.metadata.to === targetHash);\n if (!matchingBundle) {\n return notOk(\n errorUnexpected(\n `No migration bundle found for --to \"${options.to}\" (resolved hash: ${targetHash})`,\n {\n why: `The ref resolved successfully but no on-disk migration package has an end-contract hash matching ${targetHash}.`,\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 const endContractPath = join(matchingBundle.dirPath, 'end-contract.json');\n const raw = await readFile(endContractPath, 'utf-8');\n contractJson = JSON.parse(raw) as Record<string, unknown>;\n contractJsonPathForSnapshot = endContractPath;\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n throw error;\n }\n }\n\n try {\n await client.connect(dbConnection);\n\n const result = await client.dbUpdate({\n contract: contractJson,\n mode: options.dryRun ? 'plan' : 'apply',\n migrationsDir,\n ...(flags.yes ? { acceptDataLoss: true } : {}),\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapDbUpdateFailure(result.failure));\n }\n\n const advancementHash =\n result.value.mode === 'apply'\n ? (result.value.marker?.storageHash ?? result.value.destination.storageHash)\n : result.value.destination.storageHash;\n\n let refAdvancementFields: RefAdvancementFields = {\n advancedRef: null,\n plannedAdvanceRef: null,\n };\n if (\n computeRefAdvancementName({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n }) !== null\n ) {\n try {\n const contractIR = await readContractIR(contractJson, contractJsonPathForSnapshot);\n refAdvancementFields = await buildRefAdvancementFields({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n refsDir,\n contractIR,\n mode: result.value.mode,\n hash: advancementHash,\n });\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n // Convert success result to CLI output format\n const dbUpdateResult: MigrationCommandResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: ctxResult.value.config.target.targetId,\n destination: {\n storageHash: result.value.destination.storageHash,\n ...ifDefined('profileHash', result.value.destination.profileHash),\n },\n operations: result.value.plan.operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n ...ifDefined('preview', result.value.plan.preview),\n },\n ...ifDefined(\n 'execution',\n result.value.execution\n ? {\n operationsPlanned: result.value.execution.operationsPlanned,\n operationsExecuted: result.value.execution.operationsExecuted,\n }\n : undefined,\n ),\n ...ifDefined(\n 'marker',\n result.value.marker\n ? {\n storageHash: result.value.marker.storageHash,\n ...ifDefined('profileHash', result.value.marker.profileHash),\n }\n : undefined,\n ),\n ...ifDefined('perSpace', result.value.perSpace),\n advancedRef: refAdvancementFields.advancedRef,\n plannedAdvanceRef: refAdvancementFields.plannedAdvanceRef,\n summary: result.value.summary,\n timings: { total: Date.now() - startTime },\n };\n\n return ok(dbUpdateResult);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during db update: ${safeMessage}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbUpdateCommand(): Command {\n const command = new Command('update');\n setCommandDescriptions(\n command,\n 'Update your database schema to match your contract',\n 'Compares your database schema to the emitted contract and applies the necessary\\n' +\n 'changes. Works on any database, whether or not it has been initialized with `db init`.\\n' +\n 'Destructive operations prompt for confirmation in interactive mode. Use -y to\\n' +\n 'auto-accept or --dry-run to preview first.',\n );\n setCommandExamples(command, [\n 'prisma-next db update --db $DATABASE_URL',\n 'prisma-next db update --db $DATABASE_URL --dry-run',\n ]);\n addMigrationCommandOptions(command);\n command.option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n );\n command.option('--advance-ref <name>', 'Ref to advance to the post-command contract hash');\n command.action(async (options: DbUpdateOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n let result = await executeDbUpdateCommand(options, flags, ui, startTime);\n\n // Interactive confirmation for destructive operations:\n // When the control API rejects destructive changes, prompt the user instead of failing.\n // In non-interactive mode (CI, piped, --no-interactive, --json), the error is returned as-is.\n if (\n !result.ok &&\n result.failure.code === ERROR_CODE_DESTRUCTIVE_CHANGES &&\n flags.interactive &&\n !flags.json &&\n !flags.yes\n ) {\n const meta = result.failure.meta as\n | { destructiveOperations?: readonly { id: string; label: string }[] }\n | undefined;\n const destructiveOps = meta?.destructiveOperations ?? [];\n\n if (destructiveOps.length > 0) {\n ui.warn(\n `${destructiveOps.length} destructive operation(s) that may cause data loss:\\n${destructiveOps.map((op) => ` ${ui.yellow('▸')} ${op.label}`).join('\\n')}`,\n );\n }\n\n const confirmed = await ui.confirm('Apply destructive changes? This cannot be undone.');\n\n if (confirmed) {\n result = await executeDbUpdateCommand(options, { ...flags, yes: true }, ui, Date.now());\n }\n }\n\n const exitCode = handleResult(result, flags, ui, (dbUpdateResult) => {\n if (flags.json) {\n ui.output(formatMigrationJson(dbUpdateResult));\n } else {\n const output =\n dbUpdateResult.mode === 'plan'\n ? formatMigrationPlanOutput(dbUpdateResult, flags)\n : formatMigrationApplyOutput(dbUpdateResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"db-update.mjs","names":[],"sources":["../../src/commands/db-update.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join } from 'pathe';\nimport { ContractValidationError } from '../control-api/errors';\nimport type { DbUpdateFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n ERROR_CODE_DESTRUCTIVE_CHANGES,\n errorContractValidationFailed,\n errorDestructiveChanges,\n errorMigrationPlanningFailed,\n errorRunnerFailed,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport type { MigrationCommandOptions } from '../utils/command-helpers';\nimport {\n resolveMigrationPaths,\n sanitizeErrorMessage,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { buildReadAggregate } from '../utils/contract-space-aggregate-loader';\nimport {\n formatMigrationApplyOutput,\n formatMigrationJson,\n formatMigrationPlanOutput,\n type MigrationCommandResult,\n} from '../utils/formatters/migrations';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport {\n addMigrationCommandOptions,\n prepareMigrationContext,\n} from '../utils/migration-command-scaffold';\nimport {\n buildRefAdvancementFields,\n computeRefAdvancementName,\n type RefAdvancementFields,\n readContractIR,\n} from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface DbUpdateOptions extends MigrationCommandOptions {\n readonly to?: string;\n readonly advanceRef?: string;\n}\n\n/**\n * Maps a DbUpdateFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapDbUpdateFailure(failure: DbUpdateFailure): CliStructuredError {\n if (failure.code === 'PLANNING_FAILED') {\n return errorMigrationPlanningFailed({ conflicts: failure.conflicts ?? [] });\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n const runnerCode =\n typeof failure.meta?.['runnerErrorCode'] === 'string'\n ? failure.meta['runnerErrorCode']\n : undefined;\n const fix =\n runnerCode === 'LEGACY_MARKER_SHAPE'\n ? 'Legacy marker-table shape detected. Drop `prisma_contract.marker` (Postgres) or `_prisma_marker` (SQLite) and re-run `prisma-next db init` to recreate it with the current per-space schema.'\n : 'Inspect the reported conflict, reconcile schema drift if needed, then re-run `prisma-next db update`';\n return errorRunnerFailed(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix,\n meta: {\n ...failure.meta,\n ...(failure.warnings && failure.warnings.length > 0\n ? { plannerWarnings: failure.warnings }\n : {}),\n },\n });\n }\n\n if (failure.code === 'DESTRUCTIVE_CHANGES') {\n return errorDestructiveChanges(failure.summary, {\n ...ifDefined('why', failure.why),\n fix: 'Re-run with `-y` to apply destructive changes, or use `--dry-run` to preview first',\n ...ifDefined('meta', failure.meta),\n });\n }\n\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled DbUpdateFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the db update command and returns a structured Result.\n */\nasync function executeDbUpdateCommand(\n options: DbUpdateOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrationCommandResult, CliStructuredError>> {\n // Prepare shared migration context (config, contract, connection, client)\n const ctxResult = await prepareMigrationContext(options, flags, ui, {\n commandName: 'db update',\n description: 'Update your database schema to match your contract',\n url: 'https://pris.ly/db-update',\n });\n if (!ctxResult.ok) {\n return ctxResult;\n }\n const { client, config, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;\n let { contractJson } = ctxResult.value;\n let contractJsonPathForSnapshot = contractPathAbsolute;\n const { migrationsDir, refsDir } = resolveMigrationPaths(options.config, config);\n\n if (options.to) {\n try {\n const loaded = await buildReadAggregate(config, { migrationsDir });\n if (!loaded.ok) {\n return notOk(loaded.failure);\n }\n const graph = loaded.value.aggregate.app.graph();\n const bundles = loaded.value.aggregate.app.packages;\n const refs = loaded.value.aggregate.app.refs;\n const refResult = parseContractRef(options.to, { graph, refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n const targetHash = refResult.value.hash;\n const matchingBundle = bundles.find((p) => p.metadata.to === targetHash);\n if (!matchingBundle) {\n return notOk(\n errorUnexpected(\n `No migration bundle found for --to \"${options.to}\" (resolved hash: ${targetHash})`,\n {\n why: `The ref resolved successfully but no on-disk migration package has an end-contract hash matching ${targetHash}.`,\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 const endContractPath = join(matchingBundle.dirPath, 'end-contract.json');\n const raw = await readFile(endContractPath, 'utf-8');\n contractJson = JSON.parse(raw) as Record<string, unknown>;\n contractJsonPathForSnapshot = endContractPath;\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n throw error;\n }\n }\n\n try {\n await client.connect(dbConnection);\n\n const result = await client.dbUpdate({\n contract: contractJson,\n mode: options.dryRun ? 'plan' : 'apply',\n migrationsDir,\n ...(flags.yes ? { acceptDataLoss: true } : {}),\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapDbUpdateFailure(result.failure));\n }\n\n const advancementHash =\n result.value.mode === 'apply'\n ? (result.value.marker?.storageHash ?? result.value.destination.storageHash)\n : result.value.destination.storageHash;\n\n let refAdvancementFields: RefAdvancementFields = {\n advancedRef: null,\n plannedAdvanceRef: null,\n };\n if (\n computeRefAdvancementName({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n }) !== null\n ) {\n try {\n const contractIR = await readContractIR(contractJson, contractJsonPathForSnapshot);\n refAdvancementFields = await buildRefAdvancementFields({\n ...ifDefined('advanceRef', options.advanceRef),\n ...ifDefined('db', options.db),\n refsDir,\n contractIR,\n mode: result.value.mode,\n hash: advancementHash,\n });\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n // Convert success result to CLI output format\n const dbUpdateResult: MigrationCommandResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: ctxResult.value.config.target.targetId,\n destination: {\n storageHash: result.value.destination.storageHash,\n ...ifDefined('profileHash', result.value.destination.profileHash),\n },\n operations: result.value.plan.operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n ...ifDefined('preview', result.value.plan.preview),\n },\n ...ifDefined(\n 'execution',\n result.value.execution\n ? {\n operationsPlanned: result.value.execution.operationsPlanned,\n operationsExecuted: result.value.execution.operationsExecuted,\n }\n : undefined,\n ),\n ...ifDefined(\n 'marker',\n result.value.marker\n ? {\n storageHash: result.value.marker.storageHash,\n ...ifDefined('profileHash', result.value.marker.profileHash),\n }\n : undefined,\n ),\n ...ifDefined('perSpace', result.value.perSpace),\n ...ifDefined('warnings', result.value.warnings),\n advancedRef: refAdvancementFields.advancedRef,\n plannedAdvanceRef: refAdvancementFields.plannedAdvanceRef,\n summary: result.value.summary,\n timings: { total: Date.now() - startTime },\n };\n\n return ok(dbUpdateResult);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during db update: ${safeMessage}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbUpdateCommand(): Command {\n const command = new Command('update');\n setCommandDescriptions(\n command,\n 'Update your database schema to match your contract',\n 'Compares your database schema to the emitted contract and applies the necessary\\n' +\n 'changes. Works on any database, whether or not it has been initialized with `db init`.\\n' +\n 'Destructive operations prompt for confirmation in interactive mode. Use -y to\\n' +\n 'auto-accept or --dry-run to preview first.',\n );\n setCommandExamples(command, [\n 'prisma-next db update --db $DATABASE_URL',\n 'prisma-next db update --db $DATABASE_URL --dry-run',\n ]);\n addMigrationCommandOptions(command);\n command.option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n );\n command.option('--advance-ref <name>', 'Ref to advance to the post-command contract hash');\n command.action(async (options: DbUpdateOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n let result = await executeDbUpdateCommand(options, flags, ui, startTime);\n\n // Interactive confirmation for destructive operations:\n // When the control API rejects destructive changes, prompt the user instead of failing.\n // In non-interactive mode (CI, piped, --no-interactive, --json), the error is returned as-is.\n if (\n !result.ok &&\n result.failure.code === ERROR_CODE_DESTRUCTIVE_CHANGES &&\n flags.interactive &&\n !flags.json &&\n !flags.yes\n ) {\n const meta = result.failure.meta as\n | { destructiveOperations?: readonly { id: string; label: string }[] }\n | undefined;\n const destructiveOps = meta?.destructiveOperations ?? [];\n\n if (destructiveOps.length > 0) {\n ui.warn(\n `${destructiveOps.length} destructive operation(s) that may cause data loss:\\n${destructiveOps.map((op) => ` ${ui.yellow('▸')} ${op.label}`).join('\\n')}`,\n );\n }\n\n const confirmed = await ui.confirm('Apply destructive changes? This cannot be undone.');\n\n if (confirmed) {\n result = await executeDbUpdateCommand(options, { ...flags, yes: true }, ui, Date.now());\n }\n }\n\n const exitCode = handleResult(result, flags, ui, (dbUpdateResult) => {\n if (flags.json) {\n ui.output(formatMigrationJson(dbUpdateResult));\n } else {\n const output =\n dbUpdateResult.mode === 'plan'\n ? formatMigrationPlanOutput(dbUpdateResult, flags)\n : formatMigrationApplyOutput(dbUpdateResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAwDA,SAAS,mBAAmB,SAA8C;CACxE,IAAI,QAAQ,SAAS,mBACnB,OAAO,6BAA6B,EAAE,WAAW,QAAQ,aAAa,CAAC,EAAE,CAAC;CAG5E,IAAI,QAAQ,SAAS,iBAAiB;EAKpC,MAAM,OAHJ,OAAO,QAAQ,OAAO,uBAAuB,WACzC,QAAQ,KAAK,qBACb,KAAA,OAEW,wBACX,iMACA;EACN,OAAO,kBAAkB,QAAQ,SAAS;GACxC,KAAK,QAAQ,OAAO;GACpB;GACA,MAAM;IACJ,GAAG,QAAQ;IACX,GAAI,QAAQ,YAAY,QAAQ,SAAS,SAAS,IAC9C,EAAE,iBAAiB,QAAQ,SAAS,IACpC,CAAC;GACP;EACF,CAAC;CACH;CAEA,IAAI,QAAQ,SAAS,uBACnB,OAAO,wBAAwB,QAAQ,SAAS;EAC9C,GAAG,UAAU,OAAO,QAAQ,GAAG;EAC/B,KAAK;EACL,GAAG,UAAU,QAAQ,QAAQ,IAAI;CACnC,CAAC;CAGH,MAAM,aAAoB,QAAQ;CAClC,MAAM,IAAI,MAAM,mCAAmC,YAAY;AACjE;;;;AAKA,eAAe,uBACb,SACA,OACA,IACA,WAC6D;CAE7D,MAAM,YAAY,MAAM,wBAAwB,SAAS,OAAO,IAAI;EAClE,aAAa;EACb,aAAa;EACb,KAAK;CACP,CAAC;CACD,IAAI,CAAC,UAAU,IACb,OAAO;CAET,MAAM,EAAE,QAAQ,QAAQ,cAAc,YAAY,yBAAyB,UAAU;CACrF,IAAI,EAAE,iBAAiB,UAAU;CACjC,IAAI,8BAA8B;CAClC,MAAM,EAAE,eAAe,YAAY,sBAAsB,QAAQ,QAAQ,MAAM;CAE/E,IAAI,QAAQ,IACV,IAAI;EACF,MAAM,SAAS,MAAM,mBAAmB,QAAQ,EAAE,cAAc,CAAC;EACjE,IAAI,CAAC,OAAO,IACV,OAAO,MAAM,OAAO,OAAO;EAE7B,MAAM,QAAQ,OAAO,MAAM,UAAU,IAAI,MAAM;EAC/C,MAAM,UAAU,OAAO,MAAM,UAAU,IAAI;EAC3C,MAAM,OAAO,OAAO,MAAM,UAAU,IAAI;EACxC,MAAM,YAAY,iBAAiB,QAAQ,IAAI;GAAE;GAAO;EAAK,CAAC;EAC9D,IAAI,CAAC,UAAU,IACb,OAAO,MAAM,sBAAsB,UAAU,OAAO,CAAC;EAEvD,MAAM,aAAa,UAAU,MAAM;EACnC,MAAM,iBAAiB,QAAQ,MAAM,MAAM,EAAE,SAAS,OAAO,UAAU;EACvE,IAAI,CAAC,gBACH,OAAO,MACL,gBACE,uCAAuC,QAAQ,GAAG,oBAAoB,WAAW,IACjF;GACE,KAAK,oGAAoG,WAAW;GACpH,KAAK;EACP,CACF,CACF;EAEF,MAAM,kBAAkB,KAAK,eAAe,SAAS,mBAAmB;EACxE,MAAM,MAAM,MAAM,SAAS,iBAAiB,OAAO;EACnD,eAAe,KAAK,MAAM,GAAG;EAC7B,8BAA8B;CAChC,SAAS,OAAO;EACd,IAAI,oBAAoB,GAAG,KAAK,GAC9B,OAAO,MAAM,uBAAuB,KAAK,CAAC;EAE5C,IAAI,mBAAmB,GAAG,KAAK,GAC7B,OAAO,MAAM,KAAK;EAEpB,MAAM;CACR;CAGF,IAAI;EACF,MAAM,OAAO,QAAQ,YAAY;EAEjC,MAAM,SAAS,MAAM,OAAO,SAAS;GACnC,UAAU;GACV,MAAM,QAAQ,SAAS,SAAS;GAChC;GACA,GAAI,MAAM,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;GAC5C;EACF,CAAC;EAGD,IAAI,CAAC,OAAO,IACV,OAAO,MAAM,mBAAmB,OAAO,OAAO,CAAC;EAGjD,MAAM,kBACJ,OAAO,MAAM,SAAS,UACjB,OAAO,MAAM,QAAQ,eAAe,OAAO,MAAM,YAAY,cAC9D,OAAO,MAAM,YAAY;EAE/B,IAAI,uBAA6C;GAC/C,aAAa;GACb,mBAAmB;EACrB;EACA,IACE,0BAA0B;GACxB,GAAG,UAAU,cAAc,QAAQ,UAAU;GAC7C,GAAG,UAAU,MAAM,QAAQ,EAAE;EAC/B,CAAC,MAAM,MAEP,IAAI;GACF,MAAM,aAAa,MAAM,eAAe,cAAc,2BAA2B;GACjF,uBAAuB,MAAM,0BAA0B;IACrD,GAAG,UAAU,cAAc,QAAQ,UAAU;IAC7C,GAAG,UAAU,MAAM,QAAQ,EAAE;IAC7B;IACA;IACA,MAAM,OAAO,MAAM;IACnB,MAAM;GACR,CAAC;EACH,SAAS,OAAO;GACd,IAAI,oBAAoB,GAAG,KAAK,GAC9B,OAAO,MAAM,uBAAuB,KAAK,CAAC;GAE5C,MAAM;EACR;EA8CF,OAAO,GAAG;GAzCR,IAAI;GACJ,MAAM,OAAO,MAAM;GACnB,MAAM;IACJ,UAAU,UAAU,MAAM,OAAO,OAAO;IACxC,aAAa;KACX,aAAa,OAAO,MAAM,YAAY;KACtC,GAAG,UAAU,eAAe,OAAO,MAAM,YAAY,WAAW;IAClE;IACA,YAAY,OAAO,MAAM,KAAK,WAAW,KAAK,QAAQ;KACpD,IAAI,GAAG;KACP,OAAO,GAAG;KACV,gBAAgB,GAAG;IACrB,EAAE;IACF,GAAG,UAAU,WAAW,OAAO,MAAM,KAAK,OAAO;GACnD;GACA,GAAG,UACD,aACA,OAAO,MAAM,YACT;IACE,mBAAmB,OAAO,MAAM,UAAU;IAC1C,oBAAoB,OAAO,MAAM,UAAU;GAC7C,IACA,KAAA,CACN;GACA,GAAG,UACD,UACA,OAAO,MAAM,SACT;IACE,aAAa,OAAO,MAAM,OAAO;IACjC,GAAG,UAAU,eAAe,OAAO,MAAM,OAAO,WAAW;GAC7D,IACA,KAAA,CACN;GACA,GAAG,UAAU,YAAY,OAAO,MAAM,QAAQ;GAC9C,GAAG,UAAU,YAAY,OAAO,MAAM,QAAQ;GAC9C,aAAa,qBAAqB;GAClC,mBAAmB,qBAAqB;GACxC,SAAS,OAAO,MAAM;GACtB,SAAS,EAAE,OAAO,KAAK,IAAI,IAAI,UAAU;EAGpB,CAAC;CAC1B,SAAS,OAAO;EACd,IAAI,mBAAmB,GAAG,KAAK,GAC7B,OAAO,MAAM,KAAK;EAGpB,IAAI,iBAAiB,yBACnB,OAAO,MACL,8BAA8B,+BAA+B,MAAM,WAAW,EAC5E,OAAO,EAAE,MAAM,qBAAqB,EACtC,CAAC,CACH;EAIF,MAAM,cAAc,qBADD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAGtE,OAAO,iBAAiB,WAAW,eAAe,KAAA,CACpD;EACA,OAAO,MACL,gBAAgB,aAAa,EAC3B,KAAK,sCAAsC,cAC7C,CAAC,CACH;CACF,UAAU;EACR,MAAM,OAAO,MAAM;CACrB;AACF;AAEA,SAAgB,wBAAiC;CAC/C,MAAM,UAAU,IAAI,QAAQ,QAAQ;CACpC,uBACE,SACA,sDACA,oSAIF;CACA,mBAAmB,SAAS,CAC1B,4CACA,oDACF,CAAC;CACD,2BAA2B,OAAO;CAClC,QAAQ,OACN,mBACA,2FACF;CACA,QAAQ,OAAO,wBAAwB,kDAAkD;CACzF,QAAQ,OAAO,OAAO,YAA6B;EACjD,MAAM,QAAQ,uBAAuB,OAAO;EAC5C,MAAM,YAAY,KAAK,IAAI;EAE3B,MAAM,KAAK,iBAAiB,KAAK;EAEjC,IAAI,SAAS,MAAM,uBAAuB,SAAS,OAAO,IAAI,SAAS;EAKvE,IACE,CAAC,OAAO,MACR,OAAO,QAAQ,SAAS,kCACxB,MAAM,eACN,CAAC,MAAM,QACP,CAAC,MAAM,KACP;GAIA,MAAM,iBAHO,OAAO,QAAQ,MAGC,yBAAyB,CAAC;GAEvD,IAAI,eAAe,SAAS,GAC1B,GAAG,KACD,GAAG,eAAe,OAAO,uDAAuD,eAAe,KAAK,OAAO,KAAK,GAAG,OAAO,GAAG,EAAE,GAAG,GAAG,OAAO,EAAE,KAAK,IAAI,GACzJ;GAKF,IAAI,MAFoB,GAAG,QAAQ,mDAAmD,GAGpF,SAAS,MAAM,uBAAuB,SAAS;IAAE,GAAG;IAAO,KAAK;GAAK,GAAG,IAAI,KAAK,IAAI,CAAC;EAE1F;EAEA,MAAM,WAAW,aAAa,QAAQ,OAAO,KAAK,mBAAmB;GACnE,IAAI,MAAM,MACR,GAAG,OAAO,oBAAoB,cAAc,CAAC;QACxC;IACL,MAAM,SACJ,eAAe,SAAS,SACpB,0BAA0B,gBAAgB,KAAK,IAC/C,2BAA2B,gBAAgB,KAAK;IACtD,IAAI,QACF,GAAG,IAAI,MAAM;GAEjB;EACF,CAAC;EACD,QAAQ,KAAK,QAAQ;CACvB,CAAC;CAED,OAAO;AACT"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createDbVerifyCommand } from "../db-verify-
|
|
1
|
+
import { t as createDbVerifyCommand } from "../db-verify-CNz036sw.mjs";
|
|
2
2
|
export { createDbVerifyCommand };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as PerSpaceExecutionEntry, w as MigrationApplyPathDecision } from "../types-
|
|
1
|
+
import { E as PerSpaceExecutionEntry, w as MigrationApplyPathDecision } from "../types-BYwWOyYJ.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
|
|
4
4
|
//#region src/commands/migrate.d.ts
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as createControlClient } from "../client-
|
|
2
|
+
import { A as formatStyledHeader, B as errorDatabaseConnectionRequired, F as CliStructuredError, H as errorDriverRequired, K as errorMarkerMismatch, S as formatMigrationApplyCommandOutput, U as errorFileNotFound, Y as errorPathUnreachable, _ as createTerminalUI, ct as mapRefResolutionError, f as targetSupportsMigrations, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, it as errorTargetMigrationNotSupported, l as setCommandDescriptions, n as collectDeclaredInvariants, o as resolveContractPath, ot as errorUnexpected, s as resolveMigrationPaths, st as mapMigrationToolsError, t as addGlobalOptions, tt as errorRuntime, u as setCommandExamples, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-D7TK5Y9e.mjs";
|
|
3
|
+
import { t as createControlClient } from "../client-nygCs15r.mjs";
|
|
4
4
|
import { t as toDeclaredExtensionsFromRaw } from "../extension-pack-inputs-IDvjRCi3.mjs";
|
|
5
|
-
import { a as refuseContractSpaceIntegrity, i as loadContractSpaceAggregateForCli } from "../contract-space-aggregate-loader-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { t as mapContractAtError } from "../contract-at-errors-DlZHXSkI.mjs";
|
|
5
|
+
import { a as refuseContractSpaceIntegrity, i as loadContractSpaceAggregateForCli } from "../contract-space-aggregate-loader-5zmOENc4.mjs";
|
|
6
|
+
import { i as readContractIR, r as executeRefAdvancement } from "../ref-advancement-V1o-9LVK.mjs";
|
|
7
|
+
import { t as mapContractAtError } from "../contract-at-errors-CK3qoqZf.mjs";
|
|
9
8
|
import { Command } from "commander";
|
|
10
9
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
11
10
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.mjs","names":[],"sources":["../../src/commands/migrate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { RefEntry } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type {\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n PerSpaceExecutionEntry,\n} from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorMarkerMismatch,\n errorPathUnreachable,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n collectDeclaredInvariants,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { mapContractAtError } from '../utils/contract-at-errors';\nimport {\n loadContractSpaceAggregateForCli,\n refuseContractSpaceIntegrity,\n} from '../utils/contract-space-aggregate-loader';\nimport { toDeclaredExtensionsFromRaw } from '../utils/extension-pack-inputs';\nimport { formatMigrationApplyCommandOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { executeRefAdvancement, readContractIR } from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrateCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly to?: string;\n readonly advanceRef?: string;\n}\n\nexport interface MigrateResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName: string;\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n readonly pathDecision?: MigrationApplyPathDecision;\n readonly timings: {\n readonly total: number;\n };\n readonly advancedRef?: { readonly name: string; readonly hash: string } | null;\n}\n\nfunction mapApplyFailure(failure: MigrationApplyFailure): CliStructuredErrorType {\n if (failure.code === 'MIGRATION_PATH_NOT_FOUND') {\n return errorPathUnreachable(failure);\n }\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the issue and re-run `prisma-next migrate --to <contract>` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nasync function executeMigrateCommand(\n options: MigrateCommandOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrateResult, CliStructuredErrorType>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsRelative, refsDir } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migrate (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migrate',\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: 'Config.driver is required for migrate',\n }),\n );\n }\n\n if (!targetSupportsMigrations(config.target)) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n const toArg = options.to;\n\n // Construct the family instance up-front so the on-disk contract read\n // crosses the serializer seam (`familyInstance.deserializeContract`) at\n // the read site. The downstream `client.migrationApply({ contract })`\n // re-validates internally (no harm — validation is idempotent), but\n // closing the gap at the read site is what makes the cast-pattern\n // lint enforceable and matches the other CLI commands. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n const contractPathAbsolute = resolveContractPath(config);\n let contractRaw: Contract;\n let contractContent: string;\n try {\n contractContent = 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 a valid contract.json, then retry.',\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n try {\n contractRaw = familyInstance.deserializeContract(JSON.parse(contractContent) as unknown);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const loadedAggregate = await loadContractSpaceAggregateForCli({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: contractRaw,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json) => familyInstance.deserializeContract(json),\n });\n if (!loadedAggregate.ok) {\n return notOk(loadedAggregate.failure);\n }\n const aggregate = loadedAggregate.value;\n const integrityFailure = refuseContractSpaceIntegrity(aggregate, {\n declaredExtensions: toDeclaredExtensionsFromRaw(\n (config.extensionPacks ?? []) as ReadonlyArray<unknown>,\n ),\n checkContracts: true,\n });\n if (integrityFailure) {\n return notOk(integrityFailure);\n }\n\n let refEntry: RefEntry | undefined;\n let refName: string | undefined;\n if (toArg) {\n const refs = aggregate.app.refs;\n const refResult = parseContractRef(toArg, { graph: aggregate.app.graph(), refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n if (refResult.value.provenance.kind === 'ref') {\n refName = refResult.value.provenance.refName;\n const resolved = refs[refName];\n if (resolved) refEntry = resolved;\n } else {\n refEntry = { hash: refResult.value.hash, invariants: [] };\n }\n }\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({\n label: 'database',\n value: maskConnectionUrl(dbConnection),\n });\n }\n if (toArg) {\n details.push({ label: 'to', value: toArg });\n }\n const header = formatStyledHeader({\n command: 'migrate',\n description: 'Apply planned migrations to advance the database',\n url: 'https://pris.ly/migrate',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n const appGraph = aggregate.app.graph();\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n try {\n await client.connect(dbConnection);\n\n const allMarkers = await client.readAllMarkers();\n const appMarker = allMarkers.get('app') ?? null;\n\n if (appMarker !== null && !isGraphNode(appMarker.storageHash, appGraph)) {\n return notOk(\n errorMarkerMismatch(\n appMarker.storageHash,\n [...appGraph.nodes].sort(),\n findLatestMigration(appGraph)?.to ?? null,\n ),\n );\n }\n\n if (refEntry && refEntry.invariants.length > 0) {\n const declared = collectDeclaredInvariants(appGraph);\n const known = new Set<string>(declared);\n for (const id of appMarker?.invariants ?? []) known.add(id);\n const unknown = refEntry.invariants.filter((id) => !known.has(id));\n if (unknown.length > 0) {\n return notOk(\n mapMigrationToolsError(\n errorUnknownInvariant({\n ...ifDefined('refName', toArg),\n unknown,\n declared: [...declared].sort(),\n }),\n ),\n );\n }\n }\n\n if (!flags.quiet && !flags.json) {\n ui.step('Loading contract spaces…');\n }\n\n // When `--to` resolves to an on-disk graph node with a matching bundle,\n // verify and apply against THAT bundle's destination contract via\n // `contractAt` — not the emitted `contract.json`. With `--to` omitted,\n // or a target with no matching bundle, the emitted contract stays the\n // apply contract (the only migrate-specific default). The same\n // `contractAt` artifacts feed the optional ref-advancement snapshot.\n let applyContract: Contract = contractRaw;\n let snapshotContractJson: Record<string, unknown> = JSON.parse(contractContent);\n let snapshotContractDts: string | undefined;\n if (toArg && refEntry) {\n const targetHash = refEntry.hash;\n const matchingBundle = aggregate.app.packages.find((p) => p.metadata.to === targetHash);\n if (matchingBundle) {\n try {\n const at = await aggregate.app.contractAt(\n targetHash,\n refName !== undefined ? { refName } : undefined,\n );\n applyContract = at.contract;\n snapshotContractJson = at.contractJson as Record<string, unknown>;\n snapshotContractDts = at.contractDts;\n } catch (error) {\n return mapContractAtError(error, { artifactRole: 'to' });\n }\n }\n }\n\n const applyResult = await client.migrationApply({\n contract: applyContract,\n migrationsDir,\n ...ifDefined('refHash', refEntry?.hash),\n ...(refEntry?.invariants ? { refInvariants: refEntry.invariants } : {}),\n ...(refEntry !== undefined ? ifDefined('refName', toArg) : {}),\n });\n\n if (!applyResult.ok) {\n return notOk(mapApplyFailure(applyResult.failure));\n }\n\n const { value } = applyResult;\n\n let advancedRef: { name: string; hash: string } | null = null;\n if (options.advanceRef !== undefined) {\n try {\n const contractIR =\n snapshotContractDts !== undefined\n ? { contract: snapshotContractJson, contractDts: snapshotContractDts }\n : await readContractIR(snapshotContractJson, contractPathAbsolute);\n advancedRef = await executeRefAdvancement(\n refsDir,\n options.advanceRef,\n value.markerHash,\n contractIR,\n );\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n return ok({\n ok: true,\n migrationsApplied: value.migrationsApplied,\n migrationsTotal: value.perSpace.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n perSpace: value.perSpace,\n ...ifDefined('pathDecision', value.pathDecision),\n timings: { total: Date.now() - startTime },\n advancedRef,\n });\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 return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migrate: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrateCommand(): Command {\n const command = new Command('migrate');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to advance the database',\n 'Walks every contract space (app + extensions) and applies pending\\n' +\n 'on-disk migrations in canonical order (extensions alphabetically,\\n' +\n 'then app). Graph-walks the on-disk migration graph for every space.\\n' +\n 'Use --to to target a specific contract (hash, ref name, migration dir).',\n );\n setCommandExamples(command, [\n 'prisma-next migrate --db $DATABASE_URL',\n 'prisma-next migrate --to production --db $DATABASE_URL',\n 'prisma-next migrate --to sha256:abc123 --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .option('--advance-ref <name>', 'Advance the named ref to the post-apply marker after success')\n .action(async (options: MigrateCommandOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n const result = await executeMigrateCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (migrateResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(migrateResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationApplyCommandOutput(migrateResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"migrate.mjs","names":[],"sources":["../../src/commands/migrate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { RefEntry } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type {\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n PerSpaceExecutionEntry,\n} from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorMarkerMismatch,\n errorPathUnreachable,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n collectDeclaredInvariants,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { mapContractAtError } from '../utils/contract-at-errors';\nimport {\n loadContractSpaceAggregateForCli,\n refuseContractSpaceIntegrity,\n} from '../utils/contract-space-aggregate-loader';\nimport { toDeclaredExtensionsFromRaw } from '../utils/extension-pack-inputs';\nimport { formatMigrationApplyCommandOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { executeRefAdvancement, readContractIR } from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrateCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly to?: string;\n readonly advanceRef?: string;\n}\n\nexport interface MigrateResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName: string;\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n readonly pathDecision?: MigrationApplyPathDecision;\n readonly timings: {\n readonly total: number;\n };\n readonly advancedRef?: { readonly name: string; readonly hash: string } | null;\n}\n\nfunction mapApplyFailure(failure: MigrationApplyFailure): CliStructuredErrorType {\n if (failure.code === 'MIGRATION_PATH_NOT_FOUND') {\n return errorPathUnreachable(failure);\n }\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the issue and re-run `prisma-next migrate --to <contract>` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nasync function executeMigrateCommand(\n options: MigrateCommandOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrateResult, CliStructuredErrorType>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsRelative, refsDir } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migrate (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migrate',\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: 'Config.driver is required for migrate',\n }),\n );\n }\n\n if (!targetSupportsMigrations(config.target)) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n const toArg = options.to;\n\n // Construct the family instance up-front so the on-disk contract read\n // crosses the serializer seam (`familyInstance.deserializeContract`) at\n // the read site. The downstream `client.migrationApply({ contract })`\n // re-validates internally (no harm — validation is idempotent), but\n // closing the gap at the read site is what makes the cast-pattern\n // lint enforceable and matches the other CLI commands. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n const contractPathAbsolute = resolveContractPath(config);\n let contractRaw: Contract;\n let contractContent: string;\n try {\n contractContent = 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 a valid contract.json, then retry.',\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n try {\n contractRaw = familyInstance.deserializeContract(JSON.parse(contractContent) as unknown);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const loadedAggregate = await loadContractSpaceAggregateForCli({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: contractRaw,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json) => familyInstance.deserializeContract(json),\n });\n if (!loadedAggregate.ok) {\n return notOk(loadedAggregate.failure);\n }\n const aggregate = loadedAggregate.value;\n const integrityFailure = refuseContractSpaceIntegrity(aggregate, {\n declaredExtensions: toDeclaredExtensionsFromRaw(\n (config.extensionPacks ?? []) as ReadonlyArray<unknown>,\n ),\n checkContracts: true,\n });\n if (integrityFailure) {\n return notOk(integrityFailure);\n }\n\n let refEntry: RefEntry | undefined;\n let refName: string | undefined;\n if (toArg) {\n const refs = aggregate.app.refs;\n const refResult = parseContractRef(toArg, { graph: aggregate.app.graph(), refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n if (refResult.value.provenance.kind === 'ref') {\n refName = refResult.value.provenance.refName;\n const resolved = refs[refName];\n if (resolved) refEntry = resolved;\n } else {\n refEntry = { hash: refResult.value.hash, invariants: [] };\n }\n }\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({\n label: 'database',\n value: maskConnectionUrl(dbConnection),\n });\n }\n if (toArg) {\n details.push({ label: 'to', value: toArg });\n }\n const header = formatStyledHeader({\n command: 'migrate',\n description: 'Apply planned migrations to advance the database',\n url: 'https://pris.ly/migrate',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n const appGraph = aggregate.app.graph();\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n try {\n await client.connect(dbConnection);\n\n const allMarkers = await client.readAllMarkers();\n const appMarker = allMarkers.get('app') ?? null;\n\n if (appMarker !== null && !isGraphNode(appMarker.storageHash, appGraph)) {\n return notOk(\n errorMarkerMismatch(\n appMarker.storageHash,\n [...appGraph.nodes].sort(),\n findLatestMigration(appGraph)?.to ?? null,\n ),\n );\n }\n\n if (refEntry && refEntry.invariants.length > 0) {\n const declared = collectDeclaredInvariants(appGraph);\n const known = new Set<string>(declared);\n for (const id of appMarker?.invariants ?? []) known.add(id);\n const unknown = refEntry.invariants.filter((id) => !known.has(id));\n if (unknown.length > 0) {\n return notOk(\n mapMigrationToolsError(\n errorUnknownInvariant({\n ...ifDefined('refName', toArg),\n unknown,\n declared: [...declared].sort(),\n }),\n ),\n );\n }\n }\n\n if (!flags.quiet && !flags.json) {\n ui.step('Loading contract spaces…');\n }\n\n // When `--to` resolves to an on-disk graph node with a matching bundle,\n // verify and apply against THAT bundle's destination contract via\n // `contractAt` — not the emitted `contract.json`. With `--to` omitted,\n // or a target with no matching bundle, the emitted contract stays the\n // apply contract (the only migrate-specific default). The same\n // `contractAt` artifacts feed the optional ref-advancement snapshot.\n let applyContract: Contract = contractRaw;\n let snapshotContractJson: Record<string, unknown> = JSON.parse(contractContent);\n let snapshotContractDts: string | undefined;\n if (toArg && refEntry) {\n const targetHash = refEntry.hash;\n const matchingBundle = aggregate.app.packages.find((p) => p.metadata.to === targetHash);\n if (matchingBundle) {\n try {\n const at = await aggregate.app.contractAt(\n targetHash,\n refName !== undefined ? { refName } : undefined,\n );\n applyContract = at.contract;\n snapshotContractJson = at.contractJson as Record<string, unknown>;\n snapshotContractDts = at.contractDts;\n } catch (error) {\n return mapContractAtError(error, { artifactRole: 'to' });\n }\n }\n }\n\n const applyResult = await client.migrationApply({\n contract: applyContract,\n migrationsDir,\n ...ifDefined('refHash', refEntry?.hash),\n ...(refEntry?.invariants ? { refInvariants: refEntry.invariants } : {}),\n ...(refEntry !== undefined ? ifDefined('refName', toArg) : {}),\n });\n\n if (!applyResult.ok) {\n return notOk(mapApplyFailure(applyResult.failure));\n }\n\n const { value } = applyResult;\n\n let advancedRef: { name: string; hash: string } | null = null;\n if (options.advanceRef !== undefined) {\n try {\n const contractIR =\n snapshotContractDts !== undefined\n ? { contract: snapshotContractJson, contractDts: snapshotContractDts }\n : await readContractIR(snapshotContractJson, contractPathAbsolute);\n advancedRef = await executeRefAdvancement(\n refsDir,\n options.advanceRef,\n value.markerHash,\n contractIR,\n );\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n return ok({\n ok: true,\n migrationsApplied: value.migrationsApplied,\n migrationsTotal: value.perSpace.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n perSpace: value.perSpace,\n ...ifDefined('pathDecision', value.pathDecision),\n timings: { total: Date.now() - startTime },\n advancedRef,\n });\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 return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migrate: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrateCommand(): Command {\n const command = new Command('migrate');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to advance the database',\n 'Walks every contract space (app + extensions) and applies pending\\n' +\n 'on-disk migrations in canonical order (extensions alphabetically,\\n' +\n 'then app). Graph-walks the on-disk migration graph for every space.\\n' +\n 'Use --to to target a specific contract (hash, ref name, migration dir).',\n );\n setCommandExamples(command, [\n 'prisma-next migrate --db $DATABASE_URL',\n 'prisma-next migrate --to production --db $DATABASE_URL',\n 'prisma-next migrate --to sha256:abc123 --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .option('--advance-ref <name>', 'Advance the named ref to the post-apply marker after success')\n .action(async (options: MigrateCommandOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n const result = await executeMigrateCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (migrateResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(migrateResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationApplyCommandOutput(migrateResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createMigrationCheckCommand } from "../migration-check-
|
|
1
|
+
import { t as createMigrationCheckCommand } from "../migration-check-CL2MzDRX.mjs";
|
|
2
2
|
export { createMigrationCheckCommand };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
2
|
-
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-
|
|
3
|
-
import { n as StatusRef } from "../migration-types-
|
|
4
|
-
import { t as TerminalUI } from "../terminal-ui-
|
|
1
|
+
import { N as CliStructuredError } from "../types-BYwWOyYJ.mjs";
|
|
2
|
+
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DEHjV8_s.mjs";
|
|
3
|
+
import { n as StatusRef } from "../migration-types-D2FW63pr.mjs";
|
|
4
|
+
import { t as TerminalUI } from "../terminal-ui-5Y6mrg93.mjs";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { Result } from "@prisma-next/utils/result";
|
|
7
7
|
import { MigrationGraph } from "@prisma-next/migration-tools/graph";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-
|
|
4
|
-
import { c as buildMigrationGraphLayout, n as renderMigrationGraphTree, s as buildMigrationGraphRows, t as renderMigrationGraphLegend } from "../migration-graph-tree-render-
|
|
2
|
+
import { A as formatStyledHeader, _ as createTerminalUI, d as setCommandSeeAlso, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, s as resolveMigrationPaths, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "../command-helpers-D7TK5Y9e.mjs";
|
|
3
|
+
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-5zmOENc4.mjs";
|
|
4
|
+
import { c as buildMigrationGraphLayout, n as renderMigrationGraphTree, s as buildMigrationGraphRows, t as renderMigrationGraphLegend } from "../migration-graph-tree-render-CVmV9sWr.mjs";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { ok } from "@prisma-next/utils/result";
|
|
7
7
|
//#region src/commands/migration-graph.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
2
|
-
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-
|
|
3
|
-
import { n as GlyphMode, t as TerminalUI } from "../terminal-ui-
|
|
4
|
-
import { n as MigrationListResult, r as MigrationSpaceListEntry } from "../migration-list-types-
|
|
1
|
+
import { N as CliStructuredError } from "../types-BYwWOyYJ.mjs";
|
|
2
|
+
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DEHjV8_s.mjs";
|
|
3
|
+
import { n as GlyphMode, t as TerminalUI } from "../terminal-ui-5Y6mrg93.mjs";
|
|
4
|
+
import { n as MigrationListResult, r as MigrationSpaceListEntry } from "../migration-list-types-DS63IdFd.mjs";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { Result } from "@prisma-next/utils/result";
|
|
7
7
|
import { ContractSpaceAggregate, ContractSpaceMember } from "@prisma-next/migration-tools/aggregate";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-
|
|
4
|
-
import { a as renderMigrationListWithStyle, r as createAnsiMigrationListStyler } from "../migration-graph-tree-render-
|
|
2
|
+
import { A as formatStyledHeader, G as errorInvalidSpaceId, _ as createTerminalUI, d as setCommandSeeAlso, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, rt as errorSpaceNotFound, s as resolveMigrationPaths, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "../command-helpers-D7TK5Y9e.mjs";
|
|
3
|
+
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-5zmOENc4.mjs";
|
|
4
|
+
import { a as renderMigrationListWithStyle, r as createAnsiMigrationListStyler } from "../migration-graph-tree-render-CVmV9sWr.mjs";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
7
7
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
2
|
-
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-
|
|
3
|
-
import { t as TerminalUI } from "../terminal-ui-
|
|
1
|
+
import { N as CliStructuredError } from "../types-BYwWOyYJ.mjs";
|
|
2
|
+
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DEHjV8_s.mjs";
|
|
3
|
+
import { t as TerminalUI } from "../terminal-ui-5Y6mrg93.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { Result } from "@prisma-next/utils/result";
|
|
6
6
|
import { LedgerEntryRecord } from "@prisma-next/contract/types";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as executeMigrationLogCommand, t as createMigrationLogCommand } from "../migration-log-
|
|
1
|
+
import { n as executeMigrationLogCommand, t as createMigrationLogCommand } from "../migration-log-CP6skD5b.mjs";
|
|
2
2
|
export { createMigrationLogCommand, executeMigrationLogCommand };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as assertFrameworkComponentsCompatible } from "../framework-components-
|
|
4
|
-
import { o as refusePackageCorruptionOnAggregate } from "../contract-space-aggregate-loader-
|
|
2
|
+
import { A as formatStyledHeader, F as CliStructuredError, U as errorFileNotFound, _ as createTerminalUI, g as parseGlobalFlagsOrExit, it as errorTargetMigrationNotSupported, l as setCommandDescriptions, o as resolveContractPath, ot as errorUnexpected, r as getTargetMigrations, s as resolveMigrationPaths, t as addGlobalOptions, tt as errorRuntime, u as setCommandExamples, y as handleResult } from "../command-helpers-D7TK5Y9e.mjs";
|
|
3
|
+
import { t as assertFrameworkComponentsCompatible } from "../framework-components-CyM_xYCY.mjs";
|
|
4
|
+
import { o as refusePackageCorruptionOnAggregate } from "../contract-space-aggregate-loader-5zmOENc4.mjs";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { getEmittedArtifactPaths } from "@prisma-next/emitter";
|
|
7
7
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as GlobalFlags } from "../global-flags-
|
|
1
|
+
import { n as GlobalFlags } from "../global-flags-DEHjV8_s.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { Result } from "@prisma-next/utils/result";
|
|
4
4
|
import { OperationPreview } from "@prisma-next/framework-components/control";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as formatMigrationPlanOutput, r as resolveBundleByPrefix, t as createMigrationPlanCommand } from "../migration-plan-
|
|
1
|
+
import { n as formatMigrationPlanOutput, r as resolveBundleByPrefix, t as createMigrationPlanCommand } from "../migration-plan-D61N1hID.mjs";
|
|
2
2
|
export { createMigrationPlanCommand, formatMigrationPlanOutput, resolveBundleByPrefix };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
1
|
+
import { N as CliStructuredError } from "../types-BYwWOyYJ.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { Result } from "@prisma-next/utils/result";
|
|
4
4
|
import { OperationPreview } from "@prisma-next/framework-components/control";
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as createControlClient } from "../client-
|
|
4
|
-
import { a as formatMigrationShowOutput } from "../migrations-B3H6RTXb.mjs";
|
|
2
|
+
import { A as formatStyledHeader, E as formatMigrationShowOutput, U as errorFileNotFound, _ as createTerminalUI, ct as mapRefResolutionError, d as setCommandSeeAlso, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, o as resolveContractPath, ot as errorUnexpected, s as resolveMigrationPaths, t as addGlobalOptions, tt as errorRuntime, u as setCommandExamples, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-D7TK5Y9e.mjs";
|
|
3
|
+
import { t as createControlClient } from "../client-nygCs15r.mjs";
|
|
5
4
|
import { Command } from "commander";
|
|
6
5
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
7
6
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
8
7
|
import { isAbsolute, relative, resolve } from "pathe";
|
|
9
8
|
import { readFile } from "node:fs/promises";
|
|
10
9
|
import { APP_SPACE_ID, createControlStack } from "@prisma-next/framework-components/control";
|
|
11
|
-
import { loadContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
|
|
12
10
|
import { castAs } from "@prisma-next/utils/casts";
|
|
11
|
+
import { loadContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
|
|
13
12
|
import { parseMigrationRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
14
13
|
//#region src/commands/migration-show.ts
|
|
15
14
|
function looksLikePath(target) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-show.mjs","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport {\n APP_SPACE_ID,\n createControlStack,\n type MigrationPlanOperation,\n type OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { castAs } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { isAbsolute, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n type CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorRuntime,\n errorUnexpected,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n} from '../utils/command-helpers';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowPresent {\n readonly spaceId: string;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string | null;\n readonly to: string;\n readonly migrationHash: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly migration: MigrationShowPresent;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveAppTargetPath(\n target: string,\n appMigrationsDir: string,\n appMigrationsRelative: string,\n): Result<string, CliStructuredError> {\n const targetPath = resolve(target);\n const relativeToApp = relative(appMigrationsDir, targetPath);\n const isOutsideAppDir =\n relativeToApp === '' ||\n relativeToApp === '.' ||\n relativeToApp.startsWith('..') ||\n isAbsolute(relativeToApp);\n if (isOutsideAppDir) {\n return notOk(\n errorRuntime('Target must point to an app-space migration', {\n why: `Expected a path under ${appMigrationsRelative}, got ${target}`,\n fix: 'Pass an app-space migration directory or use a hash prefix.',\n }),\n );\n }\n return ok(targetPath);\n}\n\nfunction pkgToPresent(\n spaceId: string,\n pkg: OnDiskMigrationPackage,\n client: ReturnType<typeof createControlClient>,\n): MigrationShowPresent {\n const ops = castAs<readonly MigrationPlanOperation[]>(pkg.ops);\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n return {\n spaceId,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.metadata.from,\n to: pkg.metadata.to,\n migrationHash: pkg.metadata.migrationHash,\n createdAt: pkg.metadata.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n preview,\n summary: `${ops.length} operation(s)`,\n };\n}\n\nfunction findPackageByDirPath(\n packages: readonly OnDiskMigrationPackage[],\n resolvedDirPath: string,\n): OnDiskMigrationPackage | undefined {\n const normalized = resolve(resolvedDirPath);\n return packages.find((p) => resolve(p.dirPath) === normalized);\n}\n\nasync function executeMigrationShowCommand(\n target: string,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, 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 header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n { label: 'target', value: target },\n ],\n flags,\n });\n ui.stderr(header);\n }\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...ifDefined('driver', config.driver),\n extensionPacks: config.extensionPacks ?? [],\n });\n\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as NodeJS.ErrnoException).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}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to read contract file',\n }),\n );\n }\n\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let appContract: Contract;\n try {\n appContract = familyInstance.deserializeContract(\n castAs<unknown>(JSON.parse(contractJsonContent)),\n );\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const aggregate = await loadContractSpaceAggregate({\n migrationsDir,\n appContract,\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n\n const packages = aggregate.app.packages;\n const graph = aggregate.app.graph();\n const refs = aggregate.app.refs;\n\n let appPkg: OnDiskMigrationPackage;\n if (looksLikePath(target)) {\n const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);\n if (!resolved.ok) return resolved;\n const matched = findPackageByDirPath(packages, resolved.value);\n if (!matched) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `No loaded migration package at ${relative(process.cwd(), resolved.value)}`,\n fix: 'Pass a directory name, hash prefix, or path to an on-disk app-space migration package.',\n }),\n );\n }\n appPkg = matched;\n } else {\n if (packages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${appMigrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n const migResult = parseMigrationRef(target, { graph, refs });\n if (!migResult.ok) {\n return notOk(mapRefResolutionError(migResult.failure));\n }\n const matchedPkg = packages.find(\n (p) => p.metadata.migrationHash === migResult.value.migrationHash,\n );\n if (!matchedPkg) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `Resolved migration \"${migResult.value.dirName}\" but the package was not loaded`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n appPkg = matchedPkg;\n }\n\n return ok({\n ok: true,\n migration: pkgToPresent(APP_SPACE_ID, appPkg, client),\n });\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, statement preview, and metadata for one app-space migration.\\n' +\n 'Accepts a directory path, directory name, or hash prefix.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show 20260101_100000_add_user',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration log', oneLiner: 'Show executed migration history' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n ]);\n addGlobalOptions(command)\n .argument('<target>', 'Migration reference: directory name, hash/prefix, or path')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string, options: MigrationShowOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n\n const ui = createTerminalUI(flags);\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;;AAmEA,SAAS,cAAc,QAAyB;CAC9C,OAAO,OAAO,SAAS,GAAG,KAAK,OAAO,SAAS,IAAI;AACrD;AAEA,SAAgB,qBACd,QACA,kBACA,uBACoC;CACpC,MAAM,aAAa,QAAQ,MAAM;CACjC,MAAM,gBAAgB,SAAS,kBAAkB,UAAU;CAM3D,IAJE,kBAAkB,MAClB,kBAAkB,OAClB,cAAc,WAAW,IAAI,KAC7B,WAAW,aAAa,GAExB,OAAO,MACL,aAAa,+CAA+C;EAC1D,KAAK,yBAAyB,sBAAsB,QAAQ;EAC5D,KAAK;CACP,CAAC,CACH;CAEF,OAAO,GAAG,UAAU;AACtB;AAEA,SAAS,aACP,SACA,KACA,QACsB;CACtB,MAAM,MAAM,OAA0C,IAAI,GAAG;CAC7D,MAAM,UAA4B,OAAO,mBAAmB,GAAG,KAAK,EAAE,YAAY,CAAC,EAAE;CACrF,OAAO;EACL;EACA,SAAS,IAAI;EACb,SAAS,SAAS,QAAQ,IAAI,GAAG,IAAI,OAAO;EAC5C,MAAM,IAAI,SAAS;EACnB,IAAI,IAAI,SAAS;EACjB,eAAe,IAAI,SAAS;EAC5B,WAAW,IAAI,SAAS;EACxB,YAAY,IAAI,KAAK,QAAQ;GAC3B,IAAI,GAAG;GACP,OAAO,GAAG;GACV,gBAAgB,GAAG;EACrB,EAAE;EACF;EACA,SAAS,GAAG,IAAI,OAAO;CACzB;AACF;AAEA,SAAS,qBACP,UACA,iBACoC;CACpC,MAAM,aAAa,QAAQ,eAAe;CAC1C,OAAO,SAAS,MAAM,MAAM,QAAQ,EAAE,OAAO,MAAM,UAAU;AAC/D;AAEA,eAAe,4BACb,QACA,SACA,OACA,IAC0D;CAC1D,MAAM,SAAS,MAAM,WAAW,QAAQ,MAAM;CAC9C,MAAM,EAAE,YAAY,eAAe,kBAAkB,0BACnD,sBAAsB,QAAQ,QAAQ,MAAM;CAE9C,MAAM,uBAAuB,oBAAoB,MAAM;CACvD,MAAM,eAAe,SAAS,QAAQ,IAAI,GAAG,oBAAoB;CAEjE,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OAAO;EAC/B,MAAM,SAAS,mBAAmB;GAChC,SAAS;GACT,aAAa;GACb,SAAS;IACP;KAAE,OAAO;KAAU,OAAO;IAAW;IACrC;KAAE,OAAO;KAAY,OAAO;IAAa;IACzC;KAAE,OAAO;KAAc,OAAO;IAAsB;IACpD;KAAE,OAAO;KAAU,OAAO;IAAO;GACnC;GACA;EACF,CAAC;EACD,GAAG,OAAO,MAAM;CAClB;CAEA,MAAM,SAAS,oBAAoB;EACjC,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,GAAG,UAAU,UAAU,OAAO,MAAM;EACpC,gBAAgB,OAAO,kBAAkB,CAAC;CAC5C,CAAC;CAED,IAAI;CACJ,IAAI;EACF,sBAAsB,MAAM,SAAS,sBAAsB,OAAO;CACpE,SAAS,OAAO;EACd,IAAI,iBAAiB,SAAU,MAAgC,SAAS,UACtE,OAAO,MACL,kBAAkB,sBAAsB;GACtC,KAAK,8BAA8B;GACnC,KAAK,iDAAiD;EACxD,CAAC,CACH;EAEF,OAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG,EACtE,KAAK,+BACP,CAAC,CACH;CACF;CAEA,MAAM,QAAQ,mBAAmB,MAAM;CACvC,MAAM,iBAAiB,OAAO,OAAO,OAAO,KAAK;CAEjD,IAAI;CACJ,IAAI;EACF,cAAc,eAAe,oBAC3B,OAAgB,KAAK,MAAM,mBAAmB,CAAC,CACjD;CACF,SAAS,OAAO;EACd,OAAO,MACL,8BACE,eAAe,qBAAqB,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACnH,EAAE,OAAO,EAAE,MAAM,qBAAqB,EAAE,CAC1C,CACF;CACF;CAEA,MAAM,YAAY,MAAM,2BAA2B;EACjD;EACA;EACA,sBAAsB,SAAkB,eAAe,oBAAoB,IAAI;CACjF,CAAC;CAED,MAAM,WAAW,UAAU,IAAI;CAC/B,MAAM,QAAQ,UAAU,IAAI,MAAM;CAClC,MAAM,OAAO,UAAU,IAAI;CAE3B,IAAI;CACJ,IAAI,cAAc,MAAM,GAAG;EACzB,MAAM,WAAW,qBAAqB,QAAQ,kBAAkB,qBAAqB;EACrF,IAAI,CAAC,SAAS,IAAI,OAAO;EACzB,MAAM,UAAU,qBAAqB,UAAU,SAAS,KAAK;EAC7D,IAAI,CAAC,SACH,OAAO,MACL,aAAa,+BAA+B;GAC1C,KAAK,kCAAkC,SAAS,QAAQ,IAAI,GAAG,SAAS,KAAK;GAC7E,KAAK;EACP,CAAC,CACH;EAEF,SAAS;CACX,OAAO;EACL,IAAI,SAAS,WAAW,GACtB,OAAO,MACL,aAAa,uBAAuB;GAClC,KAAK,kCAAkC;GACvC,KAAK;EACP,CAAC,CACH;EAEF,MAAM,YAAY,kBAAkB,QAAQ;GAAE;GAAO;EAAK,CAAC;EAC3D,IAAI,CAAC,UAAU,IACb,OAAO,MAAM,sBAAsB,UAAU,OAAO,CAAC;EAEvD,MAAM,aAAa,SAAS,MACzB,MAAM,EAAE,SAAS,kBAAkB,UAAU,MAAM,aACtD;EACA,IAAI,CAAC,YACH,OAAO,MACL,aAAa,+BAA+B;GAC1C,KAAK,uBAAuB,UAAU,MAAM,QAAQ;GACpD,KAAK;EACP,CAAC,CACH;EAEF,SAAS;CACX;CAEA,OAAO,GAAG;EACR,IAAI;EACJ,WAAW,aAAa,cAAc,QAAQ,MAAM;CACtD,CAAC;AACH;AAEA,SAAgB,6BAAsC;CACpD,MAAM,UAAU,IAAI,QAAQ,MAAM;CAClC,uBACE,SACA,sCACA,+IAEF;CACA,mBAAmB,SAAS,CAC1B,uDACA,0CACF,CAAC;CACD,kBAAkB,SAAS;EACzB;GAAE,MAAM;GAAoB,UAAU;EAAyC;EAC/E;GAAE,MAAM;GAAiB,UAAU;EAAkC;EACrE;GAAE,MAAM;GAAkB,UAAU;EAA0B;EAC9D;GAAE,MAAM;GAAmB,UAAU;EAAoC;CAC3E,CAAC;CACD,iBAAiB,OAAO,EACrB,SAAS,YAAY,2DAA2D,EAChF,OAAO,mBAAmB,+BAA+B,EACzD,OAAO,OAAO,QAAgB,YAAkC;EAC/D,MAAM,QAAQ,uBAAuB,OAAO;EAE5C,MAAM,KAAK,iBAAiB,KAAK;EAIjC,MAAM,WAAW,aAAa,MAFT,4BAA4B,QAAQ,SAAS,OAAO,EAAE,GAErC,OAAO,KAAK,eAAe;GAC/D,IAAI,MAAM,MACR,GAAG,OAAO,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,OAChB,GAAG,IAAI,0BAA0B,YAAY,KAAK,CAAC;EAEvD,CAAC;EAED,QAAQ,KAAK,QAAQ;CACvB,CAAC;CAEH,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"migration-show.mjs","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport {\n APP_SPACE_ID,\n createControlStack,\n type MigrationPlanOperation,\n type OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { castAs } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { isAbsolute, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n type CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorRuntime,\n errorUnexpected,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n} from '../utils/command-helpers';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowPresent {\n readonly spaceId: string;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string | null;\n readonly to: string;\n readonly migrationHash: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly migration: MigrationShowPresent;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveAppTargetPath(\n target: string,\n appMigrationsDir: string,\n appMigrationsRelative: string,\n): Result<string, CliStructuredError> {\n const targetPath = resolve(target);\n const relativeToApp = relative(appMigrationsDir, targetPath);\n const isOutsideAppDir =\n relativeToApp === '' ||\n relativeToApp === '.' ||\n relativeToApp.startsWith('..') ||\n isAbsolute(relativeToApp);\n if (isOutsideAppDir) {\n return notOk(\n errorRuntime('Target must point to an app-space migration', {\n why: `Expected a path under ${appMigrationsRelative}, got ${target}`,\n fix: 'Pass an app-space migration directory or use a hash prefix.',\n }),\n );\n }\n return ok(targetPath);\n}\n\nfunction pkgToPresent(\n spaceId: string,\n pkg: OnDiskMigrationPackage,\n client: ReturnType<typeof createControlClient>,\n): MigrationShowPresent {\n const ops = castAs<readonly MigrationPlanOperation[]>(pkg.ops);\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n return {\n spaceId,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.metadata.from,\n to: pkg.metadata.to,\n migrationHash: pkg.metadata.migrationHash,\n createdAt: pkg.metadata.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n preview,\n summary: `${ops.length} operation(s)`,\n };\n}\n\nfunction findPackageByDirPath(\n packages: readonly OnDiskMigrationPackage[],\n resolvedDirPath: string,\n): OnDiskMigrationPackage | undefined {\n const normalized = resolve(resolvedDirPath);\n return packages.find((p) => resolve(p.dirPath) === normalized);\n}\n\nasync function executeMigrationShowCommand(\n target: string,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, 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 header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n { label: 'target', value: target },\n ],\n flags,\n });\n ui.stderr(header);\n }\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...ifDefined('driver', config.driver),\n extensionPacks: config.extensionPacks ?? [],\n });\n\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as NodeJS.ErrnoException).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}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to read contract file',\n }),\n );\n }\n\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let appContract: Contract;\n try {\n appContract = familyInstance.deserializeContract(\n castAs<unknown>(JSON.parse(contractJsonContent)),\n );\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const aggregate = await loadContractSpaceAggregate({\n migrationsDir,\n appContract,\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n\n const packages = aggregate.app.packages;\n const graph = aggregate.app.graph();\n const refs = aggregate.app.refs;\n\n let appPkg: OnDiskMigrationPackage;\n if (looksLikePath(target)) {\n const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);\n if (!resolved.ok) return resolved;\n const matched = findPackageByDirPath(packages, resolved.value);\n if (!matched) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `No loaded migration package at ${relative(process.cwd(), resolved.value)}`,\n fix: 'Pass a directory name, hash prefix, or path to an on-disk app-space migration package.',\n }),\n );\n }\n appPkg = matched;\n } else {\n if (packages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${appMigrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n const migResult = parseMigrationRef(target, { graph, refs });\n if (!migResult.ok) {\n return notOk(mapRefResolutionError(migResult.failure));\n }\n const matchedPkg = packages.find(\n (p) => p.metadata.migrationHash === migResult.value.migrationHash,\n );\n if (!matchedPkg) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `Resolved migration \"${migResult.value.dirName}\" but the package was not loaded`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n appPkg = matchedPkg;\n }\n\n return ok({\n ok: true,\n migration: pkgToPresent(APP_SPACE_ID, appPkg, client),\n });\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, statement preview, and metadata for one app-space migration.\\n' +\n 'Accepts a directory path, directory name, or hash prefix.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show 20260101_100000_add_user',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration log', oneLiner: 'Show executed migration history' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n ]);\n addGlobalOptions(command)\n .argument('<target>', 'Migration reference: directory name, hash/prefix, or path')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string, options: MigrationShowOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n\n const ui = createTerminalUI(flags);\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|