prisma-next 0.12.0-dev.33 → 0.12.0-dev.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +5 -5
- package/dist/{client-xeWpMlq1.mjs → client-CcqChq9N.mjs} +42 -42
- package/dist/client-CcqChq9N.mjs.map +1 -0
- package/dist/command-helpers-DK_5ItoJ.mjs.map +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +2 -2
- package/dist/commands/db-schema.mjs +1 -1
- package/dist/commands/db-sign.mjs +1 -1
- package/dist/commands/db-update.mjs +2 -2
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +2 -2
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +2 -2
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-list.d.mts +1 -1
- package/dist/commands/migration-log.d.mts +1 -1
- package/dist/commands/migration-log.mjs +1 -1
- package/dist/commands/migration-show.d.mts +1 -1
- package/dist/commands/migration-show.mjs +1 -1
- package/dist/commands/migration-status.mjs +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/{contract-infer-2wtPflGH.mjs → contract-infer-DaHH7CGX.mjs} +2 -2
- package/dist/{contract-infer-2wtPflGH.mjs.map → contract-infer-DaHH7CGX.mjs.map} +1 -1
- package/dist/{db-verify-CxHiSiTG.mjs → db-verify-DppLAhYT.mjs} +2 -2
- package/dist/{db-verify-CxHiSiTG.mjs.map → db-verify-DppLAhYT.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +2 -2
- package/dist/exports/control-api.mjs +1 -1
- package/dist/{inspect-live-schema-RekOwfi5.mjs → inspect-live-schema-CfOSPCmR.mjs} +2 -2
- package/dist/{inspect-live-schema-RekOwfi5.mjs.map → inspect-live-schema-CfOSPCmR.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-ApB3NxWY.mjs → migration-command-scaffold-CIxCqBXa.mjs} +2 -2
- package/dist/{migration-command-scaffold-ApB3NxWY.mjs.map → migration-command-scaffold-CIxCqBXa.mjs.map} +1 -1
- package/dist/{migration-log-DD_vCbYW.mjs → migration-log-CwP41Cke.mjs} +2 -2
- package/dist/{migration-log-DD_vCbYW.mjs.map → migration-log-CwP41Cke.mjs.map} +1 -1
- package/dist/{migration-status-qV8ctwPy.mjs → migration-status-GMRiiLFP.mjs} +2 -2
- package/dist/{migration-status-qV8ctwPy.mjs.map → migration-status-GMRiiLFP.mjs.map} +1 -1
- package/dist/{types-Mh7mdPHM.d.mts → types-Cculk5KV.d.mts} +32 -30
- package/dist/{types-Mh7mdPHM.d.mts.map → types-Cculk5KV.d.mts.map} +1 -1
- package/package.json +11 -11
- package/dist/client-xeWpMlq1.mjs.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createContractInferCommand } from "../contract-infer-
|
|
1
|
+
import { t as createContractInferCommand } from "../contract-infer-DaHH7CGX.mjs";
|
|
2
2
|
export { createContractInferCommand };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as formatMigrationApplyOutput, F as CliStructuredError, T as formatMigrationPlanOutput, Y as errorMigrationPlanningFailed, _ as createTerminalUI, c as sanitizeErrorMessage, ct as mapMigrationToolsError, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, nt as errorRuntime, s as resolveMigrationPaths, st as errorUnexpected, tt as errorRunnerFailed, u as setCommandExamples, w as formatMigrationJson, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-DK_5ItoJ.mjs";
|
|
2
|
-
import { a as ContractValidationError } from "../client-
|
|
3
|
-
import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-
|
|
2
|
+
import { a as ContractValidationError } from "../client-CcqChq9N.mjs";
|
|
3
|
+
import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-CIxCqBXa.mjs";
|
|
4
4
|
import { i as readContractIR, n as computeRefAdvancementName, t as buildRefAdvancementFields } from "../ref-advancement-V1o-9LVK.mjs";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as createTerminalUI, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "../command-helpers-DK_5ItoJ.mjs";
|
|
2
|
-
import { t as inspectLiveSchema } from "../inspect-live-schema-
|
|
2
|
+
import { t as inspectLiveSchema } from "../inspect-live-schema-CfOSPCmR.mjs";
|
|
3
3
|
import { n as formatIntrospectOutput, t as formatIntrospectJson } from "../verify-BdI-BgYi.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
//#region src/commands/db-schema.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { A as formatStyledHeader, B as errorDatabaseConnectionRequired, F as CliStructuredError, H as errorDriverRequired, U as errorFileNotFound, _ as createTerminalUI, ct as mapMigrationToolsError, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, l as setCommandDescriptions, lt as mapRefResolutionError, nt as errorRuntime, o as resolveContractPath, s as resolveMigrationPaths, st as errorUnexpected, t as addGlobalOptions, u as setCommandExamples, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-DK_5ItoJ.mjs";
|
|
3
3
|
import { t as createProgressAdapter } from "../progress-adapter-C644QK8l.mjs";
|
|
4
|
-
import { a as ContractValidationError, t as createControlClient } from "../client-
|
|
4
|
+
import { a as ContractValidationError, t as createControlClient } from "../client-CcqChq9N.mjs";
|
|
5
5
|
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-Dbr3-jHF.mjs";
|
|
6
6
|
import { a as formatSignJson, i as formatSchemaVerifyOutput, o as formatSignOutput, r as formatSchemaVerifyJson } from "../verify-BdI-BgYi.mjs";
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { C as formatMigrationApplyOutput, F as CliStructuredError, I as ERROR_CODE_DESTRUCTIVE_CHANGES, T as formatMigrationPlanOutput, V as errorDestructiveChanges, Y as errorMigrationPlanningFailed, _ as createTerminalUI, c as sanitizeErrorMessage, ct as mapMigrationToolsError, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, lt as mapRefResolutionError, s as resolveMigrationPaths, st as errorUnexpected, tt as errorRunnerFailed, u as setCommandExamples, w as formatMigrationJson, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-DK_5ItoJ.mjs";
|
|
2
|
-
import { a as ContractValidationError } from "../client-
|
|
2
|
+
import { a as ContractValidationError } from "../client-CcqChq9N.mjs";
|
|
3
3
|
import { n as buildReadAggregate } from "../contract-space-aggregate-loader-Dbr3-jHF.mjs";
|
|
4
|
-
import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-
|
|
4
|
+
import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-CIxCqBXa.mjs";
|
|
5
5
|
import { i as readContractIR, n as computeRefAdvancementName, t as buildRefAdvancementFields } from "../ref-advancement-V1o-9LVK.mjs";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createDbVerifyCommand } from "../db-verify-
|
|
1
|
+
import { t as createDbVerifyCommand } from "../db-verify-DppLAhYT.mjs";
|
|
2
2
|
export { createDbVerifyCommand };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as PerSpaceExecutionEntry, w as
|
|
1
|
+
import { E as PerSpaceExecutionEntry, w as MigratePathDecision } from "../types-Cculk5KV.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
|
|
4
4
|
//#region src/commands/migrate.d.ts
|
|
@@ -17,7 +17,7 @@ interface MigrateResult {
|
|
|
17
17
|
}[];
|
|
18
18
|
readonly summary: string;
|
|
19
19
|
readonly perSpace: readonly PerSpaceExecutionEntry[];
|
|
20
|
-
readonly pathDecision?:
|
|
20
|
+
readonly pathDecision?: MigratePathDecision;
|
|
21
21
|
readonly timings: {
|
|
22
22
|
readonly total: number;
|
|
23
23
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.mts","names":[],"sources":["../../src/commands/migrate.ts"],"mappings":";;;;UA+DiB,aAAA;EAAA,SACN,EAAA;EAAA,SACA,iBAAA;EAAA,SACA,eAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA;IAAA,SACE,OAAA;IAAA,SACA,OAAA;IAAA,SACA,aAAA;IAAA,SACA,IAAA;IAAA,SACA,EAAA;IAAA,SACA,kBAAA;EAAA;EAAA,SAEF,OAAA;EAAA,SACA,QAAA,WAAmB,sBAAA;EAAA,SACnB,YAAA,GAAe,
|
|
1
|
+
{"version":3,"file":"migrate.d.mts","names":[],"sources":["../../src/commands/migrate.ts"],"mappings":";;;;UA+DiB,aAAA;EAAA,SACN,EAAA;EAAA,SACA,iBAAA;EAAA,SACA,eAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA;IAAA,SACE,OAAA;IAAA,SACA,OAAA;IAAA,SACA,aAAA;IAAA,SACA,IAAA;IAAA,SACA,EAAA;IAAA,SACA,kBAAA;EAAA;EAAA,SAEF,OAAA;EAAA,SACA,QAAA,WAAmB,sBAAA;EAAA,SACnB,YAAA,GAAe,mBAAmB;EAAA,SAClC,OAAA;IAAA,SACE,KAAA;EAAA;EAAA,SAEF,WAAA;IAAA,SAAyB,IAAA;IAAA,SAAuB,IAAA;EAAA;AAAA;AAAA,iBAwS3C,oBAAA,CAAA,GAAwB,OAAO"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { A as formatStyledHeader, B as errorDatabaseConnectionRequired, F as CliStructuredError, H as errorDriverRequired, S as formatMigrationApplyCommandOutput, U as errorFileNotFound, X as errorPathUnreachable, _ as createTerminalUI, at as errorTargetMigrationNotSupported, ct as mapMigrationToolsError, f as targetSupportsMigrations, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, l as setCommandDescriptions, lt as mapRefResolutionError, n as collectDeclaredInvariants, nt as errorRuntime, o as resolveContractPath, q as errorMarkerMismatch, s as resolveMigrationPaths, st as errorUnexpected, t as addGlobalOptions, u as setCommandExamples, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-DK_5ItoJ.mjs";
|
|
3
|
-
import { t as createControlClient } from "../client-
|
|
3
|
+
import { t as createControlClient } from "../client-CcqChq9N.mjs";
|
|
4
4
|
import { t as toDeclaredExtensionsFromRaw } from "../extension-pack-inputs-IDvjRCi3.mjs";
|
|
5
5
|
import { a as refuseContractSpaceIntegrity, i as loadContractSpaceAggregateForCli } from "../contract-space-aggregate-loader-Dbr3-jHF.mjs";
|
|
6
6
|
import { i as readContractIR, r as executeRefAdvancement } from "../ref-advancement-V1o-9LVK.mjs";
|
|
@@ -147,7 +147,7 @@ async function executeMigrateCommand(options, flags, ui, startTime) {
|
|
|
147
147
|
return mapContractAtError(error, { artifactRole: "to" });
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
|
-
const applyResult = await client.
|
|
150
|
+
const applyResult = await client.migrate({
|
|
151
151
|
contract: applyContract,
|
|
152
152
|
migrationsDir,
|
|
153
153
|
...ifDefined("refHash", refEntry?.hash),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.mjs","names":[],"sources":["../../src/commands/migrate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { RefEntry } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type {\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n PerSpaceExecutionEntry,\n} from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorMarkerMismatch,\n errorPathUnreachable,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n collectDeclaredInvariants,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { mapContractAtError } from '../utils/contract-at-errors';\nimport {\n loadContractSpaceAggregateForCli,\n refuseContractSpaceIntegrity,\n} from '../utils/contract-space-aggregate-loader';\nimport { toDeclaredExtensionsFromRaw } from '../utils/extension-pack-inputs';\nimport { formatMigrationApplyCommandOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { executeRefAdvancement, readContractIR } from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrateCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly to?: string;\n readonly advanceRef?: string;\n}\n\nexport interface MigrateResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName: string;\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n readonly pathDecision?: MigrationApplyPathDecision;\n readonly timings: {\n readonly total: number;\n };\n readonly advancedRef?: { readonly name: string; readonly hash: string } | null;\n}\n\nfunction mapApplyFailure(failure: MigrationApplyFailure): CliStructuredErrorType {\n if (failure.code === 'MIGRATION_PATH_NOT_FOUND') {\n return errorPathUnreachable(failure);\n }\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the issue and re-run `prisma-next migrate --to <contract>` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nasync function executeMigrateCommand(\n options: MigrateCommandOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrateResult, CliStructuredErrorType>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsRelative, refsDir } = resolveMigrationPaths(\n options.config,\n config,\n );\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migrate (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migrate',\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: 'Config.driver is required for migrate',\n }),\n );\n }\n\n if (!targetSupportsMigrations(config.target)) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n const toArg = options.to;\n\n // Construct the family instance up-front so the on-disk contract read\n // crosses the serializer seam (`familyInstance.deserializeContract`) at\n // the read site. The downstream `client.migrationApply({ contract })`\n // re-validates internally (no harm — validation is idempotent), but\n // closing the gap at the read site is what makes the cast-pattern\n // lint enforceable and matches the other CLI commands. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n const contractPathAbsolute = resolveContractPath(config);\n let contractRaw: Contract;\n let contractContent: string;\n try {\n contractContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: 'Run `prisma-next contract emit` to generate a valid contract.json, then retry.',\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n try {\n contractRaw = familyInstance.deserializeContract(JSON.parse(contractContent) as unknown);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const loadedAggregate = await loadContractSpaceAggregateForCli({\n targetId: config.target.targetId,\n migrationsDir,\n appContract: contractRaw,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json) => familyInstance.deserializeContract(json),\n });\n if (!loadedAggregate.ok) {\n return notOk(loadedAggregate.failure);\n }\n const aggregate = loadedAggregate.value;\n const integrityFailure = refuseContractSpaceIntegrity(aggregate, {\n declaredExtensions: toDeclaredExtensionsFromRaw(\n (config.extensionPacks ?? []) as ReadonlyArray<unknown>,\n ),\n checkContracts: true,\n });\n if (integrityFailure) {\n return notOk(integrityFailure);\n }\n\n let refEntry: RefEntry | undefined;\n let refName: string | undefined;\n if (toArg) {\n const refs = aggregate.app.refs;\n const refResult = parseContractRef(toArg, { graph: aggregate.app.graph(), refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n if (refResult.value.provenance.kind === 'ref') {\n refName = refResult.value.provenance.refName;\n const resolved = refs[refName];\n if (resolved) refEntry = resolved;\n } else {\n refEntry = { hash: refResult.value.hash, invariants: [] };\n }\n }\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({\n label: 'database',\n value: maskConnectionUrl(dbConnection),\n });\n }\n if (toArg) {\n details.push({ label: 'to', value: toArg });\n }\n const header = formatStyledHeader({\n command: 'migrate',\n description: 'Apply planned migrations to advance the database',\n url: 'https://pris.ly/migrate',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n const appGraph = aggregate.app.graph();\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n try {\n await client.connect(dbConnection);\n\n const allMarkers = await client.readAllMarkers();\n const appMarker = allMarkers.get('app') ?? null;\n\n if (appMarker !== null && !isGraphNode(appMarker.storageHash, appGraph)) {\n return notOk(\n errorMarkerMismatch(\n appMarker.storageHash,\n [...appGraph.nodes].sort(),\n findLatestMigration(appGraph)?.to ?? null,\n ),\n );\n }\n\n if (refEntry && refEntry.invariants.length > 0) {\n const declared = collectDeclaredInvariants(appGraph);\n const known = new Set<string>(declared);\n for (const id of appMarker?.invariants ?? []) known.add(id);\n const unknown = refEntry.invariants.filter((id) => !known.has(id));\n if (unknown.length > 0) {\n return notOk(\n mapMigrationToolsError(\n errorUnknownInvariant({\n ...ifDefined('refName', toArg),\n unknown,\n declared: [...declared].sort(),\n }),\n ),\n );\n }\n }\n\n if (!flags.quiet && !flags.json) {\n ui.step('Loading contract spaces…');\n }\n\n // When `--to` resolves to an on-disk graph node with a matching bundle,\n // verify and apply against THAT bundle's destination contract via\n // `contractAt` — not the emitted `contract.json`. With `--to` omitted,\n // or a target with no matching bundle, the emitted contract stays the\n // apply contract (the only migrate-specific default). The same\n // `contractAt` artifacts feed the optional ref-advancement snapshot.\n let applyContract: Contract = contractRaw;\n let snapshotContractJson: Record<string, unknown> = JSON.parse(contractContent);\n let snapshotContractDts: string | undefined;\n if (toArg && refEntry) {\n const targetHash = refEntry.hash;\n const matchingBundle = aggregate.app.packages.find((p) => p.metadata.to === targetHash);\n if (matchingBundle) {\n try {\n const at = await aggregate.app.contractAt(\n targetHash,\n refName !== undefined ? { refName } : undefined,\n );\n applyContract = at.contract;\n snapshotContractJson = at.contractJson as Record<string, unknown>;\n snapshotContractDts = at.contractDts;\n } catch (error) {\n return mapContractAtError(error, { artifactRole: 'to' });\n }\n }\n }\n\n const applyResult = await client.migrationApply({\n contract: applyContract,\n migrationsDir,\n ...ifDefined('refHash', refEntry?.hash),\n ...(refEntry?.invariants ? { refInvariants: refEntry.invariants } : {}),\n ...(refEntry !== undefined ? ifDefined('refName', toArg) : {}),\n });\n\n if (!applyResult.ok) {\n return notOk(mapApplyFailure(applyResult.failure));\n }\n\n const { value } = applyResult;\n\n let advancedRef: { name: string; hash: string } | null = null;\n if (options.advanceRef !== undefined) {\n try {\n const contractIR =\n snapshotContractDts !== undefined\n ? { contract: snapshotContractJson, contractDts: snapshotContractDts }\n : await readContractIR(snapshotContractJson, contractPathAbsolute);\n advancedRef = await executeRefAdvancement(\n refsDir,\n options.advanceRef,\n value.markerHash,\n contractIR,\n );\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n return ok({\n ok: true,\n migrationsApplied: value.migrationsApplied,\n migrationsTotal: value.perSpace.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n perSpace: value.perSpace,\n ...ifDefined('pathDecision', value.pathDecision),\n timings: { total: Date.now() - startTime },\n advancedRef,\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migrate: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrateCommand(): Command {\n const command = new Command('migrate');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to advance the database',\n 'Walks every contract space (app + extensions) and applies pending\\n' +\n 'on-disk migrations in canonical order (extensions alphabetically,\\n' +\n 'then app). Graph-walks the on-disk migration graph for every space.\\n' +\n 'Use --to to target a specific contract (hash, ref name, migration dir).',\n );\n setCommandExamples(command, [\n 'prisma-next migrate --db $DATABASE_URL',\n 'prisma-next migrate --to production --db $DATABASE_URL',\n 'prisma-next migrate --to sha256:abc123 --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .option('--advance-ref <name>', 'Advance the named ref to the post-apply marker after success')\n .action(async (options: MigrateCommandOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const startTime = Date.now();\n\n const ui = createTerminalUI(flags);\n\n const result = await executeMigrateCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (migrateResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(migrateResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationApplyCommandOutput(migrateResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"migrate.mjs","names":[],"sources":["../../src/commands/migrate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { RefEntry } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type {\n MigrateFailure,\n MigratePathDecision,\n PerSpaceExecutionEntry,\n} from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorMarkerMismatch,\n errorPathUnreachable,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n collectDeclaredInvariants,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { mapContractAtError } from '../utils/contract-at-errors';\nimport {\n loadContractSpaceAggregateForCli,\n refuseContractSpaceIntegrity,\n} from '../utils/contract-space-aggregate-loader';\nimport { toDeclaredExtensionsFromRaw } from '../utils/extension-pack-inputs';\nimport { formatMigrationApplyCommandOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { executeRefAdvancement, readContractIR } from '../utils/ref-advancement';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrateCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly to?: string;\n readonly advanceRef?: string;\n}\n\nexport interface MigrateResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName: string;\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly perSpace: readonly PerSpaceExecutionEntry[];\n readonly pathDecision?: MigratePathDecision;\n readonly timings: {\n readonly total: number;\n };\n readonly advancedRef?: { readonly name: string; readonly hash: string } | null;\n}\n\nfunction mapApplyFailure(failure: MigrateFailure): 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.migrate({ 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.migrate({\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,4 +1,4 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
1
|
+
import { N as CliStructuredError } from "../types-Cculk5KV.mjs";
|
|
2
2
|
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DG4uY5tV.mjs";
|
|
3
3
|
import { t as TerminalUI } from "../terminal-ui-5Y6mrg93.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
1
|
+
import { N as CliStructuredError } from "../types-Cculk5KV.mjs";
|
|
2
2
|
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DG4uY5tV.mjs";
|
|
3
3
|
import { n as GlyphMode, t as TerminalUI } from "../terminal-ui-5Y6mrg93.mjs";
|
|
4
4
|
import { n as MigrationListResult, r as MigrationSpaceListEntry } from "../migration-list-types-DS63IdFd.mjs";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
1
|
+
import { N as CliStructuredError } from "../types-Cculk5KV.mjs";
|
|
2
2
|
import { n as GlobalFlags, t as CommonCommandOptions } from "../global-flags-DG4uY5tV.mjs";
|
|
3
3
|
import { t as TerminalUI } from "../terminal-ui-5Y6mrg93.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as executeMigrationLogCommand, t as createMigrationLogCommand } from "../migration-log-
|
|
1
|
+
import { n as executeMigrationLogCommand, t as createMigrationLogCommand } from "../migration-log-CwP41Cke.mjs";
|
|
2
2
|
export { createMigrationLogCommand, executeMigrationLogCommand };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
1
|
+
import { N as CliStructuredError } from "../types-Cculk5KV.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { Result } from "@prisma-next/utils/result";
|
|
4
4
|
import { OperationPreview } from "@prisma-next/framework-components/control";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { A as formatStyledHeader, E as formatMigrationShowOutput, U as errorFileNotFound, _ as createTerminalUI, d as setCommandSeeAlso, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, lt as mapRefResolutionError, nt as errorRuntime, o as resolveContractPath, s as resolveMigrationPaths, st as errorUnexpected, t as addGlobalOptions, u as setCommandExamples, y as handleResult, z as errorContractValidationFailed } from "../command-helpers-DK_5ItoJ.mjs";
|
|
3
|
-
import { t as createControlClient } from "../client-
|
|
3
|
+
import { t as createControlClient } from "../client-CcqChq9N.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
6
6
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as formatStatusSummary, i as formatStatusHumanOutput, n as buildStatusHeadline, r as createMigrationStatusCommand, t as buildNoPathSummary } from "../migration-status-
|
|
1
|
+
import { a as formatStatusSummary, i as formatStatusHumanOutput, n as buildStatusHeadline, r as createMigrationStatusCommand, t as buildNoPathSummary } from "../migration-status-GMRiiLFP.mjs";
|
|
2
2
|
export { buildNoPathSummary, buildStatusHeadline, createMigrationStatusCommand, formatStatusHumanOutput, formatStatusSummary };
|
package/dist/commands/ref.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as CliStructuredError } from "../types-
|
|
1
|
+
import { N as CliStructuredError } from "../types-Cculk5KV.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { Result } from "@prisma-next/utils/result";
|
|
4
4
|
import { RefEntry } from "@prisma-next/migration-tools/refs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as createTerminalUI, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "./command-helpers-DK_5ItoJ.mjs";
|
|
2
|
-
import { t as inspectLiveSchema } from "./inspect-live-schema-
|
|
2
|
+
import { t as inspectLiveSchema } from "./inspect-live-schema-CfOSPCmR.mjs";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
5
5
|
import { dirname, relative, resolve } from "pathe";
|
|
@@ -72,4 +72,4 @@ function createContractInferCommand() {
|
|
|
72
72
|
//#endregion
|
|
73
73
|
export { createContractInferCommand as t };
|
|
74
74
|
|
|
75
|
-
//# sourceMappingURL=contract-infer-
|
|
75
|
+
//# sourceMappingURL=contract-infer-DaHH7CGX.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-infer-
|
|
1
|
+
{"version":3,"file":"contract-infer-DaHH7CGX.mjs","names":[],"sources":["../src/commands/contract-infer-paths.ts","../src/commands/contract-infer.ts"],"sourcesContent":["import { dirname, resolve } from 'pathe';\n\ninterface ContractInferPathOptions {\n readonly output?: string;\n readonly config?: string;\n}\n\n/**\n * Resolves the output path for the inferred PSL contract.\n *\n * Priority:\n * 1. --output <path> flag (resolved relative to cwd)\n * 2. contract.prisma next to config.contract.output\n * 3. Canonical default: contract.prisma in the config directory\n */\nexport function resolveContractInferOutputPath(\n options: ContractInferPathOptions,\n contractOutput: string | undefined,\n): string {\n const configDir = options.config\n ? dirname(resolve(process.cwd(), options.config))\n : process.cwd();\n\n if (options.output) {\n return resolve(process.cwd(), options.output);\n }\n if (contractOutput) {\n const contractPath = resolve(configDir, contractOutput);\n return resolve(dirname(contractPath), 'contract.prisma');\n }\n return resolve(configDir, 'contract.prisma');\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { errorRuntime } from '@prisma-next/errors/execution';\nimport { printPsl } from '@prisma-next/psl-printer';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, relative } from 'pathe';\nimport type { CliStructuredError } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\nimport { resolveContractInferOutputPath } from './contract-infer-paths';\nimport {\n type InspectLiveSchemaOptions,\n type InspectLiveSchemaResult,\n inspectLiveSchema,\n} from './inspect-live-schema';\n\ninterface ContractInferOptions extends InspectLiveSchemaOptions {\n readonly output?: string;\n}\n\ninterface ContractInferSuccessResult {\n readonly ok: true;\n readonly summary: string;\n readonly target: InspectLiveSchemaResult['target'];\n readonly psl: {\n readonly path: string;\n };\n readonly meta: InspectLiveSchemaResult['meta'];\n readonly timings: {\n readonly total: number;\n };\n}\n\nasync function executeContractInferCommand(\n options: ContractInferOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<ContractInferSuccessResult, CliStructuredError>> {\n const inspectResult = await inspectLiveSchema(options, flags, ui, startTime, {\n commandName: 'contract infer',\n description: 'Infer a PSL contract from the live database schema',\n url: 'https://pris.ly/contract-infer',\n });\n\n if (!inspectResult.ok) {\n return inspectResult;\n }\n\n const { config, target, meta, pslContractAst } = inspectResult.value;\n\n if (!pslContractAst) {\n return notOk(\n errorRuntime('contract infer is not supported for this family', {\n why: 'The configured family does not implement the PslContractInferCapable capability, so an inferred PSL contract cannot be produced from the live database schema.',\n fix: 'Use a family that supports contract inference (e.g. SQL/Postgres).',\n }),\n );\n }\n\n const outputPath = resolveContractInferOutputPath(options, config.contract?.output);\n const pslContent = printPsl(pslContractAst);\n\n if (existsSync(outputPath) && !flags.json && !flags.quiet) {\n ui.stderr(`\\u26A0 Overwriting existing file: ${relative(process.cwd(), outputPath)}`);\n }\n\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, pslContent, 'utf-8');\n\n const pslPath = relative(process.cwd(), outputPath);\n if (!flags.json && !flags.quiet) {\n ui.stderr(`\\u2714 Contract written to ${pslPath}`);\n }\n\n return ok({\n ok: true,\n summary: 'Contract inferred successfully',\n target,\n psl: {\n path: pslPath,\n },\n meta,\n timings: {\n total: Date.now() - startTime,\n },\n });\n}\n\nexport function createContractInferCommand(): Command {\n const command = new Command('infer');\n setCommandDescriptions(\n command,\n 'Infer a PSL contract from the live database schema',\n 'Reads the live database schema and writes an inferred PSL contract to disk.\\n' +\n 'This command stops at `contract.prisma`; follow it with `contract emit` and\\n' +\n '`db sign` as separate steps.',\n );\n setCommandExamples(command, [\n 'prisma-next contract infer --db $DATABASE_URL',\n 'prisma-next contract infer --db $DATABASE_URL --output ./src/prisma/contract.prisma',\n 'prisma-next contract infer --db $DATABASE_URL --json',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--output <path>', 'Write the inferred PSL contract to the specified path')\n .action(async (options: ContractInferOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n const startTime = Date.now();\n\n const result = await executeContractInferCommand(options, flags, ui, startTime);\n const exitCode = handleResult(result, flags, ui, (value) => {\n if (flags.json) {\n ui.output(JSON.stringify(value, null, 2));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAeA,SAAgB,+BACd,SACA,gBACQ;CACR,MAAM,YAAY,QAAQ,SACtB,QAAQ,QAAQ,QAAQ,IAAI,GAAG,QAAQ,MAAM,CAAC,IAC9C,QAAQ,IAAI;CAEhB,IAAI,QAAQ,QACV,OAAO,QAAQ,QAAQ,IAAI,GAAG,QAAQ,MAAM;CAE9C,IAAI,gBAEF,OAAO,QAAQ,QADM,QAAQ,WAAW,cACN,CAAC,GAAG,iBAAiB;CAEzD,OAAO,QAAQ,WAAW,iBAAiB;AAC7C;;;ACQA,eAAe,4BACb,SACA,OACA,IACA,WACiE;CACjE,MAAM,gBAAgB,MAAM,kBAAkB,SAAS,OAAO,IAAI,WAAW;EAC3E,aAAa;EACb,aAAa;EACb,KAAK;CACP,CAAC;CAED,IAAI,CAAC,cAAc,IACjB,OAAO;CAGT,MAAM,EAAE,QAAQ,QAAQ,MAAM,mBAAmB,cAAc;CAE/D,IAAI,CAAC,gBACH,OAAO,MACL,aAAa,mDAAmD;EAC9D,KAAK;EACL,KAAK;CACP,CAAC,CACH;CAGF,MAAM,aAAa,+BAA+B,SAAS,OAAO,UAAU,MAAM;CAClF,MAAM,aAAa,SAAS,cAAc;CAE1C,IAAI,WAAW,UAAU,KAAK,CAAC,MAAM,QAAQ,CAAC,MAAM,OAClD,GAAG,OAAO,qCAAqC,SAAS,QAAQ,IAAI,GAAG,UAAU,GAAG;CAGtF,UAAU,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;CAClD,cAAc,YAAY,YAAY,OAAO;CAE7C,MAAM,UAAU,SAAS,QAAQ,IAAI,GAAG,UAAU;CAClD,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OACxB,GAAG,OAAO,8BAA8B,SAAS;CAGnD,OAAO,GAAG;EACR,IAAI;EACJ,SAAS;EACT;EACA,KAAK,EACH,MAAM,QACR;EACA;EACA,SAAS,EACP,OAAO,KAAK,IAAI,IAAI,UACtB;CACF,CAAC;AACH;AAEA,SAAgB,6BAAsC;CACpD,MAAM,UAAU,IAAI,QAAQ,OAAO;CACnC,uBACE,SACA,sDACA,wLAGF;CACA,mBAAmB,SAAS;EAC1B;EACA;EACA;CACF,CAAC;CACD,iBAAiB,OAAO,EACrB,OAAO,cAAc,4BAA4B,EACjD,OAAO,mBAAmB,+BAA+B,EACzD,OAAO,mBAAmB,uDAAuD,EACjF,OAAO,OAAO,YAAkC;EAC/C,MAAM,QAAQ,uBAAuB,OAAO;EAC5C,MAAM,KAAK,iBAAiB,KAAK;EAIjC,MAAM,WAAW,aAAa,MADT,4BAA4B,SAAS,OAAO,IAF/C,KAAK,IAEsD,CAAC,GACxC,OAAO,KAAK,UAAU;GAC1D,IAAI,MAAM,MACR,GAAG,OAAO,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;EAE5C,CAAC;EAED,QAAQ,KAAK,QAAQ;CACvB,CAAC;CAEH,OAAO;AACT"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { A as formatStyledHeader, B as errorDatabaseConnectionRequired, F as CliStructuredError, H as errorDriverRequired, J as errorMarkerMissing, U as errorFileNotFound, W as errorHashMismatch, _ as createTerminalUI, g as parseGlobalFlagsOrExit, i as maskConnectionUrl, l as setCommandDescriptions, nt as errorRuntime, o as resolveContractPath, ot as errorTargetMismatch, s as resolveMigrationPaths, st as errorUnexpected, t as addGlobalOptions, u as setCommandExamples, y as handleResult, z as errorContractValidationFailed } from "./command-helpers-DK_5ItoJ.mjs";
|
|
3
3
|
import { t as createProgressAdapter } from "./progress-adapter-C644QK8l.mjs";
|
|
4
|
-
import { a as ContractValidationError, t as createControlClient } from "./client-
|
|
4
|
+
import { a as ContractValidationError, t as createControlClient } from "./client-CcqChq9N.mjs";
|
|
5
5
|
import { c as formatVerifyOutput, i as formatSchemaVerifyOutput, r as formatSchemaVerifyJson, s as formatVerifyJson } from "./verify-BdI-BgYi.mjs";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
@@ -398,4 +398,4 @@ function createDbVerifyCommand() {
|
|
|
398
398
|
//#endregion
|
|
399
399
|
export { createDbVerifyCommand as t };
|
|
400
400
|
|
|
401
|
-
//# sourceMappingURL=db-verify-
|
|
401
|
+
//# sourceMappingURL=db-verify-DppLAhYT.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-verify-CxHiSiTG.mjs","names":[],"sources":["../src/utils/combine-schema-results.ts","../src/commands/db-verify.ts"],"sourcesContent":["import type { VerifyDatabaseSchemaResult } from '@prisma-next/framework-components/control';\n\n/**\n * Collapse the aggregate verifier's per-space schema results into a\n * single {@link VerifyDatabaseSchemaResult} for the existing CLI\n * display surface. Concatenates issues across members; sums counts;\n * uses the app member's result as the structural envelope (storage\n * hash, target).\n *\n * **Summary policy.** Preserve the per-family phrasing whenever the\n * combined `ok` flag agrees with the app member's `ok` flag — this is\n * the common case (single-family deployments, single-app deployments)\n * and the family's \"satisfies / does not satisfy contract\" phrasing\n * stays user-visible. When the app passes but an extension fails (or\n * vice versa) the app's summary contradicts the envelope, so fall back\n * to the first failing member's summary. This keeps family phrasing\n * intact and the envelope internally consistent (`ok: false` ↔ failure\n * summary).\n */\nexport function combineSchemaResults(\n perSpace: ReadonlyMap<string, VerifyDatabaseSchemaResult>,\n appSpaceId: string,\n strict: boolean,\n): VerifyDatabaseSchemaResult {\n const appResult = perSpace.get(appSpaceId) ?? perSpace.values().next().value;\n if (appResult === undefined) {\n throw new Error('Aggregate verifier returned no schema results — this is a wiring bug.');\n }\n\n let okAll = true;\n let firstFailure: VerifyDatabaseSchemaResult | undefined;\n let issues: VerifyDatabaseSchemaResult['schema']['issues'] = [];\n const counts = { pass: 0, warn: 0, fail: 0, totalNodes: 0 };\n const childRoots: Array<VerifyDatabaseSchemaResult['schema']['root']> = [];\n for (const [, result] of perSpace) {\n if (!result.ok) {\n okAll = false;\n if (firstFailure === undefined) firstFailure = result;\n }\n issues = [...issues, ...result.schema.issues];\n counts.pass += result.schema.counts.pass;\n counts.warn += result.schema.counts.warn;\n counts.fail += result.schema.counts.fail;\n counts.totalNodes += result.schema.counts.totalNodes;\n childRoots.push(result.schema.root);\n }\n\n // When `okAll !== appResult.ok`, exactly one shape is reachable: app passes\n // (`appResult.ok === true`) and at least one other member failed\n // (`okAll === false`). In that shape the failure was assigned to\n // `firstFailure` during iteration, so non-null assertion is safe. The mirror\n // shape (app fails while every member passes) is impossible because\n // `appResult` either *is* a member of `perSpace` or is the first iterator\n // value; either way its `ok` flag participates in `okAll`.\n const summary =\n okAll === appResult.ok\n ? appResult.summary\n : (firstFailure as VerifyDatabaseSchemaResult).summary;\n\n return {\n ok: okAll,\n ...(okAll ? {} : { code: appResult.code ?? 'PN-RUN-3010' }),\n summary,\n contract: appResult.contract,\n target: appResult.target,\n schema: {\n issues,\n root: {\n status: okAll ? 'pass' : 'fail',\n kind: 'aggregate',\n name: 'aggregate',\n contractPath: '',\n code: 'AGGREGATE',\n message: okAll ? 'Aggregate schema matches' : 'Aggregate schema mismatch',\n expected: undefined,\n actual: undefined,\n children: childRoots,\n },\n counts,\n },\n meta: { strict },\n timings: { total: 0 },\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type {\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n createControlStack,\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorHashMismatch,\n errorMarkerMissing,\n errorRuntime,\n errorTargetMismatch,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { combineSchemaResults } from '../utils/combine-schema-results';\nimport {\n addGlobalOptions,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport {\n type DbVerifyCommandSuccessResult,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatVerifyJson,\n formatVerifyOutput,\n} from '../utils/formatters/verify';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, 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 DbVerifyOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly markerOnly?: boolean;\n readonly schemaOnly?: boolean;\n readonly strict?: boolean;\n}\n\ntype DbVerifyMode = 'full' | 'marker-only' | 'schema-only';\n\n/**\n * Maps a VerifyDatabaseResult failure to a CliStructuredError.\n */\nfunction mapVerifyFailure(verifyResult: VerifyDatabaseResult): CliStructuredError {\n if (!verifyResult.ok && verifyResult.code) {\n if (verifyResult.code === VERIFY_CODE_MARKER_MISSING) {\n return errorMarkerMissing();\n }\n if (verifyResult.code === VERIFY_CODE_HASH_MISMATCH) {\n const storageMatch = verifyResult.marker?.storageHash === verifyResult.contract.storageHash;\n const profileMatch =\n !verifyResult.contract.profileHash ||\n verifyResult.marker?.profileHash === verifyResult.contract.profileHash;\n\n if (!storageMatch) {\n return errorHashMismatch({\n why: 'Contract storageHash does not match database marker',\n expected: verifyResult.contract.storageHash,\n ...ifDefined('actual', verifyResult.marker?.storageHash),\n });\n }\n\n return errorHashMismatch({\n why: profileMatch\n ? 'Contract hash does not match database marker'\n : 'Contract profileHash does not match database marker',\n ...ifDefined('expected', verifyResult.contract.profileHash),\n ...ifDefined('actual', verifyResult.marker?.profileHash),\n });\n }\n if (verifyResult.code === VERIFY_CODE_TARGET_MISMATCH) {\n return errorTargetMismatch(\n verifyResult.target.expected,\n verifyResult.target.actual ?? 'unknown',\n );\n }\n // Unknown code - fall through to runtime error\n }\n return errorRuntime(verifyResult.summary);\n}\n\ntype DbVerifyFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\nfunction errorInvalidVerifyMode(options: {\n readonly why: string;\n readonly fix: string;\n}): CliStructuredError {\n return new CliStructuredError('4012', 'Invalid verify mode', {\n domain: 'CLI',\n why: options.why,\n fix: options.fix,\n docsUrl: 'https://pris.ly/db-verify',\n });\n}\n\nfunction resolveDbVerifyMode(options: DbVerifyOptions): Result<DbVerifyMode, CliStructuredError> {\n if (options.markerOnly && options.schemaOnly) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--marker-only` and `--schema-only` cannot be used together',\n fix: 'Choose one mode: omit both to check the marker and schema, use `--marker-only` to check only the marker, or use `--schema-only` to check only the live schema.',\n }),\n );\n }\n\n if (options.markerOnly && options.strict) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--strict` requires schema verification, but `--marker-only` skips it',\n fix: 'Remove `--strict`, or use `db verify` / `db verify --schema-only` when you want to check the live schema in strict mode.',\n }),\n );\n }\n\n if (options.schemaOnly) {\n return ok('schema-only');\n }\n\n if (options.markerOnly) {\n return ok('marker-only');\n }\n\n return ok('full');\n}\n\nfunction formatDbVerifyModeLabel(mode: DbVerifyMode, strict: boolean): string {\n if (mode === 'marker-only') {\n return 'marker only';\n }\n\n if (mode === 'schema-only') {\n return `schema only (${strict ? 'strict' : 'tolerant'})`;\n }\n\n return `full (marker + schema, ${strict ? 'strict' : 'tolerant'})`;\n}\n\nfunction formatDbVerifyInvocation(mode: DbVerifyMode, strict: boolean): string {\n const args = ['db verify'];\n\n if (mode === 'marker-only') {\n args.push('--marker-only');\n }\n\n if (mode === 'schema-only') {\n args.push('--schema-only');\n }\n\n if (strict) {\n args.push('--strict');\n }\n\n return args.join(' ');\n}\n\nfunction createDbVerifyConnectionRequiredError(options: {\n readonly configPath: string;\n readonly mode: DbVerifyMode;\n readonly strict: boolean;\n}): CliStructuredError {\n const invocation = formatDbVerifyInvocation(options.mode, options.strict);\n return errorDatabaseConnectionRequired({\n why: `Database connection is required for ${invocation} (set db.connection in ${options.configPath}, or pass --db <url>)`,\n retryCommand: `prisma-next ${invocation} --db <url>`,\n });\n}\n\nfunction renderVerifyHeader(\n paths: { configPath: string; contractPath: string },\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n flags: GlobalFlags,\n ui: TerminalUI,\n): void {\n if (flags.json || flags.quiet) return;\n\n const description =\n mode === 'schema-only'\n ? 'Check whether the live database schema matches your contract'\n : mode === 'marker-only'\n ? 'Check whether the database marker matches your contract'\n : 'Check whether the database marker and live schema match your contract';\n\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: paths.configPath },\n { label: 'contract', value: paths.contractPath },\n { label: 'mode', value: formatDbVerifyModeLabel(mode, options.strict ?? false) },\n ];\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n }\n\n ui.stderr(\n formatStyledHeader({\n command: 'db verify',\n description,\n url: 'https://pris.ly/db-verify',\n details,\n flags,\n }),\n );\n}\n\nasync function resolveVerifyPaths(options: DbVerifyOptions) {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n return { config, configPath, contractPathAbsolute, contractPath };\n}\n\ntype VerifyPaths = Awaited<ReturnType<typeof resolveVerifyPaths>>;\n\ninterface VerifySetup extends VerifyPaths {\n readonly contractJson: Contract;\n readonly dbConnection: string;\n}\n\nasync function resolveVerifySetup(\n paths: VerifyPaths,\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n): Promise<Result<VerifySetup, CliStructuredError>> {\n const { config, configPath, contractPathAbsolute, contractPath } = paths;\n\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Cross the family `deserializeContract` seam at the read site, just\n // like every other CLI on-disk read (TML-2536). The downstream\n // `dbVerify` op accepts the hydrated `Contract` directly and no\n // longer re-deserializes.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let contractJson: Contract;\n try {\n contractJson = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const dbConnection = options.db ?? config.db?.connection;\n if (typeof dbConnection !== 'string' || dbConnection.length === 0) {\n return notOk(\n createDbVerifyConnectionRequiredError({\n configPath,\n mode,\n strict: options.strict ?? false,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: `Config.driver is required for ${formatDbVerifyInvocation(mode, options.strict ?? false)}`,\n }),\n );\n }\n\n return ok({ ...paths, contractJson, dbConnection });\n}\n\nfunction createVerifyClient(setup: VerifySetup) {\n return createControlClient({\n family: setup.config.family,\n target: setup.config.target,\n adapter: setup.config.adapter,\n driver: setup.config.driver!,\n extensionPacks: setup.config.extensionPacks ?? [],\n });\n}\n\nfunction wrapVerifyError(\n error: unknown,\n contractPathAbsolute: string,\n modeLabel: string,\n): Result<never, CliStructuredError> {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during ${modeLabel}: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n}\n\n/**\n * Executes the db verify command and returns a structured Result.\n */\nasync function executeDbVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n mode: Extract<DbVerifyMode, 'full' | 'marker-only'>,\n): Promise<Result<DbVerifyCommandSuccessResult, DbVerifyFailure>> {\n const startTime = Date.now();\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, mode, flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, mode);\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Single-contract marker verification preserved for the existing\n // marker / target / hash failure surface (`PN-RUN-3001/3002/3003`).\n // The aggregate verifier (run below for the per-space marker /\n // schema checks) does not duplicate this: it concerns itself with\n // marker-vs-on-disk and orphan-marker drift, not the\n // hash-mismatch-against-the-app-contract lane that today's\n // `client.verify` covers.\n const verifyResult = await client.verify({\n contract: contractJson,\n connection: dbConnection,\n onProgress,\n });\n\n if (!verifyResult.ok) {\n return notOk(mapVerifyFailure(verifyResult));\n }\n\n // Aggregate verifier (loader → verifier pipeline). Runs the layout\n // precheck, marker-aware per-space verifier, and (full mode only)\n // per-space pre-projected schema verification (closes F23).\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: mode === 'marker-only',\n skipMarker: false,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n if (mode === 'marker-only') {\n return ok({\n ok: true,\n mode: 'marker-only',\n summary: 'Database marker matches contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n warning: 'Schema verification skipped because --marker-only was provided',\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'skipped',\n },\n timings: { total: Date.now() - startTime },\n });\n }\n\n const combined = combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n );\n if (!combined.ok) {\n return notOk(combined);\n }\n\n return ok({\n ok: true,\n mode: 'full',\n summary: 'Database marker and schema match contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n schema: {\n summary: combined.summary,\n counts: combined.schema.counts,\n strict: combined.meta?.strict ?? false,\n },\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'performed',\n },\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify');\n } finally {\n await client.close();\n }\n}\n\nasync function executeDbSchemaOnlyVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<VerifyDatabaseSchemaResult, CliStructuredError>> {\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, 'schema-only', flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, 'schema-only');\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n await client.connect(dbConnection);\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: false,\n skipMarker: true,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n return ok(\n combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n ),\n );\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify --schema-only');\n } finally {\n await client.close();\n }\n}\n\nexport function createDbVerifyCommand(): Command {\n const command = new Command('verify');\n setCommandDescriptions(\n command,\n 'Check whether the database marker and live schema match your contract',\n 'Verifies the database marker first, then checks the database schema matches your contract.\\n' +\n 'Use `--marker-only` for marker-only verification, `--schema-only` to skip marker checks and\\n' +\n 'inspect only the live schema, and `--strict` to fail if the database includes elements\\n' +\n 'not present in the contract.',\n );\n setCommandExamples(command, [\n 'prisma-next db verify --db $DATABASE_URL',\n 'prisma-next db verify --db $DATABASE_URL --strict',\n 'prisma-next db verify --db $DATABASE_URL --schema-only',\n 'prisma-next db verify --db $DATABASE_URL --schema-only --strict',\n 'prisma-next db verify --db $DATABASE_URL --marker-only',\n 'prisma-next db verify --db $DATABASE_URL --json',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--marker-only', 'Skip schema verification and only check the database marker')\n .option(\n '--schema-only',\n 'Skip marker verification and only check whether the live schema satisfies the contract',\n )\n .option(\n '--strict',\n 'Strict mode: schema elements not present in the contract are considered an error',\n false,\n )\n .action(async (options: DbVerifyOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n\n const modeResult = resolveDbVerifyMode(options);\n if (!modeResult.ok) {\n const exitCode = handleResult(modeResult as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n const mode = modeResult.value;\n\n if (mode === 'schema-only') {\n const result = await executeDbSchemaOnlyVerifyCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (schemaVerifyResult) => {\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(schemaVerifyResult));\n } else {\n const output = formatSchemaVerifyOutput(schemaVerifyResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n\n if (result.ok && !result.value.ok) {\n process.exit(1);\n }\n\n process.exit(exitCode);\n }\n\n const result = await executeDbVerifyCommand(options, flags, ui, mode);\n\n if (result.ok) {\n if (flags.json) {\n ui.output(formatVerifyJson(result.value));\n } else {\n const output = formatVerifyOutput(result.value, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(0);\n }\n\n if (CliStructuredError.is(result.failure)) {\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(result.failure));\n } else {\n // Always show schema-drift failures, even in quiet mode — exiting 1 without\n // diagnostics is unhelpful.\n const output = formatSchemaVerifyOutput(result.failure, { ...flags, quiet: false });\n if (output) {\n ui.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"db-verify-DppLAhYT.mjs","names":[],"sources":["../src/utils/combine-schema-results.ts","../src/commands/db-verify.ts"],"sourcesContent":["import type { VerifyDatabaseSchemaResult } from '@prisma-next/framework-components/control';\n\n/**\n * Collapse the aggregate verifier's per-space schema results into a\n * single {@link VerifyDatabaseSchemaResult} for the existing CLI\n * display surface. Concatenates issues across members; sums counts;\n * uses the app member's result as the structural envelope (storage\n * hash, target).\n *\n * **Summary policy.** Preserve the per-family phrasing whenever the\n * combined `ok` flag agrees with the app member's `ok` flag — this is\n * the common case (single-family deployments, single-app deployments)\n * and the family's \"satisfies / does not satisfy contract\" phrasing\n * stays user-visible. When the app passes but an extension fails (or\n * vice versa) the app's summary contradicts the envelope, so fall back\n * to the first failing member's summary. This keeps family phrasing\n * intact and the envelope internally consistent (`ok: false` ↔ failure\n * summary).\n */\nexport function combineSchemaResults(\n perSpace: ReadonlyMap<string, VerifyDatabaseSchemaResult>,\n appSpaceId: string,\n strict: boolean,\n): VerifyDatabaseSchemaResult {\n const appResult = perSpace.get(appSpaceId) ?? perSpace.values().next().value;\n if (appResult === undefined) {\n throw new Error('Aggregate verifier returned no schema results — this is a wiring bug.');\n }\n\n let okAll = true;\n let firstFailure: VerifyDatabaseSchemaResult | undefined;\n let issues: VerifyDatabaseSchemaResult['schema']['issues'] = [];\n const counts = { pass: 0, warn: 0, fail: 0, totalNodes: 0 };\n const childRoots: Array<VerifyDatabaseSchemaResult['schema']['root']> = [];\n for (const [, result] of perSpace) {\n if (!result.ok) {\n okAll = false;\n if (firstFailure === undefined) firstFailure = result;\n }\n issues = [...issues, ...result.schema.issues];\n counts.pass += result.schema.counts.pass;\n counts.warn += result.schema.counts.warn;\n counts.fail += result.schema.counts.fail;\n counts.totalNodes += result.schema.counts.totalNodes;\n childRoots.push(result.schema.root);\n }\n\n // When `okAll !== appResult.ok`, exactly one shape is reachable: app passes\n // (`appResult.ok === true`) and at least one other member failed\n // (`okAll === false`). In that shape the failure was assigned to\n // `firstFailure` during iteration, so non-null assertion is safe. The mirror\n // shape (app fails while every member passes) is impossible because\n // `appResult` either *is* a member of `perSpace` or is the first iterator\n // value; either way its `ok` flag participates in `okAll`.\n const summary =\n okAll === appResult.ok\n ? appResult.summary\n : (firstFailure as VerifyDatabaseSchemaResult).summary;\n\n return {\n ok: okAll,\n ...(okAll ? {} : { code: appResult.code ?? 'PN-RUN-3010' }),\n summary,\n contract: appResult.contract,\n target: appResult.target,\n schema: {\n issues,\n root: {\n status: okAll ? 'pass' : 'fail',\n kind: 'aggregate',\n name: 'aggregate',\n contractPath: '',\n code: 'AGGREGATE',\n message: okAll ? 'Aggregate schema matches' : 'Aggregate schema mismatch',\n expected: undefined,\n actual: undefined,\n children: childRoots,\n },\n counts,\n },\n meta: { strict },\n timings: { total: 0 },\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type {\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n createControlStack,\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorHashMismatch,\n errorMarkerMissing,\n errorRuntime,\n errorTargetMismatch,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { combineSchemaResults } from '../utils/combine-schema-results';\nimport {\n addGlobalOptions,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport {\n type DbVerifyCommandSuccessResult,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatVerifyJson,\n formatVerifyOutput,\n} from '../utils/formatters/verify';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, 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 DbVerifyOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly markerOnly?: boolean;\n readonly schemaOnly?: boolean;\n readonly strict?: boolean;\n}\n\ntype DbVerifyMode = 'full' | 'marker-only' | 'schema-only';\n\n/**\n * Maps a VerifyDatabaseResult failure to a CliStructuredError.\n */\nfunction mapVerifyFailure(verifyResult: VerifyDatabaseResult): CliStructuredError {\n if (!verifyResult.ok && verifyResult.code) {\n if (verifyResult.code === VERIFY_CODE_MARKER_MISSING) {\n return errorMarkerMissing();\n }\n if (verifyResult.code === VERIFY_CODE_HASH_MISMATCH) {\n const storageMatch = verifyResult.marker?.storageHash === verifyResult.contract.storageHash;\n const profileMatch =\n !verifyResult.contract.profileHash ||\n verifyResult.marker?.profileHash === verifyResult.contract.profileHash;\n\n if (!storageMatch) {\n return errorHashMismatch({\n why: 'Contract storageHash does not match database marker',\n expected: verifyResult.contract.storageHash,\n ...ifDefined('actual', verifyResult.marker?.storageHash),\n });\n }\n\n return errorHashMismatch({\n why: profileMatch\n ? 'Contract hash does not match database marker'\n : 'Contract profileHash does not match database marker',\n ...ifDefined('expected', verifyResult.contract.profileHash),\n ...ifDefined('actual', verifyResult.marker?.profileHash),\n });\n }\n if (verifyResult.code === VERIFY_CODE_TARGET_MISMATCH) {\n return errorTargetMismatch(\n verifyResult.target.expected,\n verifyResult.target.actual ?? 'unknown',\n );\n }\n // Unknown code - fall through to runtime error\n }\n return errorRuntime(verifyResult.summary);\n}\n\ntype DbVerifyFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\nfunction errorInvalidVerifyMode(options: {\n readonly why: string;\n readonly fix: string;\n}): CliStructuredError {\n return new CliStructuredError('4012', 'Invalid verify mode', {\n domain: 'CLI',\n why: options.why,\n fix: options.fix,\n docsUrl: 'https://pris.ly/db-verify',\n });\n}\n\nfunction resolveDbVerifyMode(options: DbVerifyOptions): Result<DbVerifyMode, CliStructuredError> {\n if (options.markerOnly && options.schemaOnly) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--marker-only` and `--schema-only` cannot be used together',\n fix: 'Choose one mode: omit both to check the marker and schema, use `--marker-only` to check only the marker, or use `--schema-only` to check only the live schema.',\n }),\n );\n }\n\n if (options.markerOnly && options.strict) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--strict` requires schema verification, but `--marker-only` skips it',\n fix: 'Remove `--strict`, or use `db verify` / `db verify --schema-only` when you want to check the live schema in strict mode.',\n }),\n );\n }\n\n if (options.schemaOnly) {\n return ok('schema-only');\n }\n\n if (options.markerOnly) {\n return ok('marker-only');\n }\n\n return ok('full');\n}\n\nfunction formatDbVerifyModeLabel(mode: DbVerifyMode, strict: boolean): string {\n if (mode === 'marker-only') {\n return 'marker only';\n }\n\n if (mode === 'schema-only') {\n return `schema only (${strict ? 'strict' : 'tolerant'})`;\n }\n\n return `full (marker + schema, ${strict ? 'strict' : 'tolerant'})`;\n}\n\nfunction formatDbVerifyInvocation(mode: DbVerifyMode, strict: boolean): string {\n const args = ['db verify'];\n\n if (mode === 'marker-only') {\n args.push('--marker-only');\n }\n\n if (mode === 'schema-only') {\n args.push('--schema-only');\n }\n\n if (strict) {\n args.push('--strict');\n }\n\n return args.join(' ');\n}\n\nfunction createDbVerifyConnectionRequiredError(options: {\n readonly configPath: string;\n readonly mode: DbVerifyMode;\n readonly strict: boolean;\n}): CliStructuredError {\n const invocation = formatDbVerifyInvocation(options.mode, options.strict);\n return errorDatabaseConnectionRequired({\n why: `Database connection is required for ${invocation} (set db.connection in ${options.configPath}, or pass --db <url>)`,\n retryCommand: `prisma-next ${invocation} --db <url>`,\n });\n}\n\nfunction renderVerifyHeader(\n paths: { configPath: string; contractPath: string },\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n flags: GlobalFlags,\n ui: TerminalUI,\n): void {\n if (flags.json || flags.quiet) return;\n\n const description =\n mode === 'schema-only'\n ? 'Check whether the live database schema matches your contract'\n : mode === 'marker-only'\n ? 'Check whether the database marker matches your contract'\n : 'Check whether the database marker and live schema match your contract';\n\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: paths.configPath },\n { label: 'contract', value: paths.contractPath },\n { label: 'mode', value: formatDbVerifyModeLabel(mode, options.strict ?? false) },\n ];\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n }\n\n ui.stderr(\n formatStyledHeader({\n command: 'db verify',\n description,\n url: 'https://pris.ly/db-verify',\n details,\n flags,\n }),\n );\n}\n\nasync function resolveVerifyPaths(options: DbVerifyOptions) {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n return { config, configPath, contractPathAbsolute, contractPath };\n}\n\ntype VerifyPaths = Awaited<ReturnType<typeof resolveVerifyPaths>>;\n\ninterface VerifySetup extends VerifyPaths {\n readonly contractJson: Contract;\n readonly dbConnection: string;\n}\n\nasync function resolveVerifySetup(\n paths: VerifyPaths,\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n): Promise<Result<VerifySetup, CliStructuredError>> {\n const { config, configPath, contractPathAbsolute, contractPath } = paths;\n\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Cross the family `deserializeContract` seam at the read site, just\n // like every other CLI on-disk read (TML-2536). The downstream\n // `dbVerify` op accepts the hydrated `Contract` directly and no\n // longer re-deserializes.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let contractJson: Contract;\n try {\n contractJson = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const dbConnection = options.db ?? config.db?.connection;\n if (typeof dbConnection !== 'string' || dbConnection.length === 0) {\n return notOk(\n createDbVerifyConnectionRequiredError({\n configPath,\n mode,\n strict: options.strict ?? false,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: `Config.driver is required for ${formatDbVerifyInvocation(mode, options.strict ?? false)}`,\n }),\n );\n }\n\n return ok({ ...paths, contractJson, dbConnection });\n}\n\nfunction createVerifyClient(setup: VerifySetup) {\n return createControlClient({\n family: setup.config.family,\n target: setup.config.target,\n adapter: setup.config.adapter,\n driver: setup.config.driver!,\n extensionPacks: setup.config.extensionPacks ?? [],\n });\n}\n\nfunction wrapVerifyError(\n error: unknown,\n contractPathAbsolute: string,\n modeLabel: string,\n): Result<never, CliStructuredError> {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during ${modeLabel}: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n}\n\n/**\n * Executes the db verify command and returns a structured Result.\n */\nasync function executeDbVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n mode: Extract<DbVerifyMode, 'full' | 'marker-only'>,\n): Promise<Result<DbVerifyCommandSuccessResult, DbVerifyFailure>> {\n const startTime = Date.now();\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, mode, flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, mode);\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Single-contract marker verification preserved for the existing\n // marker / target / hash failure surface (`PN-RUN-3001/3002/3003`).\n // The aggregate verifier (run below for the per-space marker /\n // schema checks) does not duplicate this: it concerns itself with\n // marker-vs-on-disk and orphan-marker drift, not the\n // hash-mismatch-against-the-app-contract lane that today's\n // `client.verify` covers.\n const verifyResult = await client.verify({\n contract: contractJson,\n connection: dbConnection,\n onProgress,\n });\n\n if (!verifyResult.ok) {\n return notOk(mapVerifyFailure(verifyResult));\n }\n\n // Aggregate verifier (loader → verifier pipeline). Runs the layout\n // precheck, marker-aware per-space verifier, and (full mode only)\n // per-space pre-projected schema verification (closes F23).\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: mode === 'marker-only',\n skipMarker: false,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n if (mode === 'marker-only') {\n return ok({\n ok: true,\n mode: 'marker-only',\n summary: 'Database marker matches contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n warning: 'Schema verification skipped because --marker-only was provided',\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'skipped',\n },\n timings: { total: Date.now() - startTime },\n });\n }\n\n const combined = combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n );\n if (!combined.ok) {\n return notOk(combined);\n }\n\n return ok({\n ok: true,\n mode: 'full',\n summary: 'Database marker and schema match contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n schema: {\n summary: combined.summary,\n counts: combined.schema.counts,\n strict: combined.meta?.strict ?? false,\n },\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'performed',\n },\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify');\n } finally {\n await client.close();\n }\n}\n\nasync function executeDbSchemaOnlyVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<VerifyDatabaseSchemaResult, CliStructuredError>> {\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, 'schema-only', flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, 'schema-only');\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n await client.connect(dbConnection);\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: false,\n skipMarker: true,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n return ok(\n combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n ),\n );\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify --schema-only');\n } finally {\n await client.close();\n }\n}\n\nexport function createDbVerifyCommand(): Command {\n const command = new Command('verify');\n setCommandDescriptions(\n command,\n 'Check whether the database marker and live schema match your contract',\n 'Verifies the database marker first, then checks the database schema matches your contract.\\n' +\n 'Use `--marker-only` for marker-only verification, `--schema-only` to skip marker checks and\\n' +\n 'inspect only the live schema, and `--strict` to fail if the database includes elements\\n' +\n 'not present in the contract.',\n );\n setCommandExamples(command, [\n 'prisma-next db verify --db $DATABASE_URL',\n 'prisma-next db verify --db $DATABASE_URL --strict',\n 'prisma-next db verify --db $DATABASE_URL --schema-only',\n 'prisma-next db verify --db $DATABASE_URL --schema-only --strict',\n 'prisma-next db verify --db $DATABASE_URL --marker-only',\n 'prisma-next db verify --db $DATABASE_URL --json',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--marker-only', 'Skip schema verification and only check the database marker')\n .option(\n '--schema-only',\n 'Skip marker verification and only check whether the live schema satisfies the contract',\n )\n .option(\n '--strict',\n 'Strict mode: schema elements not present in the contract are considered an error',\n false,\n )\n .action(async (options: DbVerifyOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n\n const modeResult = resolveDbVerifyMode(options);\n if (!modeResult.ok) {\n const exitCode = handleResult(modeResult as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n const mode = modeResult.value;\n\n if (mode === 'schema-only') {\n const result = await executeDbSchemaOnlyVerifyCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (schemaVerifyResult) => {\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(schemaVerifyResult));\n } else {\n const output = formatSchemaVerifyOutput(schemaVerifyResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n\n if (result.ok && !result.value.ok) {\n process.exit(1);\n }\n\n process.exit(exitCode);\n }\n\n const result = await executeDbVerifyCommand(options, flags, ui, mode);\n\n if (result.ok) {\n if (flags.json) {\n ui.output(formatVerifyJson(result.value));\n } else {\n const output = formatVerifyOutput(result.value, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(0);\n }\n\n if (CliStructuredError.is(result.failure)) {\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(result.failure));\n } else {\n // Always show schema-drift failures, even in quiet mode — exiting 1 without\n // diagnostics is unhelpful.\n const output = formatSchemaVerifyOutput(result.failure, { ...flags, quiet: false });\n if (output) {\n ui.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as ExecuteDbVerifyOptions, C as IntrospectOptions, D as SchemaVerifyOptions, M as executeDbVerify, O as SignOptions, S as EmitSuccess, T as OnControlProgress, _ as EmitContractConfig, a as ControlClientOptions, b as EmitOptions, c as DbInitFailureCode, d as DbInitSuccess, f as DbUpdateFailure, g as DbUpdateSuccess, h as DbUpdateResult, i as ControlClient, j as ExecuteDbVerifyResult, k as VerifyOptions, l as DbInitOptions, m as DbUpdateOptions, n as ContractEmitResult, o as ControlProgressEvent, p as DbUpdateFailureCode, r as ControlActionName, s as DbInitFailure, t as ContractEmitOptions, u as DbInitResult, v as EmitFailure, x as EmitResult, y as EmitFailureCode } from "../types-
|
|
1
|
+
import { A as ExecuteDbVerifyOptions, C as IntrospectOptions, D as SchemaVerifyOptions, M as executeDbVerify, O as SignOptions, S as EmitSuccess, T as OnControlProgress, _ as EmitContractConfig, a as ControlClientOptions, b as EmitOptions, c as DbInitFailureCode, d as DbInitSuccess, f as DbUpdateFailure, g as DbUpdateSuccess, h as DbUpdateResult, i as ControlClient, j as ExecuteDbVerifyResult, k as VerifyOptions, l as DbInitOptions, m as DbUpdateOptions, n as ContractEmitResult, o as ControlProgressEvent, p as DbUpdateFailureCode, r as ControlActionName, s as DbInitFailure, t as ContractEmitOptions, u as DbInitResult, v as EmitFailure, x as EmitResult, y as EmitFailureCode } from "../types-Cculk5KV.mjs";
|
|
2
2
|
import { ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyInstance, ControlStack, SignDatabaseResult, TargetMigrationsCapability, VerifyDatabaseResult, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
|
|
3
3
|
import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
|
|
4
4
|
import { Contract } from "@prisma-next/contract/types";
|
|
@@ -51,7 +51,7 @@ declare function executeContractEmit(options: ContractEmitOptions): Promise<Cont
|
|
|
51
51
|
*
|
|
52
52
|
* `db init` runs the loader → planner → runner pipeline:
|
|
53
53
|
*
|
|
54
|
-
* 1. {@link
|
|
54
|
+
* 1. {@link executeRun} loads a `ContractSpaceAggregate` via
|
|
55
55
|
* {@link import('@prisma-next/migration-tools/aggregate').loadContractSpaceAggregate}
|
|
56
56
|
* from the supplied descriptor set + on-disk on-disk artefacts.
|
|
57
57
|
* 2. The aggregate planner runs with `callerPolicy.ignoreGraphFor`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { n as executeContractEmit, r as disposeEmitQueue } from "../contract-emit-BO0l6fnT.mjs";
|
|
2
2
|
import { t as enrichContract } from "../contract-enrichment-a0V5Y_mL.mjs";
|
|
3
|
-
import { i as executeDbInit, n as executeDbVerify, r as executeDbUpdate, t as createControlClient } from "../client-
|
|
3
|
+
import { i as executeDbInit, n as executeDbVerify, r as executeDbUpdate, t as createControlClient } from "../client-CcqChq9N.mjs";
|
|
4
4
|
export { createControlClient, disposeEmitQueue, enrichContract, executeContractEmit, executeDbInit, executeDbUpdate, executeDbVerify };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { A as formatStyledHeader, B as errorDatabaseConnectionRequired, F as CliStructuredError, H as errorDriverRequired, c as sanitizeErrorMessage, i as maskConnectionUrl, st as errorUnexpected } from "./command-helpers-DK_5ItoJ.mjs";
|
|
3
3
|
import { t as createProgressAdapter } from "./progress-adapter-C644QK8l.mjs";
|
|
4
|
-
import { t as createControlClient } from "./client-
|
|
4
|
+
import { t as createControlClient } from "./client-CcqChq9N.mjs";
|
|
5
5
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
6
6
|
import { relative, resolve } from "pathe";
|
|
7
7
|
//#region src/commands/inspect-live-schema.ts
|
|
@@ -86,4 +86,4 @@ async function inspectLiveSchema(options, flags, ui, startTime, context) {
|
|
|
86
86
|
//#endregion
|
|
87
87
|
export { inspectLiveSchema as t };
|
|
88
88
|
|
|
89
|
-
//# sourceMappingURL=inspect-live-schema-
|
|
89
|
+
//# sourceMappingURL=inspect-live-schema-CfOSPCmR.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect-live-schema-
|
|
1
|
+
{"version":3,"file":"inspect-live-schema-CfOSPCmR.mjs","names":[],"sources":["../src/commands/inspect-live-schema.ts"],"sourcesContent":["import type { CoreSchemaView } from '@prisma-next/framework-components/control';\nimport type { PslDocumentAst } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n CliStructuredError,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { maskConnectionUrl, sanitizeErrorMessage } from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions, GlobalFlags } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport type { TerminalUI } from '../utils/terminal-ui';\n\nexport interface InspectLiveSchemaOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n}\n\ninterface InspectLiveSchemaContext {\n readonly commandName: string;\n readonly description: string;\n readonly url: string;\n}\n\ntype LoadedCliConfig = Awaited<ReturnType<typeof loadConfig>>;\n\nexport interface InspectLiveSchemaResult {\n readonly config: LoadedCliConfig;\n readonly schema: unknown;\n readonly schemaView: CoreSchemaView | undefined;\n /**\n * PSL AST inferred from the introspected schema, when the configured family\n * implements `PslContractInferCapable`. `undefined` for families that do not\n * support inference (e.g. Mongo today).\n */\n readonly pslContractAst: PslDocumentAst | undefined;\n readonly target: {\n readonly familyId: string;\n readonly id: string;\n };\n readonly meta: {\n readonly configPath?: string;\n readonly dbUrl?: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nexport async function inspectLiveSchema(\n options: InspectLiveSchemaOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n context: InspectLiveSchemaContext,\n): Promise<Result<InspectLiveSchemaResult, CliStructuredError>> {\n let config: LoadedCliConfig;\n try {\n config = await loadConfig(options.config);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to load config',\n }),\n );\n }\n\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n ];\n\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n } else if (config.db?.connection && typeof config.db.connection === 'string') {\n details.push({ label: 'database', value: maskConnectionUrl(config.db.connection) });\n }\n\n ui.stderr(\n formatStyledHeader({\n command: context.commandName,\n description: context.description,\n url: context.url,\n details,\n flags,\n }),\n );\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 ${context.commandName} (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: context.commandName,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: `Config.driver is required for ${context.commandName}`,\n }),\n );\n }\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 const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n const schema = await client.introspect({\n connection: dbConnection,\n onProgress,\n });\n const schemaView = client.toSchemaView(schema);\n const pslContractAst = client.inferPslContract(schema);\n\n const dbUrl = typeof dbConnection === 'string' ? maskConnectionUrl(dbConnection) : undefined;\n\n return ok({\n config,\n schema,\n schemaView,\n pslContractAst,\n target: {\n familyId: config.family.familyId,\n id: config.target.targetId,\n },\n meta: {\n configPath,\n ...(dbUrl ? { dbUrl } : {}),\n },\n timings: {\n total: Date.now() - startTime,\n },\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\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 ${context.commandName}: ${safeMessage}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n"],"mappings":";;;;;;;AAsDA,eAAsB,kBACpB,SACA,OACA,IACA,WACA,SAC8D;CAC9D,IAAI;CACJ,IAAI;EACF,SAAS,MAAM,WAAW,QAAQ,MAAM;CAC1C,SAAS,OAAO;EACd,IAAI,mBAAmB,GAAG,KAAK,GAC7B,OAAO,MAAM,KAAK;EAGpB,OAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG,EACtE,KAAK,wBACP,CAAC,CACH;CACF;CAEA,MAAM,aAAa,QAAQ,SACvB,SAAS,QAAQ,IAAI,GAAG,QAAQ,QAAQ,MAAM,CAAC,IAC/C;CAEJ,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OAAO;EAC/B,MAAM,UAAmD,CACvD;GAAE,OAAO;GAAU,OAAO;EAAW,CACvC;EAEA,IAAI,QAAQ,IACV,QAAQ,KAAK;GAAE,OAAO;GAAY,OAAO,kBAAkB,QAAQ,EAAE;EAAE,CAAC;OACnE,IAAI,OAAO,IAAI,cAAc,OAAO,OAAO,GAAG,eAAe,UAClE,QAAQ,KAAK;GAAE,OAAO;GAAY,OAAO,kBAAkB,OAAO,GAAG,UAAU;EAAE,CAAC;EAGpF,GAAG,OACD,mBAAmB;GACjB,SAAS,QAAQ;GACjB,aAAa,QAAQ;GACrB,KAAK,QAAQ;GACb;GACA;EACF,CAAC,CACH;CACF;CAEA,MAAM,eAAe,QAAQ,MAAM,OAAO,IAAI;CAC9C,IAAI,CAAC,cACH,OAAO,MACL,gCAAgC;EAC9B,KAAK,uCAAuC,QAAQ,YAAY,yBAAyB,WAAW;EACpG,aAAa,QAAQ;CACvB,CAAC,CACH;CAGF,IAAI,CAAC,OAAO,QACV,OAAO,MACL,oBAAoB,EAClB,KAAK,iCAAiC,QAAQ,cAChD,CAAC,CACH;CAGF,MAAM,SAAS,oBAAoB;EACjC,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf,gBAAgB,OAAO,kBAAkB,CAAC;CAC5C,CAAC;CACD,MAAM,aAAa,sBAAsB;EAAE;EAAI;CAAM,CAAC;CAEtD,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,WAAW;GACrC,YAAY;GACZ;EACF,CAAC;EACD,MAAM,aAAa,OAAO,aAAa,MAAM;EAC7C,MAAM,iBAAiB,OAAO,iBAAiB,MAAM;EAErD,MAAM,QAAQ,OAAO,iBAAiB,WAAW,kBAAkB,YAAY,IAAI,KAAA;EAEnF,OAAO,GAAG;GACR;GACA;GACA;GACA;GACA,QAAQ;IACN,UAAU,OAAO,OAAO;IACxB,IAAI,OAAO,OAAO;GACpB;GACA,MAAM;IACJ;IACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;GAC3B;GACA,SAAS,EACP,OAAO,KAAK,IAAI,IAAI,UACtB;EACF,CAAC;CACH,SAAS,OAAO;EACd,IAAI,mBAAmB,GAAG,KAAK,GAC7B,OAAO,MAAM,KAAK;EAIpB,MAAM,cAAc,qBADD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAGtE,OAAO,iBAAiB,WAAW,eAAe,KAAA,CACpD;EACA,OAAO,MACL,gBAAgB,aAAa,EAC3B,KAAK,2BAA2B,QAAQ,YAAY,IAAI,cAC1D,CAAC,CACH;CACF,UAAU;EACR,MAAM,OAAO,MAAM;CACrB;AACF"}
|
package/dist/{migration-command-scaffold-ApB3NxWY.mjs → migration-command-scaffold-CIxCqBXa.mjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { A as formatStyledHeader, B as errorDatabaseConnectionRequired, H as errorDriverRequired, U as errorFileNotFound, at as errorTargetMigrationNotSupported, i as maskConnectionUrl, o as resolveContractPath, st as errorUnexpected, t as addGlobalOptions, z as errorContractValidationFailed } from "./command-helpers-DK_5ItoJ.mjs";
|
|
3
3
|
import { t as createProgressAdapter } from "./progress-adapter-C644QK8l.mjs";
|
|
4
|
-
import { t as createControlClient } from "./client-
|
|
4
|
+
import { t as createControlClient } from "./client-CcqChq9N.mjs";
|
|
5
5
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
7
7
|
import { hasMigrations } from "@prisma-next/framework-components/control";
|
|
@@ -100,4 +100,4 @@ function addMigrationCommandOptions(command) {
|
|
|
100
100
|
//#endregion
|
|
101
101
|
export { prepareMigrationContext as n, addMigrationCommandOptions as t };
|
|
102
102
|
|
|
103
|
-
//# sourceMappingURL=migration-command-scaffold-
|
|
103
|
+
//# sourceMappingURL=migration-command-scaffold-CIxCqBXa.mjs.map
|