prisma-next 0.11.0-dev.59 → 0.11.0-dev.60
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 +9 -9
- package/dist/{client-Ls2SAhrZ.mjs → client-CD3om3R0.mjs} +7 -7
- package/dist/{client-Ls2SAhrZ.mjs.map → client-CD3om3R0.mjs.map} +1 -1
- package/dist/{command-helpers-DTpEJCgI.mjs → command-helpers-CoceqqMl.mjs} +221 -42
- package/dist/command-helpers-CoceqqMl.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 +5 -6
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.d.mts.map +1 -1
- package/dist/commands/db-sign.mjs +12 -9
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +12 -10
- 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 +8 -9
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.mjs +1 -1
- package/dist/commands/migration-graph.d.mts +11 -2
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +15 -29
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.d.mts +59 -48
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +2 -2
- package/dist/commands/migration-log.d.mts +10 -1
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +10 -14
- package/dist/commands/migration-log.mjs.map +1 -1
- package/dist/commands/migration-new.mjs +5 -6
- package/dist/commands/migration-new.mjs.map +1 -1
- 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 +1 -1
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +7 -28
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +10 -7
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/{contract-at-errors-B98TC1wK.mjs → contract-at-errors-Bhf2jnkp.mjs} +2 -2
- package/dist/{contract-at-errors-B98TC1wK.mjs.map → contract-at-errors-Bhf2jnkp.mjs.map} +1 -1
- package/dist/{contract-emit-CS3vF-w9.mjs → contract-emit-C47r1loe.mjs} +4 -5
- package/dist/{contract-emit-CS3vF-w9.mjs.map → contract-emit-C47r1loe.mjs.map} +1 -1
- package/dist/{contract-emit-BWLCn2PH.mjs → contract-emit-DxEfEc-M.mjs} +16 -5
- package/dist/{contract-emit-BWLCn2PH.mjs.map → contract-emit-DxEfEc-M.mjs.map} +1 -1
- package/dist/{contract-enrichment-XmUPhmsS.mjs → contract-enrichment-a0V5Y_mL.mjs} +1 -1
- package/dist/{contract-enrichment-XmUPhmsS.mjs.map → contract-enrichment-a0V5Y_mL.mjs.map} +1 -1
- package/dist/{contract-infer-BtefFYF-.mjs → contract-infer-B5EhTqdR.mjs} +3 -3
- package/dist/{contract-infer-BtefFYF-.mjs.map → contract-infer-B5EhTqdR.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-DX_1n2SA.mjs → contract-space-aggregate-loader-lafgkTwG.mjs} +81 -4
- package/dist/contract-space-aggregate-loader-lafgkTwG.mjs.map +1 -0
- package/dist/{db-verify-aHw2nzH2.mjs → db-verify-B7fbkGnp.mjs} +5 -6
- package/dist/{db-verify-aHw2nzH2.mjs.map → db-verify-B7fbkGnp.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +3 -3
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{extension-pack-inputs-BiY86HbQ.mjs → extension-pack-inputs-IDvjRCi3.mjs} +1 -1
- package/dist/{extension-pack-inputs-BiY86HbQ.mjs.map → extension-pack-inputs-IDvjRCi3.mjs.map} +1 -1
- package/dist/{framework-components-BwuEBcyk.mjs → framework-components-R_O3y5IW.mjs} +2 -2
- package/dist/{framework-components-BwuEBcyk.mjs.map → framework-components-R_O3y5IW.mjs.map} +1 -1
- package/dist/global-flags-2SPgqWma.d.mts +34 -0
- package/dist/global-flags-2SPgqWma.d.mts.map +1 -0
- package/dist/{graph-render-eJDcLWny.mjs → graph-render-rFAqZujX.mjs} +2 -2
- package/dist/{graph-render-eJDcLWny.mjs.map → graph-render-rFAqZujX.mjs.map} +1 -1
- package/dist/{init-DOE4Q9YK.mjs → init-BQNpPozW.mjs} +4 -5
- package/dist/{init-DOE4Q9YK.mjs.map → init-BQNpPozW.mjs.map} +1 -1
- package/dist/{inspect-live-schema-IS8jWaJy.mjs → inspect-live-schema-CQJnuPgD.mjs} +4 -5
- package/dist/{inspect-live-schema-IS8jWaJy.mjs.map → inspect-live-schema-CQJnuPgD.mjs.map} +1 -1
- package/dist/{migration-check-BFdael8w.mjs → migration-check-CKfQlAWR.mjs} +5 -5
- package/dist/{migration-check-BFdael8w.mjs.map → migration-check-CKfQlAWR.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-DojkenVv.mjs → migration-command-scaffold-CE931d1-.mjs} +4 -5
- package/dist/{migration-command-scaffold-DojkenVv.mjs.map → migration-command-scaffold-CE931d1-.mjs.map} +1 -1
- package/dist/{migration-list-hj86sCtZ.mjs → migration-list-A3bJ4j5e.mjs} +181 -47
- package/dist/migration-list-A3bJ4j5e.mjs.map +1 -0
- package/dist/{migration-plan-Bt6wxUIv.mjs → migration-plan-ZZm8C0s-.mjs} +8 -9
- package/dist/{migration-plan-Bt6wxUIv.mjs.map → migration-plan-ZZm8C0s-.mjs.map} +1 -1
- package/dist/{migration-types-D2FW63pr.d.mts → migration-types-q64xAI_J.d.mts} +1 -1
- package/dist/{migration-types-D2FW63pr.d.mts.map → migration-types-q64xAI_J.d.mts.map} +1 -1
- package/dist/{migrations-CVLh0Kv4.mjs → migrations-CjO1DsYe.mjs} +2 -2
- package/dist/{migrations-CVLh0Kv4.mjs.map → migrations-CjO1DsYe.mjs.map} +1 -1
- package/dist/{output-CF_hqzI-.mjs → output-DEg3SSnJ.mjs} +1 -1
- package/dist/{output-CF_hqzI-.mjs.map → output-DEg3SSnJ.mjs.map} +1 -1
- package/dist/{progress-adapter-xASh41wr.mjs → progress-adapter-C644QK8l.mjs} +1 -1
- package/dist/{progress-adapter-xASh41wr.mjs.map → progress-adapter-C644QK8l.mjs.map} +1 -1
- package/dist/{ref-advancement-DRh5Nquq.mjs → ref-advancement-DUZqsue6.mjs} +1 -1
- package/dist/{ref-advancement-DRh5Nquq.mjs.map → ref-advancement-DUZqsue6.mjs.map} +1 -1
- package/dist/terminal-ui-sLZt2cxc.d.mts +133 -0
- package/dist/terminal-ui-sLZt2cxc.d.mts.map +1 -0
- package/dist/{types-BuatV9YW.d.mts → types-DK-ge7eR.d.mts} +1 -1
- package/dist/{types-BuatV9YW.d.mts.map → types-DK-ge7eR.d.mts.map} +1 -1
- package/dist/{verify-BiWm4XwD.mjs → verify-vl983Ed-.mjs} +2 -2
- package/dist/{verify-BiWm4XwD.mjs.map → verify-vl983Ed-.mjs.map} +1 -1
- package/package.json +11 -11
- package/dist/cli-errors-DQY629C7.mjs +0 -220
- package/dist/cli-errors-DQY629C7.mjs.map +0 -1
- package/dist/command-helpers-DTpEJCgI.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-DX_1n2SA.mjs.map +0 -1
- package/dist/global-flags-Bo6nCRUS.d.mts +0 -15
- package/dist/global-flags-Bo6nCRUS.d.mts.map +0 -1
- package/dist/glyph-mode-VIjULGFF.d.mts +0 -5
- package/dist/glyph-mode-VIjULGFF.d.mts.map +0 -1
- package/dist/migration-list-hj86sCtZ.mjs.map +0 -1
- package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
|
@@ -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 {
|
|
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-CoceqqMl.mjs";
|
|
2
|
+
import { t as inspectLiveSchema } from "../inspect-live-schema-CQJnuPgD.mjs";
|
|
3
|
+
import { n as formatIntrospectOutput, t as formatIntrospectJson } from "../verify-vl983Ed-.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
//#region src/commands/db-schema.ts
|
|
6
6
|
function toIntrospectSchemaResult(result) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-sign.d.mts","names":[],"sources":["../../src/commands/db-sign.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"db-sign.d.mts","names":[],"sources":["../../src/commands/db-sign.ts"],"mappings":";;;iBA4PgB,mBAAA,CAAA,GAAuB,OAAO"}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import { A as
|
|
3
|
-
import {
|
|
4
|
-
import { t as
|
|
5
|
-
import {
|
|
6
|
-
import { a as formatSignJson, i as formatSchemaVerifyOutput, o as formatSignOutput, r as formatSchemaVerifyJson } from "../verify-
|
|
2
|
+
import { A as CliStructuredError, F as errorDatabaseConnectionRequired, L as errorDriverRequired, P as errorContractValidationFailed, R as errorFileNotFound, T as formatStyledHeader, X as errorRuntime, _ as createTerminalUI, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, l as setCommandDescriptions, nt as mapMigrationToolsError, o as resolveContractPath, rt as mapRefResolutionError, s as resolveMigrationPaths, t as addGlobalOptions, tt as errorUnexpected, u as setCommandExamples, y as handleResult } from "../command-helpers-CoceqqMl.mjs";
|
|
3
|
+
import { t as createProgressAdapter } from "../progress-adapter-C644QK8l.mjs";
|
|
4
|
+
import { a as ContractValidationError, t as createControlClient } from "../client-CD3om3R0.mjs";
|
|
5
|
+
import { r as buildReadAggregate } from "../contract-space-aggregate-loader-lafgkTwG.mjs";
|
|
6
|
+
import { a as formatSignJson, i as formatSchemaVerifyOutput, o as formatSignOutput, r as formatSchemaVerifyJson } from "../verify-vl983Ed-.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";
|
|
10
10
|
import { readFile } from "node:fs/promises";
|
|
11
11
|
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
12
|
-
import { readRefs } from "@prisma-next/migration-tools/refs";
|
|
13
12
|
import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
14
13
|
//#region src/commands/db-sign.ts
|
|
15
14
|
/**
|
|
@@ -46,11 +45,15 @@ async function executeDbSignCommand(contractArg, options, flags, ui) {
|
|
|
46
45
|
}
|
|
47
46
|
let contractJson;
|
|
48
47
|
if (effectiveContractArg) try {
|
|
49
|
-
const {
|
|
50
|
-
const
|
|
48
|
+
const { migrationsDir } = resolveMigrationPaths(options.config, config);
|
|
49
|
+
const loaded = await buildReadAggregate(config, { migrationsDir });
|
|
50
|
+
if (!loaded.ok) return notOk(loaded.failure);
|
|
51
|
+
const graph = loaded.value.aggregate.app.graph();
|
|
52
|
+
const bundles = loaded.value.aggregate.app.packages;
|
|
53
|
+
const refs = loaded.value.aggregate.app.refs;
|
|
51
54
|
const refResult = parseContractRef(effectiveContractArg, {
|
|
52
55
|
graph,
|
|
53
|
-
refs
|
|
56
|
+
refs
|
|
54
57
|
});
|
|
55
58
|
if (!refResult.ok) return notOk(mapRefResolutionError(refResult.failure));
|
|
56
59
|
const targetHash = refResult.value.hash;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-sign.mjs","names":[],"sources":["../../src/commands/db-sign.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type {\n SignDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { readRefs } from '@prisma-next/migration-tools/refs';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n loadMigrationPackages,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport {\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatSignJson,\n formatSignOutput,\n} from '../utils/formatters/verify';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface DbSignOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly contract?: string;\n}\n\n/**\n * Failure type for db sign command.\n * Either an infrastructure error (CliStructuredError) or a logical failure (schema verification failed).\n */\ntype DbSignFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\n/**\n * Executes the db sign command and returns a structured Result.\n * Success: SignDatabaseResult (sign happened)\n * Failure: CliStructuredError (infra error) or VerifyDatabaseSchemaResult (schema mismatch)\n */\nasync function executeDbSignCommand(\n contractArg: string | undefined,\n options: DbSignOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<SignDatabaseResult, DbSignFailure>> {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n const effectiveContractArg = contractArg ?? options.contract;\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: effectiveContractArg ?? contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n }\n const header = formatStyledHeader({\n command: 'db sign',\n description: 'Sign the database with your contract so you can safely run queries',\n url: 'https://pris.ly/db-sign',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let contractJson: Record<string, unknown>;\n\n if (effectiveContractArg) {\n try {\n const { appMigrationsDir, refsDir } = resolveMigrationPaths(options.config, config);\n const { bundles, graph } = await loadMigrationPackages(appMigrationsDir);\n const refs = await readRefs(refsDir);\n const refResult = parseContractRef(effectiveContractArg, { 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 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 } else {\n const defaultRaw = await readFile(contractPathAbsolute, 'utf-8');\n const defaultContract = JSON.parse(defaultRaw) as Record<string, unknown>;\n const storageHash = (defaultContract['storage'] as Record<string, unknown> | undefined)?.[\n 'storageHash'\n ];\n if (storageHash === targetHash) {\n contractJson = defaultContract;\n } else {\n return notOk(\n errorRuntime(`No contract file found for hash \"${targetHash}\"`, {\n why: `Resolved contract reference \"${effectiveContractArg}\" to hash \"${targetHash}\" but no migration produces that hash and the emitted contract does not match.`,\n fix: 'Ensure the target contract exists on disk — either as a migration endpoint or as the emitted contract.json.',\n }),\n );\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));\n if (error instanceof CliStructuredError) return notOk(error);\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to resolve contract reference: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n } else {\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db sign (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'db sign',\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db sign' }));\n }\n\n // Create control client\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 // Create progress adapter\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Step 1: Schema verification - connect here\n const schemaVerifyResult = await client.schemaVerify({\n contract: contractJson,\n strict: false,\n connection: dbConnection,\n onProgress,\n });\n\n // If schema verification failed, return as failure\n if (!schemaVerifyResult.ok) {\n return notOk(schemaVerifyResult);\n }\n\n // Step 2: Sign (already connected from schemaVerify)\n const signResult = await client.sign({\n contract: contractJson,\n contractPath,\n configPath,\n onProgress,\n });\n\n return ok(signResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\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 // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db sign: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbSignCommand(): Command {\n const command = new Command('sign');\n setCommandDescriptions(\n command,\n 'Sign the database with your contract so you can safely run queries',\n 'Verifies that your database schema satisfies the emitted contract, and if so, writes or\\n' +\n 'updates the database signature. This command is idempotent and safe to run\\n' +\n 'in CI/deployment pipelines. The signature records that this database instance is aligned\\n' +\n 'with a specific contract version.',\n );\n setCommandExamples(command, [\n 'prisma-next db sign --db $DATABASE_URL',\n 'prisma-next db sign production --db $DATABASE_URL',\n 'prisma-next db sign --contract production --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .argument('[contract]', 'Contract reference (hash, prefix, ref name, or migration dir name)')\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--contract <contract>',\n 'Contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .action(async (positionalContract: string | undefined, options: DbSignOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n\n if (positionalContract && options.contract) {\n process.stderr.write(\n 'Cannot specify both a positional contract argument and --contract flag.\\n',\n );\n process.exit(2);\n return;\n }\n\n const ui = createTerminalUI(flags);\n\n const result = await executeDbSignCommand(positionalContract, options, flags, ui);\n\n if (result.ok) {\n // Success - format sign output\n if (flags.json) {\n ui.output(formatSignJson(result.value));\n } else {\n const output = formatSignOutput(result.value, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(0);\n }\n\n // Failure - determine type and handle appropriately\n const failure = result.failure;\n\n if (failure instanceof CliStructuredError) {\n // Infrastructure error - use standard handler\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n // Schema verification failed - format and print schema verification output\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(failure));\n } else {\n const output = formatSchemaVerifyOutput(failure, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"db-sign.mjs","names":[],"sources":["../../src/commands/db-sign.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type {\n SignDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { buildReadAggregate } from '../utils/contract-space-aggregate-loader';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport {\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatSignJson,\n formatSignOutput,\n} from '../utils/formatters/verify';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface DbSignOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly contract?: string;\n}\n\n/**\n * Failure type for db sign command.\n * Either an infrastructure error (CliStructuredError) or a logical failure (schema verification failed).\n */\ntype DbSignFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\n/**\n * Executes the db sign command and returns a structured Result.\n * Success: SignDatabaseResult (sign happened)\n * Failure: CliStructuredError (infra error) or VerifyDatabaseSchemaResult (schema mismatch)\n */\nasync function executeDbSignCommand(\n contractArg: string | undefined,\n options: DbSignOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<SignDatabaseResult, DbSignFailure>> {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n const effectiveContractArg = contractArg ?? options.contract;\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: effectiveContractArg ?? contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n }\n const header = formatStyledHeader({\n command: 'db sign',\n description: 'Sign the database with your contract so you can safely run queries',\n url: 'https://pris.ly/db-sign',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let contractJson: Record<string, unknown>;\n\n if (effectiveContractArg) {\n try {\n const { migrationsDir } = resolveMigrationPaths(options.config, config);\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(effectiveContractArg, { 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 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 } else {\n const defaultRaw = await readFile(contractPathAbsolute, 'utf-8');\n const defaultContract = JSON.parse(defaultRaw) as Record<string, unknown>;\n const storageHash = (defaultContract['storage'] as Record<string, unknown> | undefined)?.[\n 'storageHash'\n ];\n if (storageHash === targetHash) {\n contractJson = defaultContract;\n } else {\n return notOk(\n errorRuntime(`No contract file found for hash \"${targetHash}\"`, {\n why: `Resolved contract reference \"${effectiveContractArg}\" to hash \"${targetHash}\" but no migration produces that hash and the emitted contract does not match.`,\n fix: 'Ensure the target contract exists on disk — either as a migration endpoint or as the emitted contract.json.',\n }),\n );\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));\n if (error instanceof CliStructuredError) return notOk(error);\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to resolve contract reference: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n } else {\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db sign (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'db sign',\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db sign' }));\n }\n\n // Create control client\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 // Create progress adapter\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Step 1: Schema verification - connect here\n const schemaVerifyResult = await client.schemaVerify({\n contract: contractJson,\n strict: false,\n connection: dbConnection,\n onProgress,\n });\n\n // If schema verification failed, return as failure\n if (!schemaVerifyResult.ok) {\n return notOk(schemaVerifyResult);\n }\n\n // Step 2: Sign (already connected from schemaVerify)\n const signResult = await client.sign({\n contract: contractJson,\n contractPath,\n configPath,\n onProgress,\n });\n\n return ok(signResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\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 // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db sign: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbSignCommand(): Command {\n const command = new Command('sign');\n setCommandDescriptions(\n command,\n 'Sign the database with your contract so you can safely run queries',\n 'Verifies that your database schema satisfies the emitted contract, and if so, writes or\\n' +\n 'updates the database signature. This command is idempotent and safe to run\\n' +\n 'in CI/deployment pipelines. The signature records that this database instance is aligned\\n' +\n 'with a specific contract version.',\n );\n setCommandExamples(command, [\n 'prisma-next db sign --db $DATABASE_URL',\n 'prisma-next db sign production --db $DATABASE_URL',\n 'prisma-next db sign --contract production --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .argument('[contract]', 'Contract reference (hash, prefix, ref name, or migration dir name)')\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--contract <contract>',\n 'Contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .action(async (positionalContract: string | undefined, options: DbSignOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n\n if (positionalContract && options.contract) {\n process.stderr.write(\n 'Cannot specify both a positional contract argument and --contract flag.\\n',\n );\n process.exit(2);\n return;\n }\n\n const ui = createTerminalUI(flags);\n\n const result = await executeDbSignCommand(positionalContract, options, flags, ui);\n\n if (result.ok) {\n // Success - format sign output\n if (flags.json) {\n ui.output(formatSignJson(result.value));\n } else {\n const output = formatSignOutput(result.value, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(0);\n }\n\n // Failure - determine type and handle appropriately\n const failure = result.failure;\n\n if (failure instanceof CliStructuredError) {\n // Infrastructure error - use standard handler\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n // Schema verification failed - format and print schema verification output\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(failure));\n } else {\n const output = formatSchemaVerifyOutput(failure, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1 +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":";;;iBAiRgB,qBAAA,CAAA,GAAyB,OAAO"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import { a as
|
|
3
|
-
import {
|
|
4
|
-
import { i as formatMigrationPlanOutput, n as formatMigrationApplyOutput, r as formatMigrationJson } from "../migrations-
|
|
5
|
-
import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-
|
|
6
|
-
import { i as readContractIR, n as computeRefAdvancementName, t as buildRefAdvancementFields } from "../ref-advancement-
|
|
1
|
+
import { A as CliStructuredError, I as errorDestructiveChanges, P as errorContractValidationFailed, U as errorMigrationPlanningFailed, Y as errorRunnerFailed, _ as createTerminalUI, c as sanitizeErrorMessage, g as parseGlobalFlagsOrExit, j as ERROR_CODE_DESTRUCTIVE_CHANGES, l as setCommandDescriptions, nt as mapMigrationToolsError, rt as mapRefResolutionError, s as resolveMigrationPaths, tt as errorUnexpected, u as setCommandExamples, y as handleResult } from "../command-helpers-CoceqqMl.mjs";
|
|
2
|
+
import { a as ContractValidationError } from "../client-CD3om3R0.mjs";
|
|
3
|
+
import { r as buildReadAggregate } from "../contract-space-aggregate-loader-lafgkTwG.mjs";
|
|
4
|
+
import { i as formatMigrationPlanOutput, n as formatMigrationApplyOutput, r as formatMigrationJson } from "../migrations-CjO1DsYe.mjs";
|
|
5
|
+
import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-CE931d1-.mjs";
|
|
6
|
+
import { i as readContractIR, n as computeRefAdvancementName, t as buildRefAdvancementFields } from "../ref-advancement-DUZqsue6.mjs";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
9
9
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
10
10
|
import { join } from "pathe";
|
|
11
11
|
import { readFile } from "node:fs/promises";
|
|
12
12
|
import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
|
|
13
|
-
import { readRefs } from "@prisma-next/migration-tools/refs";
|
|
14
13
|
import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
15
14
|
//#region src/commands/db-update.ts
|
|
16
15
|
/**
|
|
@@ -47,10 +46,13 @@ async function executeDbUpdateCommand(options, flags, ui, startTime) {
|
|
|
47
46
|
const { client, config, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;
|
|
48
47
|
let { contractJson } = ctxResult.value;
|
|
49
48
|
let contractJsonPathForSnapshot = contractPathAbsolute;
|
|
50
|
-
const { migrationsDir,
|
|
49
|
+
const { migrationsDir, refsDir } = resolveMigrationPaths(options.config, config);
|
|
51
50
|
if (options.to) try {
|
|
52
|
-
const
|
|
53
|
-
|
|
51
|
+
const loaded = await buildReadAggregate(config, { migrationsDir });
|
|
52
|
+
if (!loaded.ok) return notOk(loaded.failure);
|
|
53
|
+
const graph = loaded.value.aggregate.app.graph();
|
|
54
|
+
const bundles = loaded.value.aggregate.app.packages;
|
|
55
|
+
const refs = loaded.value.aggregate.app.refs;
|
|
54
56
|
const refResult = parseContractRef(options.to, {
|
|
55
57
|
graph,
|
|
56
58
|
refs
|
|
@@ -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 { readRefs } 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 { 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 loadMigrationPackages,\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 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, appMigrationsDir, refsDir } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n if (options.to) {\n try {\n const { bundles, graph } = await loadMigrationPackages(appMigrationsDir);\n const refs = await readRefs(refsDir);\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 ...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,2 +1,2 @@
|
|
|
1
|
-
import { t as createDbVerifyCommand } from "../db-verify-
|
|
1
|
+
import { t as createDbVerifyCommand } from "../db-verify-B7fbkGnp.mjs";
|
|
2
2
|
export { createDbVerifyCommand };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as MigrationApplyPathDecision, t as AggregatePerSpaceExecutionEntry } from "../types-
|
|
1
|
+
import { T as MigrationApplyPathDecision, t as AggregatePerSpaceExecutionEntry } from "../types-DK-ge7eR.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
|
|
4
4
|
//#region src/commands/migrate.d.ts
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import { A as
|
|
3
|
-
import {
|
|
4
|
-
import { t as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { t as mapContractAtError } from "../contract-at-errors-B98TC1wK.mjs";
|
|
2
|
+
import { $ as errorTargetMigrationNotSupported, A as CliStructuredError, F as errorDatabaseConnectionRequired, L as errorDriverRequired, P as errorContractValidationFailed, R as errorFileNotFound, T as formatStyledHeader, V as errorMarkerMismatch, W as errorPathUnreachable, X as errorRuntime, _ as createTerminalUI, f as targetSupportsMigrations, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, l as setCommandDescriptions, n as collectDeclaredInvariants, nt as mapMigrationToolsError, o as resolveContractPath, rt as mapRefResolutionError, s as resolveMigrationPaths, t as addGlobalOptions, tt as errorUnexpected, u as setCommandExamples, y as handleResult } from "../command-helpers-CoceqqMl.mjs";
|
|
3
|
+
import { t as createControlClient } from "../client-CD3om3R0.mjs";
|
|
4
|
+
import { t as toDeclaredExtensionsFromRaw } from "../extension-pack-inputs-IDvjRCi3.mjs";
|
|
5
|
+
import { a as loadContractSpaceAggregateForCli, o as refuseContractSpaceIntegrity } from "../contract-space-aggregate-loader-lafgkTwG.mjs";
|
|
6
|
+
import { t as formatMigrationApplyCommandOutput } from "../migrations-CjO1DsYe.mjs";
|
|
7
|
+
import { i as readContractIR, r as executeRefAdvancement } from "../ref-advancement-DUZqsue6.mjs";
|
|
8
|
+
import { t as mapContractAtError } from "../contract-at-errors-Bhf2jnkp.mjs";
|
|
10
9
|
import { Command } from "commander";
|
|
11
10
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
12
11
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
13
12
|
import { readFile } from "node:fs/promises";
|
|
14
13
|
import { createControlStack } from "@prisma-next/framework-components/control";
|
|
15
|
-
import { findLatestMigration, isGraphNode } from "@prisma-next/migration-tools/migration-graph";
|
|
16
14
|
import { MigrationToolsError, errorUnknownInvariant } from "@prisma-next/migration-tools/errors";
|
|
15
|
+
import { findLatestMigration, isGraphNode } from "@prisma-next/migration-tools/migration-graph";
|
|
17
16
|
import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
18
17
|
//#region src/commands/migrate.ts
|
|
19
18
|
function mapApplyFailure(failure) {
|
|
@@ -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 AggregatePerSpaceExecutionEntry,\n MigrationApplyFailure,\n MigrationApplyPathDecision,\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 AggregatePerSpaceExecutionEntry[];\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 AggregatePerSpaceExecutionEntry,\n MigrationApplyFailure,\n MigrationApplyPathDecision,\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 AggregatePerSpaceExecutionEntry[];\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-CKfQlAWR.mjs";
|
|
2
2
|
export { createMigrationCheckCommand };
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { N as CliStructuredError } from "../types-DK-ge7eR.mjs";
|
|
2
|
+
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-2SPgqWma.mjs";
|
|
3
|
+
import { n as StatusRef } from "../migration-types-q64xAI_J.mjs";
|
|
4
|
+
import { t as TerminalUI } from "../terminal-ui-sLZt2cxc.mjs";
|
|
2
5
|
import { Command } from "commander";
|
|
6
|
+
import { Result } from "@prisma-next/utils/result";
|
|
3
7
|
import { MigrationGraph } from "@prisma-next/migration-tools/graph";
|
|
4
8
|
|
|
5
9
|
//#region src/commands/migration-graph.d.ts
|
|
10
|
+
interface MigrationGraphOptions extends CommonCommandOptions {
|
|
11
|
+
readonly config?: string;
|
|
12
|
+
readonly dot?: boolean;
|
|
13
|
+
}
|
|
6
14
|
interface MigrationGraphResult {
|
|
7
15
|
readonly ok: true;
|
|
8
16
|
readonly graph: MigrationGraph;
|
|
@@ -10,7 +18,8 @@ interface MigrationGraphResult {
|
|
|
10
18
|
readonly refs: readonly StatusRef[];
|
|
11
19
|
readonly summary: string;
|
|
12
20
|
}
|
|
21
|
+
declare function executeMigrationGraphCommand(options: MigrationGraphOptions, flags: GlobalFlags, ui: TerminalUI): Promise<Result<MigrationGraphResult, CliStructuredError>>;
|
|
13
22
|
declare function createMigrationGraphCommand(): Command;
|
|
14
23
|
//#endregion
|
|
15
|
-
export { MigrationGraphResult, createMigrationGraphCommand };
|
|
24
|
+
export { MigrationGraphResult, createMigrationGraphCommand, executeMigrationGraphCommand };
|
|
16
25
|
//# sourceMappingURL=migration-graph.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-graph.d.mts","names":[],"sources":["../../src/commands/migration-graph.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"migration-graph.d.mts","names":[],"sources":["../../src/commands/migration-graph.ts"],"mappings":";;;;;;;;;UAuBU,qBAAA,SAA8B,oBAAoB;EAAA,SACjD,MAAA;EAAA,SACA,GAAA;AAAA;AAAA,UAGM,oBAAA;EAAA,SACN,EAAA;EAAA,SACA,KAAA,EAAO,cAAA;EAAA,SACP,YAAA;EAAA,SACA,IAAA,WAAe,SAAS;EAAA,SACxB,OAAA;AAAA;AAAA,iBAGW,4BAAA,CACpB,OAAA,EAAS,qBAAA,EACT,KAAA,EAAO,WAAA,EACP,EAAA,EAAI,UAAA,GACH,OAAA,CAAQ,MAAA,CAAO,oBAAA,EAAsB,kBAAA;AAAA,iBA0CxB,2BAAA,CAAA,GAA+B,OAAO"}
|