prisma-next 0.11.0-dev.55 → 0.11.0-dev.57
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-errors-DFF1LlfU.mjs → cli-errors-DQY629C7.mjs} +16 -11
- package/dist/{cli-errors-DFF1LlfU.mjs.map → cli-errors-DQY629C7.mjs.map} +1 -1
- package/dist/cli.mjs +9 -9
- package/dist/{client-5uvDppD8.mjs → client-Ls2SAhrZ.mjs} +24 -6
- package/dist/{client-5uvDppD8.mjs.map → client-Ls2SAhrZ.mjs.map} +1 -1
- package/dist/{command-helpers-4UNsRRc4.mjs → command-helpers-DTpEJCgI.mjs} +2 -2
- package/dist/{command-helpers-4UNsRRc4.mjs.map → command-helpers-DTpEJCgI.mjs.map} +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +5 -5
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +4 -4
- package/dist/commands/db-update.mjs +5 -5
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +34 -38
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.mjs +1 -1
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +3 -3
- package/dist/commands/migration-list.d.mts +2 -2
- package/dist/commands/migration-list.mjs +1 -1
- package/dist/commands/migration-log.mjs +3 -3
- package/dist/commands/migration-new.mjs +4 -4
- package/dist/commands/migration-plan.d.mts +1 -1
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +1 -1
- package/dist/commands/migration-show.mjs +4 -4
- package/dist/commands/migration-status.d.mts +1 -1
- package/dist/commands/migration-status.mjs +6 -6
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +2 -2
- package/dist/contract-at-errors-B98TC1wK.mjs +42 -0
- package/dist/contract-at-errors-B98TC1wK.mjs.map +1 -0
- package/dist/{contract-emit-C-CFGZsI.mjs → contract-emit-BWLCn2PH.mjs} +3 -3
- package/dist/{contract-emit-C-CFGZsI.mjs.map → contract-emit-BWLCn2PH.mjs.map} +1 -1
- package/dist/{contract-emit-CuUzzM46.mjs → contract-emit-CS3vF-w9.mjs} +4 -4
- package/dist/{contract-emit-CuUzzM46.mjs.map → contract-emit-CS3vF-w9.mjs.map} +1 -1
- package/dist/{contract-infer-C98ZaRhp.mjs → contract-infer-BtefFYF-.mjs} +3 -3
- package/dist/{contract-infer-C98ZaRhp.mjs.map → contract-infer-BtefFYF-.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-CVHGuA35.mjs → contract-space-aggregate-loader-DX_1n2SA.mjs} +2 -2
- package/dist/{contract-space-aggregate-loader-CVHGuA35.mjs.map → contract-space-aggregate-loader-DX_1n2SA.mjs.map} +1 -1
- package/dist/{db-verify-BWl1Yxi-.mjs → db-verify-aHw2nzH2.mjs} +5 -5
- package/dist/{db-verify-BWl1Yxi-.mjs.map → db-verify-aHw2nzH2.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{framework-components-DTcjouhS.mjs → framework-components-BwuEBcyk.mjs} +2 -2
- package/dist/{framework-components-DTcjouhS.mjs.map → framework-components-BwuEBcyk.mjs.map} +1 -1
- package/dist/{global-flags-DWsQ6SSI.d.mts → global-flags-Bo6nCRUS.d.mts} +1 -1
- package/dist/{global-flags-DWsQ6SSI.d.mts.map → global-flags-Bo6nCRUS.d.mts.map} +1 -1
- package/dist/{glyph-mode-CBB4emzO.d.mts → glyph-mode-VIjULGFF.d.mts} +1 -1
- package/dist/glyph-mode-VIjULGFF.d.mts.map +1 -0
- package/dist/{graph-render-D2FnLpuK.mjs → graph-render-eJDcLWny.mjs} +1 -1
- package/dist/{graph-render-D2FnLpuK.mjs.map → graph-render-eJDcLWny.mjs.map} +1 -1
- package/dist/{init-C7PvN163.mjs → init-DOE4Q9YK.mjs} +5 -5
- package/dist/{init-C7PvN163.mjs.map → init-DOE4Q9YK.mjs.map} +1 -1
- package/dist/{inspect-live-schema-BRCWQ-Sr.mjs → inspect-live-schema-IS8jWaJy.mjs} +4 -4
- package/dist/{inspect-live-schema-BRCWQ-Sr.mjs.map → inspect-live-schema-IS8jWaJy.mjs.map} +1 -1
- package/dist/{migration-check-DoskM1nB.mjs → migration-check-BFdael8w.mjs} +2 -2
- package/dist/{migration-check-DoskM1nB.mjs.map → migration-check-BFdael8w.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-CXLkoIJx.mjs → migration-command-scaffold-DojkenVv.mjs} +4 -4
- package/dist/{migration-command-scaffold-CXLkoIJx.mjs.map → migration-command-scaffold-DojkenVv.mjs.map} +1 -1
- package/dist/{migration-list-B2-iQ5Jd.mjs → migration-list-hj86sCtZ.mjs} +3 -3
- package/dist/{migration-list-B2-iQ5Jd.mjs.map → migration-list-hj86sCtZ.mjs.map} +1 -1
- package/dist/{migration-plan-BqmIKQpZ.mjs → migration-plan-Bt6wxUIv.mjs} +165 -178
- package/dist/migration-plan-Bt6wxUIv.mjs.map +1 -0
- package/dist/{migration-types-q64xAI_J.d.mts → migration-types-D2FW63pr.d.mts} +1 -1
- package/dist/{migration-types-q64xAI_J.d.mts.map → migration-types-D2FW63pr.d.mts.map} +1 -1
- package/dist/{migrations-BcVTutso.mjs → migrations-CVLh0Kv4.mjs} +2 -2
- package/dist/{migrations-BcVTutso.mjs.map → migrations-CVLh0Kv4.mjs.map} +1 -1
- package/dist/{output-B60Gw5fu.mjs → output-CF_hqzI-.mjs} +1 -1
- package/dist/{output-B60Gw5fu.mjs.map → output-CF_hqzI-.mjs.map} +1 -1
- package/dist/{types-CEtm6v6a.d.mts → types-BuatV9YW.d.mts} +1 -1
- package/dist/{types-CEtm6v6a.d.mts.map → types-BuatV9YW.d.mts.map} +1 -1
- package/dist/{verify-DOHbbrub.mjs → verify-BiWm4XwD.mjs} +2 -2
- package/dist/{verify-DOHbbrub.mjs.map → verify-BiWm4XwD.mjs.map} +1 -1
- package/package.json +11 -11
- package/dist/glyph-mode-CBB4emzO.d.mts.map +0 -1
- package/dist/migration-plan-BqmIKQpZ.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import { O as errorUnexpected$1, t as CliStructuredError$1 } from "./cli-errors-
|
|
3
|
-
import { n as executeContractEmit } from "./contract-emit-
|
|
4
|
-
import { D as formatStyledHeader, O as formatSuccessMessage, d as setCommandDescriptions, f as setCommandExamples, j as isVerbose, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as handleResult, y as createTerminalUI } from "./command-helpers-
|
|
2
|
+
import { O as errorUnexpected$1, t as CliStructuredError$1 } from "./cli-errors-DQY629C7.mjs";
|
|
3
|
+
import { n as executeContractEmit } from "./contract-emit-BWLCn2PH.mjs";
|
|
4
|
+
import { D as formatStyledHeader, O as formatSuccessMessage, d as setCommandDescriptions, f as setCommandExamples, j as isVerbose, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as handleResult, y as createTerminalUI } from "./command-helpers-DTpEJCgI.mjs";
|
|
5
5
|
import { t as createProgressAdapter } from "./progress-adapter-xASh41wr.mjs";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { getEmittedArtifactPaths } from "@prisma-next/emitter";
|
|
@@ -148,4 +148,4 @@ function createContractEmitCommand() {
|
|
|
148
148
|
//#endregion
|
|
149
149
|
export { createContractEmitCommand as t };
|
|
150
150
|
|
|
151
|
-
//# sourceMappingURL=contract-emit-
|
|
151
|
+
//# sourceMappingURL=contract-emit-CS3vF-w9.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-emit-CuUzzM46.mjs","names":["CliStructuredError","errorUnexpected"],"sources":["../src/utils/formatters/emit.ts","../src/commands/contract-emit.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { relative } from 'pathe';\n\nimport type { GlobalFlags } from '../global-flags';\nimport { isVerbose } from './helpers';\n\n// EmitContractResult type for CLI output formatting (includes file paths)\nexport interface EmitContractResult {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n readonly outDir: string;\n readonly files: {\n readonly json: string;\n readonly dts: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for contract emit.\n */\nexport function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n // Convert absolute paths to relative paths from cwd\n const jsonPath = relative(process.cwd(), result.files.json);\n const dtsPath = relative(process.cwd(), result.files.dts);\n\n lines.push(`✔ Emitted contract.json → ${jsonPath}`);\n lines.push(`✔ Emitted contract.d.ts → ${dtsPath}`);\n lines.push(` storageHash: ${result.storageHash}`);\n if (result.executionHash) {\n lines.push(` executionHash: ${result.executionHash}`);\n }\n if (result.profileHash) {\n lines.push(` profileHash: ${result.profileHash}`);\n }\n if (isVerbose(flags, 1)) {\n lines.push(` Total time: ${result.timings.total}ms`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for contract emit.\n */\nexport function formatEmitJson(result: EmitContractResult): string {\n const output = {\n ok: true,\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n ...(result.profileHash ? { profileHash: result.profileHash } : {}),\n outDir: result.outDir,\n files: result.files,\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n","import { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { errorContractConfigMissing } from '@prisma-next/errors/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { executeContractEmit } from '../control-api/operations/contract-emit';\nimport type { ContractEmitResult } from '../control-api/types';\nimport { CliStructuredError, errorUnexpected } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport {\n type EmitContractResult,\n formatEmitJson,\n formatEmitOutput,\n} from '../utils/formatters/emit';\nimport { formatStyledHeader, formatSuccessMessage } from '../utils/formatters/styled';\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 ContractEmitOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly outputPath?: string;\n}\n\ninterface HeaderPaths {\n readonly displayConfigPath: string;\n readonly outputJsonPath: string;\n readonly outputDtsPath: string;\n}\n\n/**\n * Pre-load the config just to compute display paths for the styled header. The\n * actual emit work goes through `executeContractEmit`, which loads the config\n * itself; the redundant load here is bounded and lets the header render before\n * the emit spans start.\n */\nasync function resolveHeaderPaths(\n configOption: string | undefined,\n outputPath: string | undefined,\n): Promise<Result<HeaderPaths, CliStructuredError>> {\n const displayConfigPath = configOption\n ? relative(process.cwd(), resolve(configOption))\n : 'prisma-next.config.ts';\n\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(configOption);\n } catch (error) {\n if (error instanceof CliStructuredError) {\n return notOk(error);\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 effectiveJsonPath =\n outputPath !== undefined ? join(outputPath, 'contract.json') : config.contract?.output;\n\n if (!effectiveJsonPath) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract.output is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n }),\n );\n }\n\n try {\n const { jsonPath: outputJsonPath, dtsPath: outputDtsPath } =\n getEmittedArtifactPaths(effectiveJsonPath);\n return ok({ displayConfigPath, outputJsonPath, outputDtsPath });\n } catch (error) {\n return notOk(\n errorContractConfigMissing({\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n}\n\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n const outputPath = options.outputPath !== undefined ? resolve(options.outputPath) : undefined;\n\n const headerPathsResult = await resolveHeaderPaths(options.config, outputPath);\n if (!headerPathsResult.ok) {\n return headerPathsResult;\n }\n const { displayConfigPath, outputJsonPath, outputDtsPath } = headerPathsResult.value;\n\n if (!flags.json && !flags.quiet) {\n ui.stderr(\n formatStyledHeader({\n command: 'contract emit',\n description: 'Emit your contract artifacts',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: displayConfigPath },\n { label: 'contract', value: relative(process.cwd(), outputJsonPath) },\n { label: 'types', value: relative(process.cwd(), outputDtsPath) },\n ],\n flags,\n }),\n );\n }\n\n const onProgress = createProgressAdapter({ ui, flags });\n const configPath = options.config ? resolve(options.config) : 'prisma-next.config.ts';\n\n let result: ContractEmitResult;\n try {\n result = await executeContractEmit({\n configPath,\n onProgress,\n ...ifDefined('outputPath', outputPath),\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n\n if (result.validationWarning) {\n ui.warn(result.validationWarning);\n }\n\n return ok({\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n profileHash: result.profileHash,\n outDir: dirname(result.files.json),\n files: result.files,\n timings: { total: Date.now() - startTime },\n });\n}\n\nexport function createContractEmitCommand(): Command {\n const command = new Command('emit');\n setCommandDescriptions(\n command,\n 'Emit your contract artifacts',\n 'Reads your contract source (TypeScript or Prisma schema) and emits contract.json and\\n' +\n 'contract.d.ts. The contract.json contains the canonical contract structure, and\\n' +\n 'contract.d.ts provides TypeScript types for type-safe query building.',\n );\n setCommandExamples(command, [\n 'prisma-next contract emit',\n 'prisma-next contract emit --config ./custom-config.ts',\n 'prisma-next contract emit --output-path ./generated',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--output-path <dir>', 'Directory to write contract.json and contract.d.ts into')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (emitResult) => {\n if (flags.json) {\n ui.output(formatEmitJson(emitResult));\n } else {\n const output = formatEmitOutput(emitResult, flags);\n if (output) {\n ui.log(output);\n }\n if (!flags.quiet) {\n ui.success(formatSuccessMessage(flags));\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"contract-emit-CS3vF-w9.mjs","names":["CliStructuredError","errorUnexpected"],"sources":["../src/utils/formatters/emit.ts","../src/commands/contract-emit.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { relative } from 'pathe';\n\nimport type { GlobalFlags } from '../global-flags';\nimport { isVerbose } from './helpers';\n\n// EmitContractResult type for CLI output formatting (includes file paths)\nexport interface EmitContractResult {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n readonly outDir: string;\n readonly files: {\n readonly json: string;\n readonly dts: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for contract emit.\n */\nexport function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n // Convert absolute paths to relative paths from cwd\n const jsonPath = relative(process.cwd(), result.files.json);\n const dtsPath = relative(process.cwd(), result.files.dts);\n\n lines.push(`✔ Emitted contract.json → ${jsonPath}`);\n lines.push(`✔ Emitted contract.d.ts → ${dtsPath}`);\n lines.push(` storageHash: ${result.storageHash}`);\n if (result.executionHash) {\n lines.push(` executionHash: ${result.executionHash}`);\n }\n if (result.profileHash) {\n lines.push(` profileHash: ${result.profileHash}`);\n }\n if (isVerbose(flags, 1)) {\n lines.push(` Total time: ${result.timings.total}ms`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for contract emit.\n */\nexport function formatEmitJson(result: EmitContractResult): string {\n const output = {\n ok: true,\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n ...(result.profileHash ? { profileHash: result.profileHash } : {}),\n outDir: result.outDir,\n files: result.files,\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n","import { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { errorContractConfigMissing } from '@prisma-next/errors/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { executeContractEmit } from '../control-api/operations/contract-emit';\nimport type { ContractEmitResult } from '../control-api/types';\nimport { CliStructuredError, errorUnexpected } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport {\n type EmitContractResult,\n formatEmitJson,\n formatEmitOutput,\n} from '../utils/formatters/emit';\nimport { formatStyledHeader, formatSuccessMessage } from '../utils/formatters/styled';\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 ContractEmitOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly outputPath?: string;\n}\n\ninterface HeaderPaths {\n readonly displayConfigPath: string;\n readonly outputJsonPath: string;\n readonly outputDtsPath: string;\n}\n\n/**\n * Pre-load the config just to compute display paths for the styled header. The\n * actual emit work goes through `executeContractEmit`, which loads the config\n * itself; the redundant load here is bounded and lets the header render before\n * the emit spans start.\n */\nasync function resolveHeaderPaths(\n configOption: string | undefined,\n outputPath: string | undefined,\n): Promise<Result<HeaderPaths, CliStructuredError>> {\n const displayConfigPath = configOption\n ? relative(process.cwd(), resolve(configOption))\n : 'prisma-next.config.ts';\n\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(configOption);\n } catch (error) {\n if (error instanceof CliStructuredError) {\n return notOk(error);\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 effectiveJsonPath =\n outputPath !== undefined ? join(outputPath, 'contract.json') : config.contract?.output;\n\n if (!effectiveJsonPath) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract.output is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n }),\n );\n }\n\n try {\n const { jsonPath: outputJsonPath, dtsPath: outputDtsPath } =\n getEmittedArtifactPaths(effectiveJsonPath);\n return ok({ displayConfigPath, outputJsonPath, outputDtsPath });\n } catch (error) {\n return notOk(\n errorContractConfigMissing({\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n}\n\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n const outputPath = options.outputPath !== undefined ? resolve(options.outputPath) : undefined;\n\n const headerPathsResult = await resolveHeaderPaths(options.config, outputPath);\n if (!headerPathsResult.ok) {\n return headerPathsResult;\n }\n const { displayConfigPath, outputJsonPath, outputDtsPath } = headerPathsResult.value;\n\n if (!flags.json && !flags.quiet) {\n ui.stderr(\n formatStyledHeader({\n command: 'contract emit',\n description: 'Emit your contract artifacts',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: displayConfigPath },\n { label: 'contract', value: relative(process.cwd(), outputJsonPath) },\n { label: 'types', value: relative(process.cwd(), outputDtsPath) },\n ],\n flags,\n }),\n );\n }\n\n const onProgress = createProgressAdapter({ ui, flags });\n const configPath = options.config ? resolve(options.config) : 'prisma-next.config.ts';\n\n let result: ContractEmitResult;\n try {\n result = await executeContractEmit({\n configPath,\n onProgress,\n ...ifDefined('outputPath', outputPath),\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n\n if (result.validationWarning) {\n ui.warn(result.validationWarning);\n }\n\n return ok({\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n profileHash: result.profileHash,\n outDir: dirname(result.files.json),\n files: result.files,\n timings: { total: Date.now() - startTime },\n });\n}\n\nexport function createContractEmitCommand(): Command {\n const command = new Command('emit');\n setCommandDescriptions(\n command,\n 'Emit your contract artifacts',\n 'Reads your contract source (TypeScript or Prisma schema) and emits contract.json and\\n' +\n 'contract.d.ts. The contract.json contains the canonical contract structure, and\\n' +\n 'contract.d.ts provides TypeScript types for type-safe query building.',\n );\n setCommandExamples(command, [\n 'prisma-next contract emit',\n 'prisma-next contract emit --config ./custom-config.ts',\n 'prisma-next contract emit --output-path ./generated',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--output-path <dir>', 'Directory to write contract.json and contract.d.ts into')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (emitResult) => {\n if (flags.json) {\n ui.output(formatEmitJson(emitResult));\n } else {\n const output = formatEmitOutput(emitResult, flags);\n if (output) {\n ui.log(output);\n }\n if (!flags.quiet) {\n ui.success(formatSuccessMessage(flags));\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as setCommandDescriptions, f as setCommandExamples, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as handleResult, y as createTerminalUI } from "./command-helpers-
|
|
2
|
-
import { t as inspectLiveSchema } from "./inspect-live-schema-
|
|
1
|
+
import { d as setCommandDescriptions, f as setCommandExamples, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as handleResult, y as createTerminalUI } from "./command-helpers-DTpEJCgI.mjs";
|
|
2
|
+
import { t as inspectLiveSchema } from "./inspect-live-schema-IS8jWaJy.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-BtefFYF-.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-infer-
|
|
1
|
+
{"version":3,"file":"contract-infer-BtefFYF-.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,4 +1,4 @@
|
|
|
1
|
-
import { t as CliStructuredError } from "./cli-errors-
|
|
1
|
+
import { t as CliStructuredError } from "./cli-errors-DQY629C7.mjs";
|
|
2
2
|
import { t as toDeclaredExtensionsFromRaw } from "./extension-pack-inputs-BiY86HbQ.mjs";
|
|
3
3
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
4
4
|
import { loadContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
|
|
@@ -167,4 +167,4 @@ async function buildContractSpaceAggregate(inputs) {
|
|
|
167
167
|
//#endregion
|
|
168
168
|
export { refusePackageCorruptionOnAggregate as i, loadContractSpaceAggregateForCli as n, refuseContractSpaceIntegrity as r, buildContractSpaceAggregate as t };
|
|
169
169
|
|
|
170
|
-
//# sourceMappingURL=contract-space-aggregate-loader-
|
|
170
|
+
//# sourceMappingURL=contract-space-aggregate-loader-DX_1n2SA.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-space-aggregate-loader-CVHGuA35.mjs","names":[],"sources":["../src/utils/contract-space-aggregate-loader.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { ControlExtensionDescriptor } from '@prisma-next/framework-components/control';\nimport type {\n ContractSpaceAggregate,\n DeclaredExtensionEntry,\n IntegrityQueryOptions,\n IntegrityViolation,\n} from '@prisma-next/migration-tools/aggregate';\nimport { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { CliStructuredError } from './cli-errors';\nimport { toDeclaredExtensionsFromRaw } from './extension-pack-inputs';\n\nconst CONTRACT_SPACES_DOCS_URL = 'https://pris.ly/contract-spaces';\n\nfunction contractSpaceError5002(\n summary: string,\n options: {\n readonly why: string;\n readonly fix: string;\n readonly violations: readonly IntegrityViolation[];\n },\n): CliStructuredError {\n return new CliStructuredError('5002', summary, {\n domain: 'MIG',\n why: options.why,\n fix: options.fix,\n docsUrl: CONTRACT_SPACES_DOCS_URL,\n meta: { violations: options.violations },\n });\n}\n\n/**\n * Build the `5002` structured-error envelope for a contract-space\n * target mismatch. Shared between the declared-extension precheck (the\n * descriptor's configured target disagrees with the project target) and\n * the on-disk-contract check surfaced by `checkIntegrity`.\n */\nfunction targetMismatchError(\n spaceId: string,\n expected: string,\n actual: string,\n): CliStructuredError {\n return contractSpaceError5002(`Contract-space target mismatch for \"${spaceId}\"`, {\n why: `Space \"${spaceId}\" targets \"${actual}\" but the project's adapter targets \"${expected}\".`,\n fix: 'Update the extension descriptor to target the configured database, or change the project adapter.',\n violations: [{ kind: 'targetMismatch', spaceId, expected, actual }],\n });\n}\n\n/**\n * Human-readable detail for an integrity violation, used as the `why`\n * of the `integrityFailure` envelope. Mirrors the messages the prior\n * throw-on-load loader produced so downstream consumers see the same\n * text for the same on-disk state.\n */\nfunction describeIntegrityViolation(violation: IntegrityViolation): string {\n switch (violation.kind) {\n case 'hashMismatch':\n return `Migration \"${violation.dirName}\" stored hash \"${violation.stored}\" does not match computed hash \"${violation.computed}\".`;\n case 'providedInvariantsMismatch':\n return `Migration \"${violation.dirName}\" providedInvariants in migration.json disagrees with ops.json.`;\n case 'packageUnloadable':\n return `Migration \"${violation.dirName}\" could not be loaded: ${violation.detail}`;\n case 'sameSourceAndTarget':\n return `Migration \"${violation.dirName}\" has source equal to target (${violation.hash}) with no data invariant — a true no-op self-edge.`;\n case 'headRefMissing':\n return `Head ref \\`refs/head.json\\` is missing for contract space \"${violation.spaceId}\".`;\n case 'headRefNotInGraph':\n return `Head ref ${violation.hash} for contract space \"${violation.spaceId}\" is not present in the migration graph.`;\n case 'refUnreadable':\n return `Ref \"${violation.refName}\" for contract space \"${violation.spaceId}\" is unreadable: ${violation.detail}`;\n case 'duplicateMigrationHash':\n return `Multiple migrations in space \"${violation.spaceId}\" share migrationHash \"${violation.migrationHash}\" (${violation.dirNames.join(', ')}).`;\n default: {\n const spaceId = 'spaceId' in violation ? violation.spaceId : '*';\n return `Integrity violation \"${violation.kind}\" for contract space \"${spaceId}\".`;\n }\n }\n}\n\n/**\n * Map the integrity violations `checkIntegrity` reports into a single\n * CLI structured-error envelope, preserving the error codes the prior\n * throw-on-load loader emitted: `5001` (layout drift, bundled) and\n * `5002` (target / disjointness / contract-validation / structural\n * integrity). Returns `null` when there is nothing to refuse on.\n *\n * Precedence reproduces the prior loader's first-failure ordering:\n * layout drift first (every offence bundled into one envelope), then\n * target mismatch, then disjointness, then a contract-validation\n * failure, then any remaining structural integrity violation.\n */\nexport function mapIntegrityViolations(\n violations: readonly IntegrityViolation[],\n): CliStructuredError | null {\n if (violations.length === 0) return null;\n\n const layout = violations.filter(\n (v): v is Extract<IntegrityViolation, { kind: 'orphanSpaceDir' | 'declaredButUnmigrated' }> =>\n v.kind === 'orphanSpaceDir' || v.kind === 'declaredButUnmigrated',\n );\n if (layout.length > 0) {\n const lines = layout.map((v) => `- [${v.kind}] ${v.spaceId}`);\n const summary =\n layout.length === 1\n ? 'Contract-space layout violation detected'\n : `Contract-space layout violations detected (${layout.length})`;\n return new CliStructuredError('5001', summary, {\n domain: 'MIG',\n why: `The on-disk \\`migrations/\\` directory and your \\`extensionPacks\\` declaration are not in agreement.\\n${lines.join('\\n')}`,\n fix: 'Declare the extension in `extensionPacks` and re-emit its contract-space artefacts, or remove the orphan `migrations/<space>` directory.',\n docsUrl: CONTRACT_SPACES_DOCS_URL,\n meta: { violations: layout },\n });\n }\n\n const targetMismatch = violations.find((v) => v.kind === 'targetMismatch');\n if (targetMismatch && targetMismatch.kind === 'targetMismatch') {\n return targetMismatchError(\n targetMismatch.spaceId,\n targetMismatch.expected,\n targetMismatch.actual,\n );\n }\n\n const disjointness = violations.find((v) => v.kind === 'disjointness');\n if (disjointness && disjointness.kind === 'disjointness') {\n return contractSpaceError5002(\n `Contract-space disjointness violation: storage element \"${disjointness.element}\" claimed by multiple spaces`,\n {\n why: `Spaces ${disjointness.claimedBy.map((s) => `\"${s}\"`).join(', ')} all claim the storage element \"${disjointness.element}\". Each storage element must be owned by exactly one contract space.`,\n fix: 'Update the conflicting contracts so each storage element is claimed by exactly one space.',\n violations: [disjointness],\n },\n );\n }\n\n const contractUnreadable = violations.find((v) => v.kind === 'contractUnreadable');\n if (contractUnreadable && contractUnreadable.kind === 'contractUnreadable') {\n return contractSpaceError5002(\n `Contract-space contract validation failed for \"${contractUnreadable.spaceId}\"`,\n {\n why: contractUnreadable.detail,\n fix: 'Re-emit the extension contract with `prisma-next contract emit`, or fix the extension pack descriptor producing the invalid contract.',\n violations: [contractUnreadable],\n },\n );\n }\n\n // Any remaining recoverable structural violation refuses as an\n // integrity failure, surfacing the first one's detail (every violation\n // is still computed; the gate just renders one envelope).\n const structural = violations[0]!;\n const spaceId = 'spaceId' in structural ? structural.spaceId : '*';\n return contractSpaceError5002(`Contract-space integrity failure for \"${spaceId}\"`, {\n why: describeIntegrityViolation(structural),\n fix: 'Re-emit the affected migration package(s) or restore the on-disk `migrations/` directory from version control.',\n violations: [structural],\n });\n}\n\n/**\n * Inputs needed to compose the aggregate loader at the CLI surface.\n *\n * Keeps the loader framework-neutral (no `Config` import) by accepting\n * already-resolved structural inputs: validated app contract, target\n * id, migrations root directory, and the set of extension descriptors.\n */\nexport interface BuildAggregateInputs<TFamilyId extends string, TTargetId extends string> {\n readonly targetId: TTargetId;\n readonly migrationsDir: string;\n readonly appContract: Contract;\n readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;\n readonly deserializeContract: (contractJson: unknown) => Contract;\n}\n\nfunction declaredExtensionsFromInputs(\n extensionPacks: BuildAggregateInputs<string, string>['extensionPacks'],\n): readonly DeclaredExtensionEntry[] {\n return toDeclaredExtensionsFromRaw(extensionPacks as ReadonlyArray<unknown>);\n}\n\n/**\n * Reject extension descriptors whose configured target disagrees with\n * the project target before any on-disk read.\n */\nexport function refuseDeclaredExtensionTargetMismatch<\n TFamilyId extends string,\n TTargetId extends string,\n>(inputs: BuildAggregateInputs<TFamilyId, TTargetId>): CliStructuredError | null {\n for (const declared of declaredExtensionsFromInputs(inputs.extensionPacks)) {\n if (declared.targetId !== inputs.targetId) {\n return targetMismatchError(declared.id, inputs.targetId, declared.targetId);\n }\n }\n return null;\n}\n\n/**\n * Load the tolerant {@link ContractSpaceAggregate} once at the CLI\n * surface. Construction never throws on disk content; callers query\n * {@link ContractSpaceAggregate.app} / extension facets instead of\n * re-reading `migrations/`.\n */\nexport async function loadContractSpaceAggregateForCli<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n inputs: BuildAggregateInputs<TFamilyId, TTargetId>,\n): Promise<Result<ContractSpaceAggregate, CliStructuredError>> {\n const targetFailure = refuseDeclaredExtensionTargetMismatch(inputs);\n if (targetFailure) {\n return notOk(targetFailure);\n }\n\n const aggregate = await loadContractSpaceAggregate({\n migrationsDir: inputs.migrationsDir,\n deserializeContract: inputs.deserializeContract,\n appContract: inputs.appContract,\n });\n return ok(aggregate);\n}\n\n/**\n * Run `checkIntegrity` on a loaded aggregate and map violations into\n * the contract-space refusal envelope, or return `null` when the model\n * is acceptable for the requested check scope.\n */\nexport function refuseContractSpaceIntegrity(\n aggregate: ContractSpaceAggregate,\n options: IntegrityQueryOptions,\n): CliStructuredError | null {\n return mapIntegrityViolations(aggregate.checkIntegrity(options));\n}\n\nconst PACKAGE_CORRUPTION_KINDS = new Set<IntegrityViolation['kind']>([\n 'hashMismatch',\n 'providedInvariantsMismatch',\n 'packageUnloadable',\n]);\n\n/**\n * Reader-subset integrity refusal for `migration status`: package\n * corruptions only (`hashMismatch`, `providedInvariantsMismatch`,\n * `packageUnloadable`).\n */\nexport function refusePackageCorruptionOnAggregate(\n aggregate: ContractSpaceAggregate,\n): CliStructuredError | null {\n const corruption = aggregate.checkIntegrity().filter((v) => PACKAGE_CORRUPTION_KINDS.has(v.kind));\n return mapIntegrityViolations(corruption);\n}\n\n/**\n * Construct the tolerant {@link ContractSpaceAggregate} at the CLI\n * surface and apply the explicit integrity refusal.\n *\n * App-space migration packages are read from `migrations/<app>/` by the\n * loader itself; callers no longer thread them through.\n */\nexport async function buildContractSpaceAggregate<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n inputs: BuildAggregateInputs<TFamilyId, TTargetId>,\n): Promise<Result<ContractSpaceAggregate, CliStructuredError>> {\n const declaredExtensions = declaredExtensionsFromInputs(inputs.extensionPacks);\n const loaded = await loadContractSpaceAggregateForCli(inputs);\n if (!loaded.ok) {\n return loaded;\n }\n const failure = refuseContractSpaceIntegrity(loaded.value, {\n declaredExtensions,\n checkContracts: true,\n });\n if (failure) {\n return notOk(failure);\n }\n return ok(loaded.value);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"contract-space-aggregate-loader-DX_1n2SA.mjs","names":[],"sources":["../src/utils/contract-space-aggregate-loader.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { ControlExtensionDescriptor } from '@prisma-next/framework-components/control';\nimport type {\n ContractSpaceAggregate,\n DeclaredExtensionEntry,\n IntegrityQueryOptions,\n IntegrityViolation,\n} from '@prisma-next/migration-tools/aggregate';\nimport { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { CliStructuredError } from './cli-errors';\nimport { toDeclaredExtensionsFromRaw } from './extension-pack-inputs';\n\nconst CONTRACT_SPACES_DOCS_URL = 'https://pris.ly/contract-spaces';\n\nfunction contractSpaceError5002(\n summary: string,\n options: {\n readonly why: string;\n readonly fix: string;\n readonly violations: readonly IntegrityViolation[];\n },\n): CliStructuredError {\n return new CliStructuredError('5002', summary, {\n domain: 'MIG',\n why: options.why,\n fix: options.fix,\n docsUrl: CONTRACT_SPACES_DOCS_URL,\n meta: { violations: options.violations },\n });\n}\n\n/**\n * Build the `5002` structured-error envelope for a contract-space\n * target mismatch. Shared between the declared-extension precheck (the\n * descriptor's configured target disagrees with the project target) and\n * the on-disk-contract check surfaced by `checkIntegrity`.\n */\nfunction targetMismatchError(\n spaceId: string,\n expected: string,\n actual: string,\n): CliStructuredError {\n return contractSpaceError5002(`Contract-space target mismatch for \"${spaceId}\"`, {\n why: `Space \"${spaceId}\" targets \"${actual}\" but the project's adapter targets \"${expected}\".`,\n fix: 'Update the extension descriptor to target the configured database, or change the project adapter.',\n violations: [{ kind: 'targetMismatch', spaceId, expected, actual }],\n });\n}\n\n/**\n * Human-readable detail for an integrity violation, used as the `why`\n * of the `integrityFailure` envelope. Mirrors the messages the prior\n * throw-on-load loader produced so downstream consumers see the same\n * text for the same on-disk state.\n */\nfunction describeIntegrityViolation(violation: IntegrityViolation): string {\n switch (violation.kind) {\n case 'hashMismatch':\n return `Migration \"${violation.dirName}\" stored hash \"${violation.stored}\" does not match computed hash \"${violation.computed}\".`;\n case 'providedInvariantsMismatch':\n return `Migration \"${violation.dirName}\" providedInvariants in migration.json disagrees with ops.json.`;\n case 'packageUnloadable':\n return `Migration \"${violation.dirName}\" could not be loaded: ${violation.detail}`;\n case 'sameSourceAndTarget':\n return `Migration \"${violation.dirName}\" has source equal to target (${violation.hash}) with no data invariant — a true no-op self-edge.`;\n case 'headRefMissing':\n return `Head ref \\`refs/head.json\\` is missing for contract space \"${violation.spaceId}\".`;\n case 'headRefNotInGraph':\n return `Head ref ${violation.hash} for contract space \"${violation.spaceId}\" is not present in the migration graph.`;\n case 'refUnreadable':\n return `Ref \"${violation.refName}\" for contract space \"${violation.spaceId}\" is unreadable: ${violation.detail}`;\n case 'duplicateMigrationHash':\n return `Multiple migrations in space \"${violation.spaceId}\" share migrationHash \"${violation.migrationHash}\" (${violation.dirNames.join(', ')}).`;\n default: {\n const spaceId = 'spaceId' in violation ? violation.spaceId : '*';\n return `Integrity violation \"${violation.kind}\" for contract space \"${spaceId}\".`;\n }\n }\n}\n\n/**\n * Map the integrity violations `checkIntegrity` reports into a single\n * CLI structured-error envelope, preserving the error codes the prior\n * throw-on-load loader emitted: `5001` (layout drift, bundled) and\n * `5002` (target / disjointness / contract-validation / structural\n * integrity). Returns `null` when there is nothing to refuse on.\n *\n * Precedence reproduces the prior loader's first-failure ordering:\n * layout drift first (every offence bundled into one envelope), then\n * target mismatch, then disjointness, then a contract-validation\n * failure, then any remaining structural integrity violation.\n */\nexport function mapIntegrityViolations(\n violations: readonly IntegrityViolation[],\n): CliStructuredError | null {\n if (violations.length === 0) return null;\n\n const layout = violations.filter(\n (v): v is Extract<IntegrityViolation, { kind: 'orphanSpaceDir' | 'declaredButUnmigrated' }> =>\n v.kind === 'orphanSpaceDir' || v.kind === 'declaredButUnmigrated',\n );\n if (layout.length > 0) {\n const lines = layout.map((v) => `- [${v.kind}] ${v.spaceId}`);\n const summary =\n layout.length === 1\n ? 'Contract-space layout violation detected'\n : `Contract-space layout violations detected (${layout.length})`;\n return new CliStructuredError('5001', summary, {\n domain: 'MIG',\n why: `The on-disk \\`migrations/\\` directory and your \\`extensionPacks\\` declaration are not in agreement.\\n${lines.join('\\n')}`,\n fix: 'Declare the extension in `extensionPacks` and re-emit its contract-space artefacts, or remove the orphan `migrations/<space>` directory.',\n docsUrl: CONTRACT_SPACES_DOCS_URL,\n meta: { violations: layout },\n });\n }\n\n const targetMismatch = violations.find((v) => v.kind === 'targetMismatch');\n if (targetMismatch && targetMismatch.kind === 'targetMismatch') {\n return targetMismatchError(\n targetMismatch.spaceId,\n targetMismatch.expected,\n targetMismatch.actual,\n );\n }\n\n const disjointness = violations.find((v) => v.kind === 'disjointness');\n if (disjointness && disjointness.kind === 'disjointness') {\n return contractSpaceError5002(\n `Contract-space disjointness violation: storage element \"${disjointness.element}\" claimed by multiple spaces`,\n {\n why: `Spaces ${disjointness.claimedBy.map((s) => `\"${s}\"`).join(', ')} all claim the storage element \"${disjointness.element}\". Each storage element must be owned by exactly one contract space.`,\n fix: 'Update the conflicting contracts so each storage element is claimed by exactly one space.',\n violations: [disjointness],\n },\n );\n }\n\n const contractUnreadable = violations.find((v) => v.kind === 'contractUnreadable');\n if (contractUnreadable && contractUnreadable.kind === 'contractUnreadable') {\n return contractSpaceError5002(\n `Contract-space contract validation failed for \"${contractUnreadable.spaceId}\"`,\n {\n why: contractUnreadable.detail,\n fix: 'Re-emit the extension contract with `prisma-next contract emit`, or fix the extension pack descriptor producing the invalid contract.',\n violations: [contractUnreadable],\n },\n );\n }\n\n // Any remaining recoverable structural violation refuses as an\n // integrity failure, surfacing the first one's detail (every violation\n // is still computed; the gate just renders one envelope).\n const structural = violations[0]!;\n const spaceId = 'spaceId' in structural ? structural.spaceId : '*';\n return contractSpaceError5002(`Contract-space integrity failure for \"${spaceId}\"`, {\n why: describeIntegrityViolation(structural),\n fix: 'Re-emit the affected migration package(s) or restore the on-disk `migrations/` directory from version control.',\n violations: [structural],\n });\n}\n\n/**\n * Inputs needed to compose the aggregate loader at the CLI surface.\n *\n * Keeps the loader framework-neutral (no `Config` import) by accepting\n * already-resolved structural inputs: validated app contract, target\n * id, migrations root directory, and the set of extension descriptors.\n */\nexport interface BuildAggregateInputs<TFamilyId extends string, TTargetId extends string> {\n readonly targetId: TTargetId;\n readonly migrationsDir: string;\n readonly appContract: Contract;\n readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;\n readonly deserializeContract: (contractJson: unknown) => Contract;\n}\n\nfunction declaredExtensionsFromInputs(\n extensionPacks: BuildAggregateInputs<string, string>['extensionPacks'],\n): readonly DeclaredExtensionEntry[] {\n return toDeclaredExtensionsFromRaw(extensionPacks as ReadonlyArray<unknown>);\n}\n\n/**\n * Reject extension descriptors whose configured target disagrees with\n * the project target before any on-disk read.\n */\nexport function refuseDeclaredExtensionTargetMismatch<\n TFamilyId extends string,\n TTargetId extends string,\n>(inputs: BuildAggregateInputs<TFamilyId, TTargetId>): CliStructuredError | null {\n for (const declared of declaredExtensionsFromInputs(inputs.extensionPacks)) {\n if (declared.targetId !== inputs.targetId) {\n return targetMismatchError(declared.id, inputs.targetId, declared.targetId);\n }\n }\n return null;\n}\n\n/**\n * Load the tolerant {@link ContractSpaceAggregate} once at the CLI\n * surface. Construction never throws on disk content; callers query\n * {@link ContractSpaceAggregate.app} / extension facets instead of\n * re-reading `migrations/`.\n */\nexport async function loadContractSpaceAggregateForCli<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n inputs: BuildAggregateInputs<TFamilyId, TTargetId>,\n): Promise<Result<ContractSpaceAggregate, CliStructuredError>> {\n const targetFailure = refuseDeclaredExtensionTargetMismatch(inputs);\n if (targetFailure) {\n return notOk(targetFailure);\n }\n\n const aggregate = await loadContractSpaceAggregate({\n migrationsDir: inputs.migrationsDir,\n deserializeContract: inputs.deserializeContract,\n appContract: inputs.appContract,\n });\n return ok(aggregate);\n}\n\n/**\n * Run `checkIntegrity` on a loaded aggregate and map violations into\n * the contract-space refusal envelope, or return `null` when the model\n * is acceptable for the requested check scope.\n */\nexport function refuseContractSpaceIntegrity(\n aggregate: ContractSpaceAggregate,\n options: IntegrityQueryOptions,\n): CliStructuredError | null {\n return mapIntegrityViolations(aggregate.checkIntegrity(options));\n}\n\nconst PACKAGE_CORRUPTION_KINDS = new Set<IntegrityViolation['kind']>([\n 'hashMismatch',\n 'providedInvariantsMismatch',\n 'packageUnloadable',\n]);\n\n/**\n * Reader-subset integrity refusal for `migration status`: package\n * corruptions only (`hashMismatch`, `providedInvariantsMismatch`,\n * `packageUnloadable`).\n */\nexport function refusePackageCorruptionOnAggregate(\n aggregate: ContractSpaceAggregate,\n): CliStructuredError | null {\n const corruption = aggregate.checkIntegrity().filter((v) => PACKAGE_CORRUPTION_KINDS.has(v.kind));\n return mapIntegrityViolations(corruption);\n}\n\n/**\n * Construct the tolerant {@link ContractSpaceAggregate} at the CLI\n * surface and apply the explicit integrity refusal.\n *\n * App-space migration packages are read from `migrations/<app>/` by the\n * loader itself; callers no longer thread them through.\n */\nexport async function buildContractSpaceAggregate<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n inputs: BuildAggregateInputs<TFamilyId, TTargetId>,\n): Promise<Result<ContractSpaceAggregate, CliStructuredError>> {\n const declaredExtensions = declaredExtensionsFromInputs(inputs.extensionPacks);\n const loaded = await loadContractSpaceAggregateForCli(inputs);\n if (!loaded.ok) {\n return loaded;\n }\n const failure = refuseContractSpaceIntegrity(loaded.value, {\n declaredExtensions,\n checkContracts: true,\n });\n if (failure) {\n return notOk(failure);\n }\n return ok(loaded.value);\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import { C as errorRuntime, D as errorTargetMismatch, O as errorUnexpected, a as errorContractValidationFailed, c as errorDriverRequired, l as errorFileNotFound, m as errorMarkerMissing, o as errorDatabaseConnectionRequired, t as CliStructuredError, u as errorHashMismatch } from "./cli-errors-
|
|
3
|
-
import { D as formatStyledHeader, c as resolveContractPath, d as setCommandDescriptions, f as setCommandExamples, l as resolveMigrationPaths, o as maskConnectionUrl, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as handleResult, y as createTerminalUI } from "./command-helpers-
|
|
2
|
+
import { C as errorRuntime, D as errorTargetMismatch, O as errorUnexpected, a as errorContractValidationFailed, c as errorDriverRequired, l as errorFileNotFound, m as errorMarkerMissing, o as errorDatabaseConnectionRequired, t as CliStructuredError, u as errorHashMismatch } from "./cli-errors-DQY629C7.mjs";
|
|
3
|
+
import { D as formatStyledHeader, c as resolveContractPath, d as setCommandDescriptions, f as setCommandExamples, l as resolveMigrationPaths, o as maskConnectionUrl, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as handleResult, y as createTerminalUI } from "./command-helpers-DTpEJCgI.mjs";
|
|
4
4
|
import { t as createProgressAdapter } from "./progress-adapter-xASh41wr.mjs";
|
|
5
|
-
import { a as ContractValidationError, t as createControlClient } from "./client-
|
|
6
|
-
import { c as formatVerifyOutput, i as formatSchemaVerifyOutput, r as formatSchemaVerifyJson, s as formatVerifyJson } from "./verify-
|
|
5
|
+
import { a as ContractValidationError, t as createControlClient } from "./client-Ls2SAhrZ.mjs";
|
|
6
|
+
import { c as formatVerifyOutput, i as formatSchemaVerifyOutput, r as formatSchemaVerifyJson, s as formatVerifyJson } from "./verify-BiWm4XwD.mjs";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
9
9
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -399,4 +399,4 @@ function createDbVerifyCommand() {
|
|
|
399
399
|
//#endregion
|
|
400
400
|
export { createDbVerifyCommand as t };
|
|
401
401
|
|
|
402
|
-
//# sourceMappingURL=db-verify-
|
|
402
|
+
//# sourceMappingURL=db-verify-aHw2nzH2.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-verify-BWl1Yxi-.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-aHw2nzH2.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 EmitSuccess, D as SchemaVerifyOptions, E as OnControlProgress, M as executeDbVerify, O as SignOptions, S as EmitResult, _ as DbUpdateSuccess, a as ControlClient, b as EmitFailureCode, c as DbInitFailure, d as DbInitResult, f as DbInitSuccess, g as DbUpdateResult, h as DbUpdateOptions, i as ControlActionName, j as ExecuteDbVerifyResult, k as VerifyOptions, l as DbInitFailureCode, m as DbUpdateFailureCode, n as ContractEmitOptions, o as ControlClientOptions, p as DbUpdateFailure, r as ContractEmitResult, s as ControlProgressEvent, u as DbInitOptions, v as EmitContractConfig, w as IntrospectOptions, x as EmitOptions, y as EmitFailure } from "../types-
|
|
1
|
+
import { A as ExecuteDbVerifyOptions, C as EmitSuccess, D as SchemaVerifyOptions, E as OnControlProgress, M as executeDbVerify, O as SignOptions, S as EmitResult, _ as DbUpdateSuccess, a as ControlClient, b as EmitFailureCode, c as DbInitFailure, d as DbInitResult, f as DbInitSuccess, g as DbUpdateResult, h as DbUpdateOptions, i as ControlActionName, j as ExecuteDbVerifyResult, k as VerifyOptions, l as DbInitFailureCode, m as DbUpdateFailureCode, n as ContractEmitOptions, o as ControlClientOptions, p as DbUpdateFailure, r as ContractEmitResult, s as ControlProgressEvent, u as DbInitOptions, v as EmitContractConfig, w as IntrospectOptions, x as EmitOptions, y as EmitFailure } from "../types-BuatV9YW.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";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as executeContractEmit, r as disposeEmitQueue } from "../contract-emit-
|
|
1
|
+
import { n as executeContractEmit, r as disposeEmitQueue } from "../contract-emit-BWLCn2PH.mjs";
|
|
2
2
|
import { t as enrichContract } from "../contract-enrichment-XmUPhmsS.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-Ls2SAhrZ.mjs";
|
|
4
4
|
export { createControlClient, disposeEmitQueue, enrichContract, executeContractEmit, executeDbInit, executeDbUpdate, executeDbVerify };
|
package/dist/exports/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createContractEmitCommand } from "../contract-emit-
|
|
1
|
+
import { t as createContractEmitCommand } from "../contract-emit-CS3vF-w9.mjs";
|
|
2
2
|
import { join, resolve } from "pathe";
|
|
3
3
|
import { existsSync, unlinkSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as InitOutputSchema } from "../output-
|
|
1
|
+
import { t as InitOutputSchema } from "../output-CF_hqzI-.mjs";
|
|
2
2
|
export { InitOutputSchema };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as errorConfigValidation } from "./cli-errors-
|
|
1
|
+
import { r as errorConfigValidation } from "./cli-errors-DQY629C7.mjs";
|
|
2
2
|
import "@prisma-next/framework-components/components";
|
|
3
3
|
//#region src/utils/framework-components.ts
|
|
4
4
|
/**
|
|
@@ -55,4 +55,4 @@ function assertFrameworkComponentsCompatible(expectedFamilyId, expectedTargetId,
|
|
|
55
55
|
//#endregion
|
|
56
56
|
export { assertFrameworkComponentsCompatible as t };
|
|
57
57
|
|
|
58
|
-
//# sourceMappingURL=framework-components-
|
|
58
|
+
//# sourceMappingURL=framework-components-BwuEBcyk.mjs.map
|
package/dist/{framework-components-DTcjouhS.mjs.map → framework-components-BwuEBcyk.mjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"framework-components-
|
|
1
|
+
{"version":3,"file":"framework-components-BwuEBcyk.mjs","names":[],"sources":["../src/utils/framework-components.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport {\n checkContractComponentRequirements,\n type TargetBoundComponentDescriptor,\n} from '@prisma-next/framework-components/components';\nimport type { ControlStack } from '@prisma-next/framework-components/control';\nimport { errorConfigValidation, errorContractMissingExtensionPacks } from './cli-errors';\n\n/**\n * Asserts that all framework components are compatible with the expected family and target.\n *\n * This function validates that each component in the framework components array:\n * - Has kind 'target', 'adapter', 'extension', or 'driver'\n * - Has familyId matching expectedFamilyId\n * - Has targetId matching expectedTargetId\n *\n * This validation happens at the CLI composition boundary, before passing components\n * to typed planner/runner instances. It fills the gap between runtime validation\n * (via `validateConfig()`) and compile-time type enforcement.\n *\n * @param expectedFamilyId - The expected family ID (e.g., 'sql')\n * @param expectedTargetId - The expected target ID (e.g., 'postgres')\n * @param frameworkComponents - Array of framework components to validate\n * @returns The same array typed as TargetBoundComponentDescriptor\n * @throws CliStructuredError if any component is incompatible\n *\n * @example\n * ```ts\n * const config = await loadConfig();\n * const frameworkComponents = [config.target, config.adapter, ...(config.extensionPacks ?? [])];\n *\n * // Validate and type-narrow components before passing to planner\n * const typedComponents = assertFrameworkComponentsCompatible(\n * config.family.familyId,\n * config.target.targetId,\n * frameworkComponents\n * );\n *\n * const planner = target.migrations.createPlanner(familyInstance);\n * planner.plan({ contract, schema, policy, frameworkComponents: typedComponents });\n * ```\n */\nexport function assertFrameworkComponentsCompatible<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n expectedFamilyId: TFamilyId,\n expectedTargetId: TTargetId,\n frameworkComponents: ReadonlyArray<unknown>,\n): ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>> {\n for (let i = 0; i < frameworkComponents.length; i++) {\n const component = frameworkComponents[i];\n\n // Check that component is an object\n if (typeof component !== 'object' || component === null) {\n throw errorConfigValidation('frameworkComponents[]', {\n why: `Framework component at index ${i} must be an object`,\n });\n }\n\n const record = component as Record<string, unknown>;\n\n // Check kind\n if (!Object.hasOwn(record, 'kind')) {\n throw errorConfigValidation('frameworkComponents[].kind', {\n why: `Framework component at index ${i} must have 'kind' property`,\n });\n }\n\n const kind = record['kind'];\n if (kind !== 'target' && kind !== 'adapter' && kind !== 'extension' && kind !== 'driver') {\n throw errorConfigValidation('frameworkComponents[].kind', {\n why: `Framework component at index ${i} has invalid kind '${String(kind)}' (must be 'target', 'adapter', 'extension', or 'driver')`,\n });\n }\n\n // Check familyId\n if (!Object.hasOwn(record, 'familyId')) {\n throw errorConfigValidation('frameworkComponents[].familyId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'familyId' property`,\n });\n }\n\n const familyId = record['familyId'];\n if (familyId !== expectedFamilyId) {\n throw errorConfigValidation('frameworkComponents[].familyId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) has familyId '${String(familyId)}' but expected '${expectedFamilyId}'`,\n });\n }\n\n // Check targetId\n if (!Object.hasOwn(record, 'targetId')) {\n throw errorConfigValidation('frameworkComponents[].targetId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'targetId' property`,\n });\n }\n\n const targetId = record['targetId'];\n if (targetId !== expectedTargetId) {\n throw errorConfigValidation('frameworkComponents[].targetId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) has targetId '${String(targetId)}' but expected '${expectedTargetId}'`,\n });\n }\n }\n\n // Type assertion is safe because we've validated all components above\n return frameworkComponents as ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n}\n\n/**\n * Validates that a contract is compatible with the configured target, adapter,\n * and extension packs. Throws on family/target mismatches or missing extension packs.\n *\n * This check ensures the emitted contract matches the CLI config before running\n * commands that depend on the contract (e.g., db verify, db sign).\n *\n * @param contract - The contract to validate (must include targetFamily, target, extensionPacks).\n * @param stack - The control plane stack (target, adapter, driver, extensionPacks).\n *\n * @throws {CliStructuredError} errorConfigValidation when contract.targetFamily or contract.target\n * doesn't match the configured family/target.\n * @throws {CliStructuredError} errorContractMissingExtensionPacks when the contract requires\n * extension packs that are not provided in the config (includes all missing packs in error.meta).\n *\n * @example\n * ```ts\n * import { assertContractRequirementsSatisfied } from './framework-components';\n *\n * const config = await loadConfig();\n * const contract = await loadContractJson(config.contract.output);\n * const stack = createControlStack({ family: config.family, target: config.target, adapter: config.adapter, ... });\n *\n * // Throws if contract is incompatible with config\n * assertContractRequirementsSatisfied({ contract, stack });\n * ```\n */\nexport function assertContractRequirementsSatisfied<\n TFamilyId extends string,\n TTargetId extends string,\n>({\n contract,\n stack,\n}: {\n readonly contract: Pick<Contract, 'targetFamily' | 'target' | 'extensionPacks'>;\n readonly stack: ControlStack<TFamilyId, TTargetId>;\n}): void {\n const providedComponentIds = new Set<string>([\n stack.target.id,\n ...(stack.adapter ? [stack.adapter.id] : []),\n ]);\n for (const extension of stack.extensionPacks) {\n providedComponentIds.add(extension.id);\n }\n\n const result = checkContractComponentRequirements({\n contract,\n expectedTargetFamily: stack.target.familyId,\n expectedTargetId: stack.target.targetId,\n providedComponentIds,\n });\n\n if (result.familyMismatch) {\n throw errorConfigValidation('contract.targetFamily', {\n why: `Contract was emitted for family '${result.familyMismatch.actual}' but CLI config is wired to '${result.familyMismatch.expected}'.`,\n });\n }\n\n if (result.targetMismatch) {\n throw errorConfigValidation('contract.target', {\n why: `Contract target '${result.targetMismatch.actual}' does not match CLI target '${result.targetMismatch.expected}'.`,\n });\n }\n\n if (result.missingExtensionPackIds.length > 0) {\n throw errorContractMissingExtensionPacks({\n missingExtensionPacks: result.missingExtensionPackIds,\n providedComponentIds: [...providedComponentIds],\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAgB,oCAId,kBACA,kBACA,qBACqE;CACrE,KAAK,IAAI,IAAI,GAAG,IAAI,oBAAoB,QAAQ,KAAK;EACnD,MAAM,YAAY,oBAAoB;EAGtC,IAAI,OAAO,cAAc,YAAY,cAAc,MACjD,MAAM,sBAAsB,yBAAyB,EACnD,KAAK,gCAAgC,EAAE,oBACzC,CAAC;EAGH,MAAM,SAAS;EAGf,IAAI,CAAC,OAAO,OAAO,QAAQ,MAAM,GAC/B,MAAM,sBAAsB,8BAA8B,EACxD,KAAK,gCAAgC,EAAE,4BACzC,CAAC;EAGH,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,YAAY,SAAS,aAAa,SAAS,eAAe,SAAS,UAC9E,MAAM,sBAAsB,8BAA8B,EACxD,KAAK,gCAAgC,EAAE,qBAAqB,OAAO,IAAI,EAAE,2DAC3E,CAAC;EAIH,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,GACnC,MAAM,sBAAsB,kCAAkC,EAC5D,KAAK,gCAAgC,EAAE,UAAU,OAAO,IAAI,EAAE,iCAChE,CAAC;EAGH,MAAM,WAAW,OAAO;EACxB,IAAI,aAAa,kBACf,MAAM,sBAAsB,kCAAkC,EAC5D,KAAK,gCAAgC,EAAE,UAAU,OAAO,IAAI,EAAE,kBAAkB,OAAO,QAAQ,EAAE,kBAAkB,iBAAiB,GACtI,CAAC;EAIH,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,GACnC,MAAM,sBAAsB,kCAAkC,EAC5D,KAAK,gCAAgC,EAAE,UAAU,OAAO,IAAI,EAAE,iCAChE,CAAC;EAGH,MAAM,WAAW,OAAO;EACxB,IAAI,aAAa,kBACf,MAAM,sBAAsB,kCAAkC,EAC5D,KAAK,gCAAgC,EAAE,UAAU,OAAO,IAAI,EAAE,kBAAkB,OAAO,QAAQ,EAAE,kBAAkB,iBAAiB,GACtI,CAAC;CAEL;CAGA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-flags-
|
|
1
|
+
{"version":3,"file":"global-flags-Bo6nCRUS.d.mts","names":[],"sources":["../src/utils/global-flags.ts"],"mappings":";KAMY,YAAA;AAAA,UAEK,WAAA;EAAA,SACN,MAAA,EAAQ,YAAY;EAAA,SACpB,cAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA;EAAA,SACA,WAAA;EAAA,SACA,GAAA;AAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glyph-mode-VIjULGFF.d.mts","names":[],"sources":["../src/utils/glyph-mode.ts"],"mappings":";KAAY,SAAA"}
|
|
@@ -1078,4 +1078,4 @@ function isLinearGraph(graph) {
|
|
|
1078
1078
|
//#endregion
|
|
1079
1079
|
export { migrationGraphToRenderInput as i, graphRenderer as n, isLinearGraph as r, extractRelevantSubgraph as t };
|
|
1080
1080
|
|
|
1081
|
-
//# sourceMappingURL=graph-render-
|
|
1081
|
+
//# sourceMappingURL=graph-render-eJDcLWny.mjs.map
|