@prisma-next/cli 0.14.0-dev.5 → 0.14.0-dev.51

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.
Files changed (112) hide show
  1. package/dist/cli.mjs +14 -14
  2. package/dist/cli.mjs.map +1 -1
  3. package/dist/{client-EnAjSmZg.mjs → client-DL6KE_c0.mjs} +88 -99
  4. package/dist/client-DL6KE_c0.mjs.map +1 -0
  5. package/dist/{command-helpers-6cNJZ863.mjs → command-helpers-DMG0RsR1.mjs} +3 -3
  6. package/dist/command-helpers-DMG0RsR1.mjs.map +1 -0
  7. package/dist/commands/contract-emit.mjs +1 -1
  8. package/dist/commands/contract-infer.mjs +1 -1
  9. package/dist/commands/db-init.mjs +3 -3
  10. package/dist/commands/db-schema.mjs +3 -3
  11. package/dist/commands/db-sign.mjs +4 -4
  12. package/dist/commands/db-update.mjs +4 -4
  13. package/dist/commands/db-verify.mjs +1 -1
  14. package/dist/commands/migrate.d.mts +1 -1
  15. package/dist/commands/migrate.d.mts.map +1 -1
  16. package/dist/commands/migrate.mjs +35 -35
  17. package/dist/commands/migrate.mjs.map +1 -1
  18. package/dist/commands/migration-check.d.mts +1 -1
  19. package/dist/commands/migration-check.mjs +1 -1
  20. package/dist/commands/migration-graph.d.mts +1 -1
  21. package/dist/commands/migration-graph.mjs +7 -7
  22. package/dist/commands/migration-graph.mjs.map +1 -1
  23. package/dist/commands/migration-list.d.mts +6 -6
  24. package/dist/commands/migration-list.d.mts.map +1 -1
  25. package/dist/commands/migration-list.mjs +1 -1
  26. package/dist/commands/migration-log.d.mts +1 -1
  27. package/dist/commands/migration-log.mjs +1 -1
  28. package/dist/commands/migration-new.mjs +3 -3
  29. package/dist/commands/migration-plan.d.mts.map +1 -1
  30. package/dist/commands/migration-plan.mjs +1 -1
  31. package/dist/commands/migration-show.mjs +3 -3
  32. package/dist/commands/migration-status.d.mts +1 -1
  33. package/dist/commands/migration-status.mjs +1 -1
  34. package/dist/commands/ref.d.mts +1 -1
  35. package/dist/commands/ref.mjs +2 -2
  36. package/dist/commands/telemetry/index.mjs +1 -1
  37. package/dist/{contract-at-errors-DdxWRjMc.mjs → contract-at-errors-bF4CGDl0.mjs} +2 -2
  38. package/dist/{contract-at-errors-DdxWRjMc.mjs.map → contract-at-errors-bF4CGDl0.mjs.map} +1 -1
  39. package/dist/{contract-emit-fz6pDR2n.mjs → contract-emit-BM7oxYIG.mjs} +7 -5
  40. package/dist/{contract-emit-fz6pDR2n.mjs.map → contract-emit-BM7oxYIG.mjs.map} +1 -1
  41. package/dist/{contract-emit-D4xDDFkO.mjs → contract-emit-DnCG2JaQ.mjs} +3 -3
  42. package/dist/{contract-emit-D4xDDFkO.mjs.map → contract-emit-DnCG2JaQ.mjs.map} +1 -1
  43. package/dist/{contract-infer-Ars4yjBv.mjs → contract-infer-Dq9XNQCx.mjs} +3 -3
  44. package/dist/{contract-infer-Ars4yjBv.mjs.map → contract-infer-Dq9XNQCx.mjs.map} +1 -1
  45. package/dist/{contract-space-aggregate-loader-Bu2fjSWV.mjs → contract-space-aggregate-loader-DAa8u6bi.mjs} +2 -2
  46. package/dist/{contract-space-aggregate-loader-Bu2fjSWV.mjs.map → contract-space-aggregate-loader-DAa8u6bi.mjs.map} +1 -1
  47. package/dist/{db-verify-CZxRV_er.mjs → db-verify-BpfJvC8O.mjs} +56 -60
  48. package/dist/db-verify-BpfJvC8O.mjs.map +1 -0
  49. package/dist/exports/control-api.d.mts +3 -3
  50. package/dist/exports/control-api.mjs +2 -2
  51. package/dist/exports/index.mjs +2 -2
  52. package/dist/extension-pack-inputs-1ySHqxKG.mjs.map +1 -1
  53. package/dist/{format-C3XdaDuA.mjs → format-DrUSkdqR.mjs} +2 -2
  54. package/dist/{format-C3XdaDuA.mjs.map → format-DrUSkdqR.mjs.map} +1 -1
  55. package/dist/{framework-components-5RljWT7Q.mjs → framework-components-BdmVlRSS.mjs} +2 -2
  56. package/dist/{framework-components-5RljWT7Q.mjs.map → framework-components-BdmVlRSS.mjs.map} +1 -1
  57. package/dist/{init-C79Yb97u.mjs → init-C0YyVoGj.mjs} +3 -3
  58. package/dist/{init-C79Yb97u.mjs.map → init-C0YyVoGj.mjs.map} +1 -1
  59. package/dist/{inspect-live-schema-DR8Eyt29.mjs → inspect-live-schema-Bs_0M6z8.mjs} +3 -3
  60. package/dist/{inspect-live-schema-DR8Eyt29.mjs.map → inspect-live-schema-Bs_0M6z8.mjs.map} +1 -1
  61. package/dist/{migration-check-CTcJfCC4.mjs → migration-check-DYxrNfK-.mjs} +9 -9
  62. package/dist/migration-check-DYxrNfK-.mjs.map +1 -0
  63. package/dist/{migration-command-scaffold-6OT_Q-3Y.mjs → migration-command-scaffold-DB5DQLvF.mjs} +3 -3
  64. package/dist/{migration-command-scaffold-6OT_Q-3Y.mjs.map → migration-command-scaffold-DB5DQLvF.mjs.map} +1 -1
  65. package/dist/{migration-list-DVHVmMrf.mjs → migration-list-BX5w9HAn.mjs} +14 -14
  66. package/dist/migration-list-BX5w9HAn.mjs.map +1 -0
  67. package/dist/{migration-log-CQpc9JoL.mjs → migration-log-CB1KzVOG.mjs} +3 -3
  68. package/dist/{migration-log-CQpc9JoL.mjs.map → migration-log-CB1KzVOG.mjs.map} +1 -1
  69. package/dist/{migration-path-target-zK6RG6JY.mjs → migration-path-target-CEFRK2Q7.mjs} +2 -2
  70. package/dist/{migration-path-target-zK6RG6JY.mjs.map → migration-path-target-CEFRK2Q7.mjs.map} +1 -1
  71. package/dist/{migration-plan-o2aqjnfd.mjs → migration-plan-DMKl_HnV.mjs} +29 -28
  72. package/dist/migration-plan-DMKl_HnV.mjs.map +1 -0
  73. package/dist/{migration-status-2aXGtYMW.mjs → migration-status-BeNAmEju.mjs} +12 -12
  74. package/dist/migration-status-BeNAmEju.mjs.map +1 -0
  75. package/dist/{telemetry-BckOSUWG.mjs → telemetry-_19qtfXp.mjs} +2 -2
  76. package/dist/{telemetry-BckOSUWG.mjs.map → telemetry-_19qtfXp.mjs.map} +1 -1
  77. package/dist/{types-qETCCNbe.d.mts → types-DFoqNIcQ.d.mts} +26 -20
  78. package/dist/types-DFoqNIcQ.d.mts.map +1 -0
  79. package/dist/{verify-DLqhL2LU.mjs → verify-Djo-Jep_.mjs} +57 -159
  80. package/dist/verify-Djo-Jep_.mjs.map +1 -0
  81. package/package.json +21 -21
  82. package/src/commands/db-verify.ts +31 -19
  83. package/src/commands/lsp.ts +3 -1
  84. package/src/commands/migrate.ts +46 -43
  85. package/src/commands/migration-check.ts +5 -5
  86. package/src/commands/migration-graph.ts +4 -4
  87. package/src/commands/migration-list.ts +12 -12
  88. package/src/commands/migration-plan.ts +14 -3
  89. package/src/commands/migration-status.ts +9 -9
  90. package/src/control-api/client.ts +5 -3
  91. package/src/control-api/operations/contract-emit.ts +7 -6
  92. package/src/control-api/operations/db-init.ts +2 -2
  93. package/src/control-api/operations/db-run.ts +18 -17
  94. package/src/control-api/operations/db-verify.ts +52 -44
  95. package/src/control-api/operations/migrate.ts +72 -72
  96. package/src/control-api/operations/run-migration.ts +6 -5
  97. package/src/control-api/types.ts +8 -8
  98. package/src/utils/combine-verify-results.ts +94 -0
  99. package/src/utils/extension-pack-inputs.ts +1 -1
  100. package/src/utils/formatters/errors.ts +12 -4
  101. package/src/utils/formatters/verify.ts +88 -227
  102. package/src/utils/plan-resolution.ts +18 -18
  103. package/dist/client-EnAjSmZg.mjs.map +0 -1
  104. package/dist/command-helpers-6cNJZ863.mjs.map +0 -1
  105. package/dist/db-verify-CZxRV_er.mjs.map +0 -1
  106. package/dist/migration-check-CTcJfCC4.mjs.map +0 -1
  107. package/dist/migration-list-DVHVmMrf.mjs.map +0 -1
  108. package/dist/migration-plan-o2aqjnfd.mjs.map +0 -1
  109. package/dist/migration-status-2aXGtYMW.mjs.map +0 -1
  110. package/dist/types-qETCCNbe.d.mts.map +0 -1
  111. package/dist/verify-DLqhL2LU.mjs.map +0 -1
  112. package/src/utils/combine-schema-results.ts +0 -84
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-verify-BpfJvC8O.mjs","names":[],"sources":["../src/utils/combine-verify-results.ts","../src/commands/db-verify.ts"],"sourcesContent":["import type { VerifyDatabaseSchemaResult } from '@prisma-next/framework-components/control';\n\n/**\n * The combined per-space contract-satisfaction result plus the standalone\n * unclaimed-elements list, reported once. The CLI renders\n * both; `unclaimed` is never folded into the combined tree or its issues.\n */\nexport interface CombinedVerifyResult {\n readonly result: VerifyDatabaseSchemaResult;\n readonly unclaimed: readonly string[];\n}\n\n/**\n * Collapse the aggregate verifier's per-space contract-satisfaction results\n * into a single {@link VerifyDatabaseSchemaResult} for the CLI display\n * surface, and carry the deduplicated unclaimed-elements list alongside it.\n * Concatenates the issue lists across spaces; uses the app space's result as\n * the structural envelope (storage hash, target). Extras are already\n * stripped from each per-space result, so nothing here duplicates an\n * unclaimed element per space.\n *\n * **Unclaimed disposition.** In strict mode a non-empty `unclaimed` list fails\n * the combined verdict (`ok: false`); in lenient mode it is carried for\n * informational rendering only. The list itself is returned unchanged for the\n * renderer.\n *\n * **Summary policy.** Preserve the per-family phrasing whenever the\n * combined `ok` flag agrees with the app space'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 space's summary. This keeps family phrasing\n * intact and the envelope internally consistent (`ok: false` ↔ failure\n * summary).\n */\nexport function combineVerifyResults(\n perSpace: ReadonlyMap<string, VerifyDatabaseSchemaResult>,\n appSpaceId: string,\n strict: boolean,\n unclaimed: readonly string[],\n): CombinedVerifyResult {\n const appResult = perSpace.get(appSpaceId) ?? perSpace.values().next().value;\n if (appResult === undefined) {\n throw new Error(\n 'Aggregate verifier returned no per-space verify results — this is a wiring bug.',\n );\n }\n\n let okAll = true;\n let firstFailure: VerifyDatabaseSchemaResult | undefined;\n let issues: VerifyDatabaseSchemaResult['schema']['issues'] = [];\n let warningIssues: VerifyDatabaseSchemaResult['schema']['issues'] = [];\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 warningIssues = [...warningIssues, ...(result.schema.warnings?.issues ?? [])];\n }\n\n const unclaimedFails = strict && unclaimed.length > 0;\n const ok = okAll && !unclaimedFails;\n\n // Prefer a failing space's family phrasing; else, when only the unclaimed list\n // fails the verdict, say so; else keep the app space's phrasing. When `okAll`\n // is false the loop assigned `firstFailure`, so the `?? appResult.summary`\n // fallback is unreachable — it exists only to keep the read cast-free.\n const summary = okAll\n ? unclaimedFails\n ? `Database schema has ${unclaimed.length} unclaimed element${unclaimed.length === 1 ? '' : 's'} (not in any contract)`\n : appResult.summary\n : appResult.ok\n ? (firstFailure?.summary ?? appResult.summary)\n : appResult.summary;\n\n return {\n result: {\n ok,\n ...(ok ? {} : { code: appResult.code ?? 'PN-RUN-3010' }),\n summary,\n contract: appResult.contract,\n target: appResult.target,\n schema: {\n issues,\n warnings: { issues: warningIssues },\n },\n meta: { strict },\n timings: { total: 0 },\n },\n unclaimed,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { loadConfig } from '@prisma-next/config-loader';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { VerifyDatabaseResult } 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 { 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 { type CombinedVerifyResult, combineVerifyResults } from '../utils/combine-verify-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 | CombinedVerifyResult;\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 = combineVerifyResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n aggregateResult.value.unclaimed,\n );\n if (!combined.result.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.result.summary,\n strict: combined.result.meta?.strict ?? false,\n warnings: (combined.result.schema.warnings?.issues ?? []).map((issue) => issue.message),\n },\n unclaimed: combined.unclaimed,\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<CombinedVerifyResult, 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 combineVerifyResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n aggregateResult.value.unclaimed,\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, (combined) => {\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(combined.result, combined.unclaimed));\n } else {\n // Always show schema-drift failures, even in quiet mode — exiting 1\n // without diagnostics is unhelpful (same policy as the full-mode\n // failure branch below).\n const renderFlags = combined.result.ok ? flags : { ...flags, quiet: false };\n const output = formatSchemaVerifyOutput(\n combined.result,\n renderFlags,\n combined.unclaimed,\n );\n if (output) {\n ui.log(output);\n }\n }\n });\n\n if (result.ok && !result.value.result.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.result, result.failure.unclaimed));\n } else {\n // Always show schema-drift failures, even in quiet mode — exiting 1 without\n // diagnostics is unhelpful.\n const output = formatSchemaVerifyOutput(\n result.failure.result,\n { ...flags, quiet: false },\n result.failure.unclaimed,\n );\n if (output) {\n ui.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { A as ExecuteDbVerifyOptions, C as IntrospectOptions, D as SchemaVerifyOptions, M as executeDbVerify, O as SignOptions, S as EmitSuccess, T as OnControlProgress, _ as EmitContractConfig, a as ControlClientOptions, b as EmitOptions, c as DbInitFailureCode, d as DbInitSuccess, f as DbUpdateFailure, g as DbUpdateSuccess, h as DbUpdateResult, i as ControlClient, j as ExecuteDbVerifyResult, k as VerifyOptions, l as DbInitOptions, m as DbUpdateOptions, n as ContractEmitResult, o as ControlProgressEvent, p as DbUpdateFailureCode, r as ControlActionName, s as DbInitFailure, t as ContractEmitOptions, u as DbInitResult, v as EmitFailure, x as EmitResult, y as EmitFailureCode } from "../types-qETCCNbe.mjs";
1
+ import { A as ExecuteDbVerifyOptions, C as IntrospectOptions, D as SchemaVerifyOptions, M as executeDbVerify, O as SignOptions, S as EmitSuccess, T as OnControlProgress, _ as EmitContractConfig, a as ControlClientOptions, b as EmitOptions, c as DbInitFailureCode, d as DbInitSuccess, f as DbUpdateFailure, g as DbUpdateSuccess, h as DbUpdateResult, i as ControlClient, j as ExecuteDbVerifyResult, k as VerifyOptions, l as DbInitOptions, m as DbUpdateOptions, n as ContractEmitResult, o as ControlProgressEvent, p as DbUpdateFailureCode, r as ControlActionName, s as DbInitFailure, t as ContractEmitOptions, u as DbInitResult, v as EmitFailure, x as EmitResult, y as EmitFailureCode } from "../types-DFoqNIcQ.mjs";
2
2
  import { ControlAdapterInstance, 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";
@@ -55,7 +55,7 @@ declare function executeContractEmit(options: ContractEmitOptions): Promise<Cont
55
55
  * {@link import('@prisma-next/migration-tools/aggregate').loadContractSpaceAggregate}
56
56
  * from the supplied descriptor set + on-disk on-disk artefacts.
57
57
  * 2. The aggregate planner runs with `callerPolicy.ignoreGraphFor`
58
- * locked to the app member — synth strategy for the app, graph-walk
58
+ * locked to the app space — synth strategy for the app, graph-walk
59
59
  * for every extension.
60
60
  * 3. The runner's `execute` applies the per-space plans
61
61
  * inside one outer transaction.
@@ -84,7 +84,7 @@ interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extends strin
84
84
  /**
85
85
  * Declared extension descriptors. Defaults to an empty list, which
86
86
  * routes through the same loader → planner → runner pipeline with no
87
- * extension members in the aggregate.
87
+ * extension spaces in the aggregate.
88
88
  */
89
89
  readonly extensionPacks?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
90
90
  /** Optional progress callback for observing operation progress */
@@ -1,4 +1,4 @@
1
- import { n as executeContractEmit, r as disposeEmitQueue } from "../contract-emit-fz6pDR2n.mjs";
1
+ import { n as executeContractEmit, r as disposeEmitQueue } from "../contract-emit-BM7oxYIG.mjs";
2
2
  import { t as enrichContract } from "../contract-enrichment-gn9sWbPw.mjs";
3
- import { a as executeDbInit, i as executeDbUpdate, r as executeDbVerify, t as createControlClient } from "../client-EnAjSmZg.mjs";
3
+ import { a as executeDbInit, i as executeDbUpdate, r as executeDbVerify, t as createControlClient } from "../client-DL6KE_c0.mjs";
4
4
  export { createControlClient, disposeEmitQueue, enrichContract, executeContractEmit, executeDbInit, executeDbUpdate, executeDbVerify };
@@ -1,5 +1,5 @@
1
- import { t as createContractEmitCommand } from "../contract-emit-D4xDDFkO.mjs";
2
- import { t as createFormatCommand } from "../format-C3XdaDuA.mjs";
1
+ import { t as createContractEmitCommand } from "../contract-emit-DnCG2JaQ.mjs";
2
+ import { t as createFormatCommand } from "../format-DrUSkdqR.mjs";
3
3
  import { join, resolve } from "pathe";
4
4
  import { existsSync, unlinkSync, writeFileSync } from "node:fs";
5
5
  import { tmpdir } from "node:os";
@@ -1 +1 @@
1
- {"version":3,"file":"extension-pack-inputs-1ySHqxKG.mjs","names":[],"sources":["../src/utils/extension-pack-inputs.ts"],"sourcesContent":["/**\n * Single descriptor-import boundary for CLI consumers of `Config.extensionPacks`.\n *\n * Every CLI command / utility that reads an extension descriptor's\n * `contractSpace` projection (loader, migrate-pass, extension-migrations\n * pass, migration commands) goes through {@link toExtensionInputs}. The\n * structural cast `pack as { contractSpace?: ... }` lives **only** here —\n * downstream code consumes the canonical shape and maps it to its own\n * narrower shape via the per-consumer adapters below.\n *\n * The CLI receives extension descriptors typed against the SQL family\n * (or any other family in the future); this helper only depends on the\n * structural shape of `contractSpace`. SQL-family callers pass the same\n * `contractJson` / `headRef.hash` value through unchanged.\n */\nimport type { DeclaredExtensionEntry } from '@prisma-next/migration-tools/aggregate';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport type { MigrationOps } from '@prisma-next/migration-tools/package';\n\n/**\n * In-memory authored migration package shipped by an extension descriptor.\n * Mirrors the `MigrationPackage` shape from\n * `@prisma-next/framework-components/control` minus `dirPath`; redeclared\n * structurally here so the helper does not couple to the SQL family's\n * `ExtensionMigrationPackage` type.\n */\nexport interface DescriptorMigrationPackage {\n readonly dirName: string;\n readonly metadata: MigrationMetadata;\n readonly ops: MigrationOps;\n}\n\n/**\n * The most-general projection of a single declared extension pack\n * needed by the CLI's descriptor-import boundary.\n *\n * - `id` / `targetId` are always present.\n * - `contractSpace` is present only when the extension declares one.\n * When present, it carries the canonical inputs every downstream\n * consumer needs — `contractJson`, `headRef`, and the descriptor's\n * pre-built migration packages.\n */\nexport interface ExtensionPackInput {\n readonly id: string;\n readonly targetId: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: {\n readonly hash: string;\n readonly invariants: readonly string[];\n };\n readonly migrations: readonly DescriptorMigrationPackage[];\n };\n}\n\n/**\n * Structural shape we read off each `Config.extensionPacks` entry.\n *\n * The CLI is the descriptor-import boundary; `extensionPacks` is the only\n * surface where the SQL-family-typed `ControlExtensionDescriptor` flows\n * into framework-neutral helpers. The structural cast lives here, and\n * here alone — every other CLI consumer reads the canonical\n * {@link ExtensionPackInput} shape produced by {@link toExtensionInputs}.\n */\ntype ExtensionPackLike = {\n readonly id: string;\n readonly targetId: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: {\n readonly hash: string;\n readonly invariants: readonly string[];\n };\n readonly migrations?: readonly DescriptorMigrationPackage[];\n };\n};\n\n/**\n * Project the CLI's `Config.extensionPacks` array into the canonical\n * {@link ExtensionPackInput} shape. The single `as ExtensionPackLike`\n * structural cast in the CLI lives inside this function.\n */\nexport function toExtensionInputs(\n extensionPacks: ReadonlyArray<unknown>,\n): readonly ExtensionPackInput[] {\n return extensionPacks.map((raw) => {\n const pack = raw as ExtensionPackLike;\n if (pack.contractSpace === undefined) {\n return { id: pack.id, targetId: pack.targetId };\n }\n return {\n id: pack.id,\n targetId: pack.targetId,\n contractSpace: {\n contractJson: pack.contractSpace.contractJson,\n headRef: pack.contractSpace.headRef,\n migrations: pack.contractSpace.migrations ?? [],\n },\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Per-consumer adapters: take the canonical `ExtensionPackInput[]` and\n// project to whatever narrower shape the downstream primitive needs.\n// ---------------------------------------------------------------------------\n\n/**\n * Aggregate-loader projection. Surfaces `id` + `targetId` per\n * contract-space-bearing extension to\n * {@link import('./contract-space-aggregate-loader').buildContractSpaceAggregate}.\n *\n * Codec-only extensions (no `contractSpace` declaration) are filtered\n * out: they are not contract-space members, so the aggregate loader\n * has nothing to do with them. Filtering happens at this descriptor-\n * import boundary so the loader stays oblivious to that distinction —\n * every entry it sees expects an on-disk `migrations/<id>/` directory.\n */\nexport function toDeclaredExtensions(\n inputs: ReadonlyArray<ExtensionPackInput>,\n): readonly DeclaredExtensionEntry[] {\n const entries: DeclaredExtensionEntry[] = [];\n for (const pack of inputs) {\n if (pack.contractSpace === undefined) continue;\n entries.push({ id: pack.id, targetId: pack.targetId });\n }\n return entries;\n}\n\n/**\n * Minimal aggregate-loader projection that extracts `id` + `targetId`\n * from raw extension pack descriptors **without invoking any\n * `contractSpace` accessor**. Inspects the own-property descriptor so\n * that getter-backed `contractSpace` declarations are detected but\n * never called.\n *\n * Inclusion semantics match {@link toDeclaredExtensions}: a data\n * property whose value is explicitly `undefined` is treated as \"no\n * contract-space declaration\" and skipped, mirroring the\n * `pack.contractSpace === undefined` check used on canonicalised\n * inputs. Prototype-chain `contractSpace` properties (no own\n * descriptor) are also skipped.\n *\n * This variant must be used by `buildContractSpaceAggregate` so that\n * the aggregate path (including `db verify`) never reads\n * `contractSpace.contractJson` from extension descriptors — the loader\n * always reads the contract from on-disk artefacts instead.\n */\nexport function toDeclaredExtensionsFromRaw(\n extensionPacks: ReadonlyArray<unknown>,\n): readonly DeclaredExtensionEntry[] {\n const entries: DeclaredExtensionEntry[] = [];\n for (const raw of extensionPacks) {\n if (typeof raw !== 'object' || raw === null) continue;\n const descriptor = Object.getOwnPropertyDescriptor(raw, 'contractSpace');\n if (descriptor === undefined) continue;\n if ('value' in descriptor && descriptor.value === undefined) continue;\n const pack = raw as { readonly id: string; readonly targetId: string };\n entries.push({ id: pack.id, targetId: pack.targetId });\n }\n return entries;\n}\n"],"mappings":";;;;;;AAkFA,SAAgB,kBACd,gBAC+B;CAC/B,OAAO,eAAe,KAAK,QAAQ;EACjC,MAAM,OAAO;EACb,IAAI,KAAK,kBAAkB,KAAA,GACzB,OAAO;GAAE,IAAI,KAAK;GAAI,UAAU,KAAK;EAAS;EAEhD,OAAO;GACL,IAAI,KAAK;GACT,UAAU,KAAK;GACf,eAAe;IACb,cAAc,KAAK,cAAc;IACjC,SAAS,KAAK,cAAc;IAC5B,YAAY,KAAK,cAAc,cAAc,CAAC;GAChD;EACF;CACF,CAAC;AACH;;;;;;;;;;;;;;;;;;;;AAgDA,SAAgB,4BACd,gBACmC;CACnC,MAAM,UAAoC,CAAC;CAC3C,KAAK,MAAM,OAAO,gBAAgB;EAChC,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;EAC7C,MAAM,aAAa,OAAO,yBAAyB,KAAK,eAAe;EACvE,IAAI,eAAe,KAAA,GAAW;EAC9B,IAAI,WAAW,cAAc,WAAW,UAAU,KAAA,GAAW;EAC7D,MAAM,OAAO;EACb,QAAQ,KAAK;GAAE,IAAI,KAAK;GAAI,UAAU,KAAK;EAAS,CAAC;CACvD;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"extension-pack-inputs-1ySHqxKG.mjs","names":[],"sources":["../src/utils/extension-pack-inputs.ts"],"sourcesContent":["/**\n * Single descriptor-import boundary for CLI consumers of `Config.extensionPacks`.\n *\n * Every CLI command / utility that reads an extension descriptor's\n * `contractSpace` projection (loader, migrate-pass, extension-migrations\n * pass, migration commands) goes through {@link toExtensionInputs}. The\n * structural cast `pack as { contractSpace?: ... }` lives **only** here —\n * downstream code consumes the canonical shape and maps it to its own\n * narrower shape via the per-consumer adapters below.\n *\n * The CLI receives extension descriptors typed against the SQL family\n * (or any other family in the future); this helper only depends on the\n * structural shape of `contractSpace`. SQL-family callers pass the same\n * `contractJson` / `headRef.hash` value through unchanged.\n */\nimport type { DeclaredExtensionEntry } from '@prisma-next/migration-tools/aggregate';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport type { MigrationOps } from '@prisma-next/migration-tools/package';\n\n/**\n * In-memory authored migration package shipped by an extension descriptor.\n * Mirrors the `MigrationPackage` shape from\n * `@prisma-next/framework-components/control` minus `dirPath`; redeclared\n * structurally here so the helper does not couple to the SQL family's\n * `ExtensionMigrationPackage` type.\n */\nexport interface DescriptorMigrationPackage {\n readonly dirName: string;\n readonly metadata: MigrationMetadata;\n readonly ops: MigrationOps;\n}\n\n/**\n * The most-general projection of a single declared extension pack\n * needed by the CLI's descriptor-import boundary.\n *\n * - `id` / `targetId` are always present.\n * - `contractSpace` is present only when the extension declares one.\n * When present, it carries the canonical inputs every downstream\n * consumer needs — `contractJson`, `headRef`, and the descriptor's\n * pre-built migration packages.\n */\nexport interface ExtensionPackInput {\n readonly id: string;\n readonly targetId: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: {\n readonly hash: string;\n readonly invariants: readonly string[];\n };\n readonly migrations: readonly DescriptorMigrationPackage[];\n };\n}\n\n/**\n * Structural shape we read off each `Config.extensionPacks` entry.\n *\n * The CLI is the descriptor-import boundary; `extensionPacks` is the only\n * surface where the SQL-family-typed `ControlExtensionDescriptor` flows\n * into framework-neutral helpers. The structural cast lives here, and\n * here alone — every other CLI consumer reads the canonical\n * {@link ExtensionPackInput} shape produced by {@link toExtensionInputs}.\n */\ntype ExtensionPackLike = {\n readonly id: string;\n readonly targetId: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: {\n readonly hash: string;\n readonly invariants: readonly string[];\n };\n readonly migrations?: readonly DescriptorMigrationPackage[];\n };\n};\n\n/**\n * Project the CLI's `Config.extensionPacks` array into the canonical\n * {@link ExtensionPackInput} shape. The single `as ExtensionPackLike`\n * structural cast in the CLI lives inside this function.\n */\nexport function toExtensionInputs(\n extensionPacks: ReadonlyArray<unknown>,\n): readonly ExtensionPackInput[] {\n return extensionPacks.map((raw) => {\n const pack = raw as ExtensionPackLike;\n if (pack.contractSpace === undefined) {\n return { id: pack.id, targetId: pack.targetId };\n }\n return {\n id: pack.id,\n targetId: pack.targetId,\n contractSpace: {\n contractJson: pack.contractSpace.contractJson,\n headRef: pack.contractSpace.headRef,\n migrations: pack.contractSpace.migrations ?? [],\n },\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Per-consumer adapters: take the canonical `ExtensionPackInput[]` and\n// project to whatever narrower shape the downstream primitive needs.\n// ---------------------------------------------------------------------------\n\n/**\n * Aggregate-loader projection. Surfaces `id` + `targetId` per\n * contract-space-bearing extension to\n * {@link import('./contract-space-aggregate-loader').buildContractSpaceAggregate}.\n *\n * Codec-only extensions (no `contractSpace` declaration) are filtered\n * out: they contribute no contract space, so the aggregate loader\n * has nothing to do with them. Filtering happens at this descriptor-\n * import boundary so the loader stays oblivious to that distinction —\n * every entry it sees expects an on-disk `migrations/<id>/` directory.\n */\nexport function toDeclaredExtensions(\n inputs: ReadonlyArray<ExtensionPackInput>,\n): readonly DeclaredExtensionEntry[] {\n const entries: DeclaredExtensionEntry[] = [];\n for (const pack of inputs) {\n if (pack.contractSpace === undefined) continue;\n entries.push({ id: pack.id, targetId: pack.targetId });\n }\n return entries;\n}\n\n/**\n * Minimal aggregate-loader projection that extracts `id` + `targetId`\n * from raw extension pack descriptors **without invoking any\n * `contractSpace` accessor**. Inspects the own-property descriptor so\n * that getter-backed `contractSpace` declarations are detected but\n * never called.\n *\n * Inclusion semantics match {@link toDeclaredExtensions}: a data\n * property whose value is explicitly `undefined` is treated as \"no\n * contract-space declaration\" and skipped, mirroring the\n * `pack.contractSpace === undefined` check used on canonicalised\n * inputs. Prototype-chain `contractSpace` properties (no own\n * descriptor) are also skipped.\n *\n * This variant must be used by `buildContractSpaceAggregate` so that\n * the aggregate path (including `db verify`) never reads\n * `contractSpace.contractJson` from extension descriptors — the loader\n * always reads the contract from on-disk artefacts instead.\n */\nexport function toDeclaredExtensionsFromRaw(\n extensionPacks: ReadonlyArray<unknown>,\n): readonly DeclaredExtensionEntry[] {\n const entries: DeclaredExtensionEntry[] = [];\n for (const raw of extensionPacks) {\n if (typeof raw !== 'object' || raw === null) continue;\n const descriptor = Object.getOwnPropertyDescriptor(raw, 'contractSpace');\n if (descriptor === undefined) continue;\n if ('value' in descriptor && descriptor.value === undefined) continue;\n const pack = raw as { readonly id: string; readonly targetId: string };\n entries.push({ id: pack.id, targetId: pack.targetId });\n }\n return entries;\n}\n"],"mappings":";;;;;;AAkFA,SAAgB,kBACd,gBAC+B;CAC/B,OAAO,eAAe,KAAK,QAAQ;EACjC,MAAM,OAAO;EACb,IAAI,KAAK,kBAAkB,KAAA,GACzB,OAAO;GAAE,IAAI,KAAK;GAAI,UAAU,KAAK;EAAS;EAEhD,OAAO;GACL,IAAI,KAAK;GACT,UAAU,KAAK;GACf,eAAe;IACb,cAAc,KAAK,cAAc;IACjC,SAAS,KAAK,cAAc;IAC5B,YAAY,KAAK,cAAc,cAAc,CAAC;GAChD;EACF;CACF,CAAC;AACH;;;;;;;;;;;;;;;;;;;;AAgDA,SAAgB,4BACd,gBACmC;CACnC,MAAM,UAAoC,CAAC;CAC3C,KAAK,MAAM,OAAO,gBAAgB;EAChC,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;EAC7C,MAAM,aAAa,OAAO,yBAAyB,KAAK,eAAe;EACvE,IAAI,eAAe,KAAA,GAAW;EAC9B,IAAI,WAAW,cAAc,WAAW,UAAU,KAAA,GAAW;EAC7D,MAAM,OAAO;EACb,QAAQ,KAAK;GAAE,IAAI,KAAK;GAAI,UAAU,KAAK;EAAS,CAAC;CACvD;CACA,OAAO;AACT"}
@@ -1,4 +1,4 @@
1
- import { A as formatStyledHeader, F as CliStructuredError, _ as createTerminalUI, ct as errorUnexpected, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, rt as errorRuntime, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "./command-helpers-6cNJZ863.mjs";
1
+ import { A as formatStyledHeader, F as CliStructuredError, _ as createTerminalUI, ct as errorUnexpected, g as parseGlobalFlagsOrExit, l as setCommandDescriptions, rt as errorRuntime, t as addGlobalOptions, u as setCommandExamples, y as handleResult } from "./command-helpers-DMG0RsR1.mjs";
2
2
  import { Command } from "commander";
3
3
  import { loadConfig } from "@prisma-next/config-loader";
4
4
  import { ifDefined } from "@prisma-next/utils/defined";
@@ -99,4 +99,4 @@ function createFormatCommand() {
99
99
  //#endregion
100
100
  export { createFormatCommand as t };
101
101
 
102
- //# sourceMappingURL=format-C3XdaDuA.mjs.map
102
+ //# sourceMappingURL=format-DrUSkdqR.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-C3XdaDuA.mjs","names":[],"sources":["../src/control-api/operations/format.ts","../src/commands/format.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { EOL } from 'node:os';\nimport { loadConfig } from '@prisma-next/config-loader';\nimport { type FormatOptions, format, PslFormatError } from '@prisma-next/psl-parser/format';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { CliStructuredError, errorRuntime, errorUnexpected } from '../../utils/cli-errors';\n\nexport interface FormatOperationOptions {\n readonly configPath?: string;\n readonly eol?: string;\n}\n\nexport interface FormatOperationResult {\n readonly formatted: boolean;\n readonly path?: string;\n}\n\nexport function resolveNewline(\n formatterNewline: 'LF' | 'CRLF' | undefined,\n eol: string,\n): 'LF' | 'CRLF' {\n if (formatterNewline !== undefined) {\n return formatterNewline;\n }\n return eol === '\\r\\n' ? 'CRLF' : 'LF';\n}\n\nexport async function executeFormat(\n options: FormatOperationOptions,\n): Promise<Result<FormatOperationResult, CliStructuredError>> {\n const eol = options.eol ?? EOL;\n\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(options.configPath);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(errorUnexpected(error instanceof Error ? error.message : String(error)));\n }\n\n const source = config.contract?.source;\n if (source?.sourceFormat !== 'psl') {\n return ok({ formatted: false });\n }\n\n const inputPath = source.inputs?.[0];\n if (inputPath === undefined) {\n return ok({ formatted: false });\n }\n\n let contents: string;\n try {\n contents = await readFile(inputPath, 'utf-8');\n } catch (error) {\n return notOk(\n errorRuntime('Failed to read contract source file', {\n why: error instanceof Error ? error.message : String(error),\n fix: `Check that ${inputPath} exists and is readable.`,\n }),\n );\n }\n\n const formatOptions: FormatOptions = {\n indent: config.formatter?.indent ?? 2,\n newline: resolveNewline(config.formatter?.newline, eol),\n };\n\n let formatted: string;\n try {\n formatted = format(contents, formatOptions);\n } catch (error) {\n if (error instanceof PslFormatError) {\n return notOk(\n errorRuntime('Cannot format PSL with parse errors', {\n why: error.message,\n fix: 'Fix the parse errors in your schema and try again.',\n meta: { diagnostics: error.diagnostics },\n }),\n );\n }\n return notOk(errorUnexpected(error instanceof Error ? error.message : String(error)));\n }\n\n try {\n await writeFile(inputPath, formatted, 'utf-8');\n } catch (error) {\n return notOk(\n errorRuntime('Failed to write formatted contract source file', {\n why: error instanceof Error ? error.message : String(error),\n fix: `Check that ${inputPath} is writable.`,\n }),\n );\n }\n\n return ok({ formatted: true, path: inputPath });\n}\n","import { ifDefined } from '@prisma-next/utils/defined';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { executeFormat } from '../control-api/operations/format';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI } from '../utils/terminal-ui';\n\ninterface FormatCommandOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport function createFormatCommand(): Command {\n const command = new Command('format');\n setCommandDescriptions(\n command,\n 'Format your PSL contract source',\n 'Formats the Prisma schema (PSL) contract source declared in your config\\n' +\n '(contract.source.inputs[0]) in place. Only runs when contract.source.sourceFormat\\n' +\n \"is 'psl'; a TypeScript or unset source is left untouched. Indent and newline are\\n\" +\n 'read from the optional formatter config section, defaulting to two spaces and the\\n' +\n 'system newline.',\n );\n setCommandExamples(command, [\n 'prisma-next format',\n 'prisma-next format --config ./custom-config.ts',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (options: FormatCommandOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n\n if (!flags.json && !flags.quiet) {\n const displayConfigPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n ui.stderr(\n formatStyledHeader({\n command: 'format',\n description: 'Format your PSL contract source',\n details: [{ label: 'config', value: displayConfigPath }],\n flags,\n }),\n );\n }\n\n const result = await executeFormat({ ...ifDefined('configPath', options.config) });\n\n const exitCode = handleResult(result, flags, ui, (value) => {\n if (flags.json) {\n ui.output(JSON.stringify(value));\n return;\n }\n if (flags.quiet) {\n return;\n }\n if (value.formatted) {\n ui.success(`Formatted ${relative(process.cwd(), value.path ?? '')}`);\n } else {\n ui.info('Nothing to format (contract source is not PSL).');\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"format-DrUSkdqR.mjs","names":[],"sources":["../src/control-api/operations/format.ts","../src/commands/format.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { EOL } from 'node:os';\nimport { loadConfig } from '@prisma-next/config-loader';\nimport { type FormatOptions, format, PslFormatError } from '@prisma-next/psl-parser/format';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { CliStructuredError, errorRuntime, errorUnexpected } from '../../utils/cli-errors';\n\nexport interface FormatOperationOptions {\n readonly configPath?: string;\n readonly eol?: string;\n}\n\nexport interface FormatOperationResult {\n readonly formatted: boolean;\n readonly path?: string;\n}\n\nexport function resolveNewline(\n formatterNewline: 'LF' | 'CRLF' | undefined,\n eol: string,\n): 'LF' | 'CRLF' {\n if (formatterNewline !== undefined) {\n return formatterNewline;\n }\n return eol === '\\r\\n' ? 'CRLF' : 'LF';\n}\n\nexport async function executeFormat(\n options: FormatOperationOptions,\n): Promise<Result<FormatOperationResult, CliStructuredError>> {\n const eol = options.eol ?? EOL;\n\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(options.configPath);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(errorUnexpected(error instanceof Error ? error.message : String(error)));\n }\n\n const source = config.contract?.source;\n if (source?.sourceFormat !== 'psl') {\n return ok({ formatted: false });\n }\n\n const inputPath = source.inputs?.[0];\n if (inputPath === undefined) {\n return ok({ formatted: false });\n }\n\n let contents: string;\n try {\n contents = await readFile(inputPath, 'utf-8');\n } catch (error) {\n return notOk(\n errorRuntime('Failed to read contract source file', {\n why: error instanceof Error ? error.message : String(error),\n fix: `Check that ${inputPath} exists and is readable.`,\n }),\n );\n }\n\n const formatOptions: FormatOptions = {\n indent: config.formatter?.indent ?? 2,\n newline: resolveNewline(config.formatter?.newline, eol),\n };\n\n let formatted: string;\n try {\n formatted = format(contents, formatOptions);\n } catch (error) {\n if (error instanceof PslFormatError) {\n return notOk(\n errorRuntime('Cannot format PSL with parse errors', {\n why: error.message,\n fix: 'Fix the parse errors in your schema and try again.',\n meta: { diagnostics: error.diagnostics },\n }),\n );\n }\n return notOk(errorUnexpected(error instanceof Error ? error.message : String(error)));\n }\n\n try {\n await writeFile(inputPath, formatted, 'utf-8');\n } catch (error) {\n return notOk(\n errorRuntime('Failed to write formatted contract source file', {\n why: error instanceof Error ? error.message : String(error),\n fix: `Check that ${inputPath} is writable.`,\n }),\n );\n }\n\n return ok({ formatted: true, path: inputPath });\n}\n","import { ifDefined } from '@prisma-next/utils/defined';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { executeFormat } from '../control-api/operations/format';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI } from '../utils/terminal-ui';\n\ninterface FormatCommandOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport function createFormatCommand(): Command {\n const command = new Command('format');\n setCommandDescriptions(\n command,\n 'Format your PSL contract source',\n 'Formats the Prisma schema (PSL) contract source declared in your config\\n' +\n '(contract.source.inputs[0]) in place. Only runs when contract.source.sourceFormat\\n' +\n \"is 'psl'; a TypeScript or unset source is left untouched. Indent and newline are\\n\" +\n 'read from the optional formatter config section, defaulting to two spaces and the\\n' +\n 'system newline.',\n );\n setCommandExamples(command, [\n 'prisma-next format',\n 'prisma-next format --config ./custom-config.ts',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (options: FormatCommandOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n\n if (!flags.json && !flags.quiet) {\n const displayConfigPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n ui.stderr(\n formatStyledHeader({\n command: 'format',\n description: 'Format your PSL contract source',\n details: [{ label: 'config', value: displayConfigPath }],\n flags,\n }),\n );\n }\n\n const result = await executeFormat({ ...ifDefined('configPath', options.config) });\n\n const exitCode = handleResult(result, flags, ui, (value) => {\n if (flags.json) {\n ui.output(JSON.stringify(value));\n return;\n }\n if (flags.quiet) {\n return;\n }\n if (value.formatted) {\n ui.success(`Formatted ${relative(process.cwd(), value.path ?? '')}`);\n } else {\n ui.info('Nothing to format (contract source is not PSL).');\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { R as errorConfigValidation } from "./command-helpers-6cNJZ863.mjs";
1
+ import { R as errorConfigValidation } from "./command-helpers-DMG0RsR1.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-5RljWT7Q.mjs.map
58
+ //# sourceMappingURL=framework-components-BdmVlRSS.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"framework-components-5RljWT7Q.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
+ {"version":3,"file":"framework-components-BdmVlRSS.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,4 +1,4 @@
1
- import { F as CliStructuredError, _ as createTerminalUI, b as formatErrorJson, x as formatErrorOutput } from "./command-helpers-6cNJZ863.mjs";
1
+ import { F as CliStructuredError, _ as createTerminalUI, b as formatErrorJson, x as formatErrorOutput } from "./command-helpers-DMG0RsR1.mjs";
2
2
  import { a as starterSchema, c as version, i as schemaSample, n as dbFile, o as targetLabel, r as defaultSchemaPath, s as targetPackageName, t as configFile } from "./cli.mjs";
3
3
  import { i as renderInitOutro, n as buildNextSteps, r as formatInitJson, t as InitOutputSchema } from "./output-mEQ74_nd.mjs";
4
4
  import { createRequire } from "node:module";
@@ -2149,7 +2149,7 @@ async function runEmit(ctx) {
2149
2149
  const spinner = ctx.ui.spinner();
2150
2150
  spinner.start("Emitting contract...");
2151
2151
  try {
2152
- const { executeContractEmit } = await import("./contract-emit-fz6pDR2n.mjs").then((n) => n.t);
2152
+ const { executeContractEmit } = await import("./contract-emit-BM7oxYIG.mjs").then((n) => n.t);
2153
2153
  await executeContractEmit({ configPath: join(ctx.baseDir, "prisma-next.config.ts") });
2154
2154
  spinner.stop("Contract emitted");
2155
2155
  } catch (err) {
@@ -2202,4 +2202,4 @@ function sanitisePackageName(raw) {
2202
2202
  //#endregion
2203
2203
  export { runInit };
2204
2204
 
2205
- //# sourceMappingURL=init-C79Yb97u.mjs.map
2205
+ //# sourceMappingURL=init-C0YyVoGj.mjs.map