@prisma-next/cli 0.4.1 → 0.4.3

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 (170) hide show
  1. package/README.md +56 -26
  2. package/dist/agent-skill-mongo.md +63 -31
  3. package/dist/agent-skill-postgres.md +1 -1
  4. package/dist/cli-errors-By1iVE3z.mjs +34 -0
  5. package/dist/cli-errors-By1iVE3z.mjs.map +1 -0
  6. package/dist/cli-errors-DDeVsP2Y.d.mts +5 -0
  7. package/dist/cli.mjs +131 -15
  8. package/dist/cli.mjs.map +1 -1
  9. package/dist/{client-DGKrciLM.mjs → client-1JqqkiC7.mjs} +45 -20
  10. package/dist/client-1JqqkiC7.mjs.map +1 -0
  11. package/dist/commands/contract-emit.d.mts.map +1 -1
  12. package/dist/commands/contract-emit.mjs +7 -2
  13. package/dist/commands/contract-infer.d.mts.map +1 -1
  14. package/dist/commands/contract-infer.mjs +8 -2
  15. package/dist/commands/db-init.d.mts.map +1 -1
  16. package/dist/commands/db-init.mjs +11 -9
  17. package/dist/commands/db-init.mjs.map +1 -1
  18. package/dist/commands/db-schema.mjs +8 -5
  19. package/dist/commands/db-schema.mjs.map +1 -1
  20. package/dist/commands/db-sign.mjs +8 -7
  21. package/dist/commands/db-sign.mjs.map +1 -1
  22. package/dist/commands/db-update.mjs +10 -9
  23. package/dist/commands/db-update.mjs.map +1 -1
  24. package/dist/commands/db-verify.mjs +10 -9
  25. package/dist/commands/db-verify.mjs.map +1 -1
  26. package/dist/commands/migration-apply.d.mts +5 -2
  27. package/dist/commands/migration-apply.d.mts.map +1 -1
  28. package/dist/commands/migration-apply.mjs +57 -57
  29. package/dist/commands/migration-apply.mjs.map +1 -1
  30. package/dist/commands/migration-new.d.mts.map +1 -1
  31. package/dist/commands/migration-new.mjs +26 -32
  32. package/dist/commands/migration-new.mjs.map +1 -1
  33. package/dist/commands/migration-plan.d.mts +14 -5
  34. package/dist/commands/migration-plan.d.mts.map +1 -1
  35. package/dist/commands/migration-plan.mjs +45 -48
  36. package/dist/commands/migration-plan.mjs.map +1 -1
  37. package/dist/commands/migration-ref.d.mts +6 -4
  38. package/dist/commands/migration-ref.d.mts.map +1 -1
  39. package/dist/commands/migration-ref.mjs +31 -40
  40. package/dist/commands/migration-ref.mjs.map +1 -1
  41. package/dist/commands/migration-show.d.mts +13 -7
  42. package/dist/commands/migration-show.d.mts.map +1 -1
  43. package/dist/commands/migration-show.mjs +28 -29
  44. package/dist/commands/migration-show.mjs.map +1 -1
  45. package/dist/commands/migration-status.d.mts +23 -5
  46. package/dist/commands/migration-status.d.mts.map +1 -1
  47. package/dist/commands/migration-status.mjs +8 -3
  48. package/dist/{config-loader-_xQZsw0i.mjs → config-loader-ih8ViDb_.mjs} +2 -2
  49. package/dist/config-loader-ih8ViDb_.mjs.map +1 -0
  50. package/dist/config-loader.mjs +1 -1
  51. package/dist/contract-emit-DS5NzZh2.mjs +6 -0
  52. package/dist/contract-emit-RZBWzkop.mjs +329 -0
  53. package/dist/contract-emit-RZBWzkop.mjs.map +1 -0
  54. package/dist/contract-emit-rt_Nmdwq.mjs +150 -0
  55. package/dist/contract-emit-rt_Nmdwq.mjs.map +1 -0
  56. package/dist/{contract-enrichment-BV4KpbNW.mjs → contract-enrichment-4Ptgw3Pe.mjs} +1 -1
  57. package/dist/{contract-enrichment-BV4KpbNW.mjs.map → contract-enrichment-4Ptgw3Pe.mjs.map} +1 -1
  58. package/dist/{contract-infer-CUbiWGX0.mjs → contract-infer-Cf5J2wVg.mjs} +11 -19
  59. package/dist/contract-infer-Cf5J2wVg.mjs.map +1 -0
  60. package/dist/exports/control-api.d.mts +86 -21
  61. package/dist/exports/control-api.d.mts.map +1 -1
  62. package/dist/exports/control-api.mjs +7 -5
  63. package/dist/exports/index.mjs +8 -3
  64. package/dist/exports/index.mjs.map +1 -1
  65. package/dist/exports/init-output.d.mts +39 -0
  66. package/dist/exports/init-output.d.mts.map +1 -0
  67. package/dist/exports/init-output.mjs +3 -0
  68. package/dist/{framework-components-B__p--vT.mjs → framework-components-Bgcre3Z6.mjs} +2 -2
  69. package/dist/{framework-components-B__p--vT.mjs.map → framework-components-Bgcre3Z6.mjs.map} +1 -1
  70. package/dist/init-DAbQMxIR.mjs +2062 -0
  71. package/dist/init-DAbQMxIR.mjs.map +1 -0
  72. package/dist/{inspect-live-schema-wIYBTdL3.mjs → inspect-live-schema-LWtXfxm_.mjs} +9 -9
  73. package/dist/inspect-live-schema-LWtXfxm_.mjs.map +1 -0
  74. package/dist/migration-cli.d.mts +80 -0
  75. package/dist/migration-cli.d.mts.map +1 -0
  76. package/dist/migration-cli.mjs +408 -0
  77. package/dist/migration-cli.mjs.map +1 -0
  78. package/dist/{migration-command-scaffold-BC73xQSo.mjs → migration-command-scaffold-CU452v9h.mjs} +7 -7
  79. package/dist/{migration-command-scaffold-BC73xQSo.mjs.map → migration-command-scaffold-CU452v9h.mjs.map} +1 -1
  80. package/dist/{migration-status-CXBbScH5.mjs → migration-status-DoPrFIOQ.mjs} +119 -64
  81. package/dist/migration-status-DoPrFIOQ.mjs.map +1 -0
  82. package/dist/{migrations-DYRAjiVh.mjs → migrations-MEoKMiV5.mjs} +42 -21
  83. package/dist/migrations-MEoKMiV5.mjs.map +1 -0
  84. package/dist/output-BpcQrnnq.mjs +103 -0
  85. package/dist/output-BpcQrnnq.mjs.map +1 -0
  86. package/dist/{progress-adapter-Bwouy73-.mjs → progress-adapter-DgRGldpT.mjs} +1 -1
  87. package/dist/{progress-adapter-Bwouy73-.mjs.map → progress-adapter-DgRGldpT.mjs.map} +1 -1
  88. package/dist/quick-reference-mongo.md +34 -13
  89. package/dist/quick-reference-postgres.md +11 -9
  90. package/dist/{result-handler-CGohaH1o.mjs → result-handler-Ch6hVnOo.mjs} +36 -94
  91. package/dist/result-handler-Ch6hVnOo.mjs.map +1 -0
  92. package/dist/{terminal-ui-BuPXVRFY.mjs → terminal-ui-u2YgKghu.mjs} +76 -2
  93. package/dist/terminal-ui-u2YgKghu.mjs.map +1 -0
  94. package/dist/{verify-Cm2UFuZA.mjs → verify-BT9tgCOH.mjs} +2 -2
  95. package/dist/{verify-Cm2UFuZA.mjs.map → verify-BT9tgCOH.mjs.map} +1 -1
  96. package/package.json +27 -17
  97. package/src/cli.ts +32 -6
  98. package/src/commands/contract-emit.ts +67 -163
  99. package/src/commands/contract-infer.ts +7 -20
  100. package/src/commands/db-init.ts +1 -0
  101. package/src/commands/db-update.ts +1 -1
  102. package/src/commands/init/detect-pnpm-catalog.ts +141 -0
  103. package/src/commands/init/errors.ts +254 -0
  104. package/src/commands/init/exit-codes.ts +62 -0
  105. package/src/commands/init/hygiene-gitattributes.ts +97 -0
  106. package/src/commands/init/hygiene-gitignore.ts +48 -0
  107. package/src/commands/init/hygiene-package-scripts.ts +91 -0
  108. package/src/commands/init/index.ts +112 -7
  109. package/src/commands/init/init.ts +766 -144
  110. package/src/commands/init/inputs.ts +421 -0
  111. package/src/commands/init/output.ts +147 -0
  112. package/src/commands/init/probe-db.ts +308 -0
  113. package/src/commands/init/reinit-cleanup.ts +83 -0
  114. package/src/commands/init/templates/agent-skill-mongo.md +63 -31
  115. package/src/commands/init/templates/agent-skill-postgres.md +1 -1
  116. package/src/commands/init/templates/agent-skill.ts +25 -3
  117. package/src/commands/init/templates/code-templates.ts +125 -32
  118. package/src/commands/init/templates/env.ts +80 -0
  119. package/src/commands/init/templates/quick-reference-mongo.md +34 -13
  120. package/src/commands/init/templates/quick-reference-postgres.md +11 -9
  121. package/src/commands/init/templates/quick-reference.ts +42 -3
  122. package/src/commands/init/templates/tsconfig.ts +167 -5
  123. package/src/commands/inspect-live-schema.ts +10 -5
  124. package/src/commands/migration-apply.ts +86 -65
  125. package/src/commands/migration-new.ts +28 -34
  126. package/src/commands/migration-plan.ts +80 -56
  127. package/src/commands/migration-ref.ts +40 -54
  128. package/src/commands/migration-show.ts +53 -36
  129. package/src/commands/migration-status.ts +202 -71
  130. package/src/config-path-validation.ts +0 -1
  131. package/src/control-api/client.ts +21 -0
  132. package/src/control-api/operations/contract-emit.ts +198 -115
  133. package/src/control-api/operations/db-init.ts +10 -6
  134. package/src/control-api/operations/db-update.ts +10 -6
  135. package/src/control-api/operations/migration-apply.ts +30 -9
  136. package/src/control-api/types.ts +69 -7
  137. package/src/exports/control-api.ts +2 -1
  138. package/src/exports/init-output.ts +10 -0
  139. package/src/migration-cli.ts +577 -0
  140. package/src/utils/cli-errors.ts +50 -2
  141. package/src/utils/command-helpers.ts +48 -26
  142. package/src/utils/emit-queue.ts +26 -0
  143. package/src/utils/formatters/graph-migration-mapper.ts +7 -3
  144. package/src/utils/formatters/migrations.ts +62 -26
  145. package/src/utils/publish-contract-artifact-pair.ts +134 -0
  146. package/dist/cli-errors-CznZA5-d.mjs +0 -5
  147. package/dist/cli-errors-z37sV3eR.d.mts +0 -4
  148. package/dist/client-DGKrciLM.mjs.map +0 -1
  149. package/dist/config-loader-_xQZsw0i.mjs.map +0 -1
  150. package/dist/contract-emit-304WZtZJ.mjs +0 -4
  151. package/dist/contract-emit-DgeWdonT.mjs +0 -122
  152. package/dist/contract-emit-DgeWdonT.mjs.map +0 -1
  153. package/dist/contract-emit-mU1_B_m9.mjs +0 -195
  154. package/dist/contract-emit-mU1_B_m9.mjs.map +0 -1
  155. package/dist/contract-infer-CUbiWGX0.mjs.map +0 -1
  156. package/dist/extract-operation-statements-DWWFz1PK.mjs +0 -13
  157. package/dist/extract-operation-statements-DWWFz1PK.mjs.map +0 -1
  158. package/dist/extract-sql-ddl-7zn_AFS8.mjs +0 -26
  159. package/dist/extract-sql-ddl-7zn_AFS8.mjs.map +0 -1
  160. package/dist/init-DRquYpPa.mjs +0 -430
  161. package/dist/init-DRquYpPa.mjs.map +0 -1
  162. package/dist/inspect-live-schema-wIYBTdL3.mjs.map +0 -1
  163. package/dist/migration-status-CXBbScH5.mjs.map +0 -1
  164. package/dist/migrations-DYRAjiVh.mjs.map +0 -1
  165. package/dist/result-handler-CGohaH1o.mjs.map +0 -1
  166. package/dist/terminal-ui-BuPXVRFY.mjs.map +0 -1
  167. package/dist/validate-contract-deps-DZqv9m7H.mjs +0 -37
  168. package/dist/validate-contract-deps-DZqv9m7H.mjs.map +0 -1
  169. package/src/control-api/operations/extract-operation-statements.ts +0 -14
  170. package/src/control-api/operations/extract-sql-ddl.ts +0 -47
@@ -1 +1 @@
1
- {"version":3,"file":"migration-show.mjs","names":["details: Array<{ label: string; value: string }>","pkg: MigrationBundle"],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';\nimport { findLatestMigration, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type { MigrationBundle } from '@prisma-next/migration-tools/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/types';\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 { extractOperationStatements } from '../control-api/operations/extract-operation-statements';\nimport { type CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string;\n readonly kind: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly sql: readonly string[];\n readonly summary: string;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveByHashPrefix(\n packages: readonly MigrationBundle[],\n prefix: string,\n): Result<MigrationBundle, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const matches = packages.filter((p) => p.manifest.migrationId.startsWith(normalizedPrefix));\n\n if (matches.length === 1) {\n return ok(matches[0]!);\n }\n\n if (matches.length === 0) {\n return notOk(\n errorRuntime('No migration found matching prefix', {\n why: `No migration has a migrationId starting with \"${normalizedPrefix}\"`,\n fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',\n }),\n );\n }\n\n const candidates = matches.map((p) => ` ${p.dirName} ${p.manifest.migrationId}`).join('\\n');\n return notOk(\n errorRuntime('Ambiguous hash prefix', {\n why: `Multiple migrations match prefix \"${normalizedPrefix}\":\\n${candidates}`,\n fix: 'Provide a longer prefix to uniquely identify the migration.',\n }),\n );\n}\n\nasync function executeMigrationShowCommand(\n target: string | undefined,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\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\n const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (target) {\n details.push({ label: 'target', value: target });\n }\n const header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let pkg: MigrationBundle;\n\n try {\n if (target && looksLikePath(target)) {\n pkg = await readMigrationPackage(resolve(target));\n } else {\n const allPackages = await readMigrationsDir(migrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${migrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n\n if (target) {\n const resolved = resolveByHashPrefix(allPackages, target);\n if (!resolved.ok) return resolved;\n pkg = resolved.value;\n } else {\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: 'No latest migration found in the migration history',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.manifest.migrationId === latestMigration.migrationId,\n );\n if (!leafPkg) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `Latest migration ${latestMigration.dirName} does not match any package`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n pkg = leafPkg;\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n const sql = extractOperationStatements(config.family.familyId, ops) ?? [];\n\n const result: MigrationShowResult = {\n ok: true,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.manifest.from,\n to: pkg.manifest.to,\n migrationId: pkg.manifest.migrationId,\n kind: pkg.manifest.kind,\n createdAt: pkg.manifest.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n sql,\n summary: `${ops.length} operation(s)`,\n };\n return ok(result);\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, DDL preview, and metadata for a migration package.\\n' +\n 'Accepts a directory path, a hash prefix (git-style), or defaults to the\\n' +\n 'latest migration.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n addGlobalOptions(command)\n .argument(\n '[target]',\n 'Migration directory path or migrationId hash prefix (defaults to latest)',\n )\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"migration-show.mjs","names":["details: Array<{ label: string; value: string }>","pkg: MigrationPackage","preview: OperationPreview"],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import type {\n MigrationPlanOperation,\n OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport {\n findLatestMigration,\n reconstructGraph,\n} from '@prisma-next/migration-tools/migration-graph';\nimport type { MigrationPackage } from '@prisma-next/migration-tools/package';\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 {\n type CliStructuredError,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string | null;\n readonly to: string;\n readonly migrationHash: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the migration's operations. Replaces\n * the previous string-array DDL field. Always defined; statements is empty\n * for a no-op migration or a family that does not implement the\n * `OperationPreviewCapable` capability.\n */\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\nexport function resolveByHashPrefix(\n packages: readonly MigrationPackage[],\n prefix: string,\n): Result<MigrationPackage, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const matches = packages.filter((p) => p.metadata.migrationHash.startsWith(normalizedPrefix));\n\n if (matches.length === 1) {\n return ok(matches[0]!);\n }\n\n if (matches.length === 0) {\n return notOk(\n errorRuntime('No migration found matching prefix', {\n why: `No migration has a migrationHash starting with \"${normalizedPrefix}\"`,\n fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',\n }),\n );\n }\n\n const candidates = matches.map((p) => ` ${p.dirName} ${p.metadata.migrationHash}`).join('\\n');\n return notOk(\n errorRuntime('Ambiguous hash prefix', {\n why: `Multiple migrations match prefix \"${normalizedPrefix}\":\\n${candidates}`,\n fix: 'Provide a longer prefix to uniquely identify the migration.',\n }),\n );\n}\n\nasync function executeMigrationShowCommand(\n target: string | undefined,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\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\n const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (target) {\n details.push({ label: 'target', value: target });\n }\n const header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let pkg: MigrationPackage;\n\n try {\n if (target && looksLikePath(target)) {\n pkg = await readMigrationPackage(resolve(target));\n } else {\n const allPackages = await readMigrationsDir(migrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${migrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n\n if (target) {\n const resolved = resolveByHashPrefix(allPackages, target);\n if (!resolved.ok) return resolved;\n pkg = resolved.value;\n } else {\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: 'No latest migration found in the migration history',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n if (!leafPkg) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `Latest migration ${latestMigration.dirName} does not match any package`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n pkg = leafPkg;\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n\n // `migration show` is an offline command; the control client is constructed\n // purely to dispatch the family-specific `toOperationPreview` capability and\n // is not connected to a database.\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...(config.driver ? { driver: config.driver } : {}),\n extensionPacks: config.extensionPacks ?? [],\n });\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n\n const result: MigrationShowResult = {\n ok: true,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.metadata.from,\n to: pkg.metadata.to,\n migrationHash: pkg.metadata.migrationHash,\n createdAt: pkg.metadata.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n preview,\n summary: `${ops.length} operation(s)`,\n };\n return ok(result);\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, statement preview, and metadata for a migration package.\\n' +\n 'Accepts a directory path, a hash prefix (git-style), or defaults to the\\n' +\n 'latest migration.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n addGlobalOptions(command)\n .argument('[target]', 'Migration directory path or migrationHash prefix (defaults to latest)')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
- import { MigrationBundle, MigrationGraph } from "@prisma-next/migration-tools/types";
2
+ import { MigrationPackage } from "@prisma-next/migration-tools/package";
3
+ import { MigrationGraph } from "@prisma-next/migration-tools/graph";
3
4
 
4
5
  //#region src/utils/migration-types.d.ts
5
6
  interface StatusRef {
@@ -27,7 +28,7 @@ interface MigrationStatusEntry {
27
28
  readonly dirName: string;
28
29
  readonly from: string;
29
30
  readonly to: string;
30
- readonly migrationId: string;
31
+ readonly migrationHash: string;
31
32
  readonly operationCount: number;
32
33
  readonly operationSummary: string;
33
34
  readonly hasDestructive: boolean;
@@ -41,23 +42,39 @@ interface MigrationStatusResult {
41
42
  readonly targetHash: string;
42
43
  readonly contractHash: string;
43
44
  readonly refs?: readonly StatusRef[];
45
+ /** Required invariants from the active ref, sorted ascending. Always present (`[]` when no `--ref` or the ref declares none) — knowable offline. */
46
+ readonly requiredInvariants: readonly string[];
47
+ /**
48
+ * Invariants the marker has applied at least once, intersected with
49
+ * `requiredInvariants` for display relevance. JSON consumers see only the
50
+ * subset overlapping the active ref's required set — the full unfiltered
51
+ * marker invariant list lives on `marker.invariants` (control plane) and
52
+ * is not surfaced here. Present only in `mode === 'online'`; absent when
53
+ * offline (the marker is unknown, not empty).
54
+ */
55
+ readonly appliedInvariants?: readonly string[];
56
+ /** required − applied. Present only in `mode === 'online'`; absent when offline. */
57
+ readonly missingInvariants?: readonly string[];
44
58
  readonly pathDecision?: {
45
59
  readonly fromHash: string;
46
60
  readonly toHash: string;
47
61
  readonly alternativeCount: number;
48
62
  readonly tieBreakReasons: readonly string[];
49
63
  readonly refName?: string;
64
+ readonly requiredInvariants: readonly string[];
65
+ readonly satisfiedInvariants: readonly string[];
50
66
  readonly selectedPath: readonly {
51
67
  readonly dirName: string;
52
- readonly migrationId: string;
68
+ readonly migrationHash: string;
53
69
  readonly from: string;
54
70
  readonly to: string;
71
+ readonly invariants: readonly string[];
55
72
  }[];
56
73
  };
57
74
  readonly summary: string;
58
75
  readonly diagnostics: readonly StatusDiagnostic[];
59
76
  readonly graph?: MigrationGraph;
60
- readonly bundles?: readonly MigrationBundle[];
77
+ readonly bundles?: readonly MigrationPackage[];
61
78
  readonly edgeStatuses?: readonly EdgeStatus[];
62
79
  readonly activeRefHash?: string;
63
80
  readonly activeRefName?: string;
@@ -80,6 +97,7 @@ interface MigrationStatusResult {
80
97
  */
81
98
  declare function deriveEdgeStatuses(graph: MigrationGraph, targetHash: string, contractHash: string, markerHash: string | undefined, mode: 'online' | 'offline'): EdgeStatus[];
82
99
  declare function createMigrationStatusCommand(): Command;
100
+ declare function formatStatusSummary(result: MigrationStatusResult, colorize: boolean): string;
83
101
  //#endregion
84
- export { MigrationStatusEntry, MigrationStatusResult, type StatusDiagnostic, type StatusRef, createMigrationStatusCommand, deriveEdgeStatuses };
102
+ export { MigrationStatusEntry, MigrationStatusResult, type StatusDiagnostic, type StatusRef, createMigrationStatusCommand, deriveEdgeStatuses, formatStatusSummary };
85
103
  //# sourceMappingURL=migration-status.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/migration-types.ts","../../src/utils/formatters/graph-migration-mapper.ts","../../src/commands/migration-status.ts"],"sourcesContent":[],"mappings":";;;;UAAiB,SAAA;;;;AAAjB;AAMiB,UAAA,gBAAA,CAAgB;;;;ECWrB,SAAA,KAAA,EAAA,SAAc,MAAA,EAAA;AAmB1B;;;KAnBY,cAAA;ADjBZ;AAMiB,UC8BA,UAAA,CD9BgB;;mBCgCd;;;;ADtCF,UE2DA,oBAAA,CF3DS;EAMT,SAAA,OAAA,EAAA,MAAgB;;;;ECWrB,SAAA,cAAc,EAAA,MAAA;EAmBT,SAAA,gBAEE,EAAA,MAAA;;mBC6BA;;AAKF,UAAA,qBAAA,CAAqB;EAGN,SAAA,EAAA,EAAA,IAAA;EAIL,SAAA,IAAA,EAAA,QAAA,GAAA,SAAA;EAeM,SAAA,UAAA,EAAA,SAnBD,oBAmBC,EAAA;EACd,SAAA,UAAA,CAAA,EAAA,MAAA;EACW,SAAA,UAAA,EAAA,MAAA;EACK,SAAA,YAAA,EAAA,MAAA;EAAU,SAAA,IAAA,CAAA,EAAA,SAlBlB,SAkBkB,EAAA;EAkD7B,SAAA,YAAkB,CAAA,EAAA;IA2iBlB,SAAA,QAAA,EAAA,MAAA;;;;;;;;;;;;;iCAhmBiB;mBACd;8BACW;mCACK;;;;;;;;;;;;;;;;;;;;iBAkDnB,kBAAA,QACP,uHAKN;iBAqiBa,4BAAA,CAAA,GAAgC"}
1
+ {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/migration-types.ts","../../src/utils/formatters/graph-migration-mapper.ts","../../src/commands/migration-status.ts"],"sourcesContent":[],"mappings":";;;;;UAAiB,SAAA;;;;;AAAA,UAMA,gBAAA,CANS;EAMT,SAAA,IAAA,EAAA,MAAgB;;;;ACWjC;;;KAAY,cAAA;;ADjBK,UCoCA,UAAA,CDpCS;EAMT,SAAA,OAAA,EAAA,MAAgB;mBCgCd;;;;ADtCF,UEmEA,oBAAA,CFnES;EAMT,SAAA,OAAA,EAAA,MAAgB;;;;ECWrB,SAAA,cAAc,EAAA,MAAA;EAmBT,SAAA,gBAEE,EAAA,MAAA;;mBCqCA;;AAKF,UAAA,qBAAA,CAAqB;EAGN,SAAA,EAAA,EAAA,IAAA;EAIL,SAAA,IAAA,EAAA,QAAA,GAAA,SAAA;EA+BM,SAAA,UAAA,EAAA,SAnCD,oBAmCC,EAAA;EACd,SAAA,UAAA,CAAA,EAAA,MAAA;EACW,SAAA,UAAA,EAAA,MAAA;EACK,SAAA,YAAA,EAAA,MAAA;EAAU,SAAA,IAAA,CAAA,EAAA,SAlClB,SAkCkB,EAAA;EAkD7B;EA8nBA,SAAA,kBAAA,EAAA,SAA4B,MAAI,EAAA;EAoGhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAvxBiB;mBACd;8BACW;mCACK;;;;;;;;;;;;;;;;;;;;iBAkDnB,kBAAA,QACP,uHAKN;iBAwnBa,4BAAA,CAAA,GAAgC;iBAoGhC,mBAAA,SAA4B"}
@@ -1,4 +1,9 @@
1
- import "../config-loader-_xQZsw0i.mjs";
2
- import { n as deriveEdgeStatuses, t as createMigrationStatusCommand } from "../migration-status-CXBbScH5.mjs";
1
+ import "../config-loader-ih8ViDb_.mjs";
2
+ import "../cli-errors-By1iVE3z.mjs";
3
+ import "../framework-components-Bgcre3Z6.mjs";
4
+ import "../terminal-ui-u2YgKghu.mjs";
5
+ import "../result-handler-Ch6hVnOo.mjs";
6
+ import "../client-1JqqkiC7.mjs";
7
+ import { n as deriveEdgeStatuses, r as formatStatusSummary, t as createMigrationStatusCommand } from "../migration-status-DoPrFIOQ.mjs";
3
8
 
4
- export { createMigrationStatusCommand, deriveEdgeStatuses };
9
+ export { createMigrationStatusCommand, deriveEdgeStatuses, formatStatusSummary };
@@ -1,8 +1,8 @@
1
1
  import { getEmittedArtifactPaths } from "@prisma-next/emitter";
2
2
  import { errorConfigFileNotFound, errorConfigValidation, errorUnexpected } from "@prisma-next/errors/control";
3
+ import { ifDefined } from "@prisma-next/utils/defined";
3
4
  import { dirname, resolve } from "pathe";
4
5
  import { ConfigValidationError, validateConfig } from "@prisma-next/config/config-validation";
5
- import { ifDefined } from "@prisma-next/utils/defined";
6
6
  import { loadConfig } from "c12";
7
7
  import { normalizeContractConfig } from "@prisma-next/config/config-types";
8
8
 
@@ -87,4 +87,4 @@ async function loadConfig$1(configPath) {
87
87
 
88
88
  //#endregion
89
89
  export { loadConfig$1 as t };
90
- //# sourceMappingURL=config-loader-_xQZsw0i.mjs.map
90
+ //# sourceMappingURL=config-loader-ih8ViDb_.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader-ih8ViDb_.mjs","names":["emittedArtifactPaths: ReturnType<typeof getEmittedArtifactPaths>","loadConfigC12","loadConfig"],"sources":["../src/config-path-validation.ts","../src/config-loader.ts"],"sourcesContent":["import {\n type ContractSourceProvider,\n normalizeContractConfig,\n type PrismaNextConfig,\n} from '@prisma-next/config/config-types';\nimport { ConfigValidationError } from '@prisma-next/config/config-validation';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { resolve } from 'pathe';\n\nfunction throwValidation(field: string, why: string): never {\n throw new ConfigValidationError(field, why);\n}\n\nfunction finalizeContractSource(\n source: ContractSourceProvider,\n configDir: string,\n): ContractSourceProvider {\n const resolvedInputs = source.inputs?.map((input) => resolve(configDir, input));\n if (resolvedInputs === undefined) {\n return source;\n }\n\n return {\n ...source,\n inputs: resolvedInputs,\n };\n}\n\nfunction validateNoOutputsAreInputs(\n inputs: readonly string[] | undefined,\n output: string | undefined,\n): void {\n if (inputs === undefined || output === undefined) {\n return;\n }\n\n let emittedArtifactPaths: ReturnType<typeof getEmittedArtifactPaths>;\n try {\n emittedArtifactPaths = getEmittedArtifactPaths(output);\n } catch (error) {\n throwValidation('contract.output', error instanceof Error ? error.message : String(error));\n }\n\n const emittedPaths = new Set([emittedArtifactPaths.jsonPath, emittedArtifactPaths.dtsPath]);\n\n for (const input of inputs) {\n if (emittedPaths.has(input)) {\n throwValidation(\n 'contract.source.inputs[]',\n 'Config.contract.source.inputs must not include emitted artifact paths derived from contract.output',\n );\n }\n }\n}\n\nexport function finalizeConfig(config: PrismaNextConfig, configDir: string): PrismaNextConfig {\n if (!config.contract) {\n return config;\n }\n const contract = normalizeContractConfig(config.contract);\n const source = finalizeContractSource(contract.source, configDir);\n const output = resolve(configDir, contract.output);\n\n validateNoOutputsAreInputs(source.inputs, output);\n\n return {\n ...config,\n contract: {\n ...contract,\n source,\n output,\n },\n };\n}\n","import type { PrismaNextConfig } from '@prisma-next/config/config-types';\nimport { ConfigValidationError, validateConfig } from '@prisma-next/config/config-validation';\nimport {\n errorConfigFileNotFound,\n errorConfigValidation,\n errorUnexpected,\n} from '@prisma-next/errors/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { loadConfig as loadConfigC12 } from 'c12';\nimport { dirname, resolve } from 'pathe';\nimport { finalizeConfig } from './config-path-validation';\n\nasync function loadValidatedConfig(configPath?: string): Promise<PrismaNextConfig> {\n const cwd = process.cwd();\n const resolvedConfigPath = configPath ? resolve(cwd, configPath) : undefined;\n const configCwd = resolvedConfigPath ? dirname(resolvedConfigPath) : cwd;\n\n const result = await loadConfigC12<PrismaNextConfig>({\n name: 'prisma-next',\n ...ifDefined('configFile', resolvedConfigPath),\n cwd: configCwd,\n });\n\n // When a specific config file was requested, verify it was actually loaded\n // (c12 falls back to searching by name if the specified file doesn't exist)\n if (resolvedConfigPath && result.configFile !== resolvedConfigPath) {\n throw errorConfigFileNotFound(resolvedConfigPath);\n }\n\n // Check if config is missing or empty (c12 may return empty object when file doesn't exist)\n if (!result.config || Object.keys(result.config).length === 0) {\n // Use c12's configFile if available, otherwise use explicit configPath, otherwise omit path\n const displayPath = result.configFile || resolvedConfigPath || configPath;\n throw errorConfigFileNotFound(displayPath);\n }\n\n // Validate config structure\n validateConfig(result.config);\n\n const loadedConfigDir = result.configFile ? dirname(result.configFile) : configCwd;\n return finalizeConfig(result.config, loadedConfigDir);\n}\n\n/**\n * Loads the Prisma Next config from a TypeScript file.\n * Supports both default export and named export.\n * Uses c12 to automatically handle TypeScript compilation and config file discovery.\n *\n * @param configPath - Optional path to config file. Defaults to `./prisma-next.config.ts` in current directory.\n * @returns The loaded config object.\n * @throws Error if config file doesn't exist or is invalid.\n */\nexport async function loadConfig(configPath?: string): Promise<PrismaNextConfig> {\n try {\n return await loadValidatedConfig(configPath);\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw errorConfigValidation(error.field, {\n why: error.why,\n });\n }\n\n // Re-throw structured errors as-is\n if (\n error instanceof Error &&\n 'code' in error &&\n typeof (error as { code: string }).code === 'string'\n ) {\n throw error;\n }\n\n if (error instanceof Error) {\n // Check for file not found errors\n if (\n error.message.includes('not found') ||\n error.message.includes('Cannot find') ||\n error.message.includes('ENOENT')\n ) {\n // Use resolved path if available, otherwise use original configPath\n const displayPath = configPath ? resolve(process.cwd(), configPath) : undefined;\n throw errorConfigFileNotFound(displayPath, {\n why: error.message,\n });\n }\n // For other errors, wrap in unexpected error\n throw errorUnexpected(error.message, {\n why: `Failed to load config: ${error.message}`,\n });\n }\n throw errorUnexpected(String(error));\n }\n}\n"],"mappings":";;;;;;;;;AASA,SAAS,gBAAgB,OAAe,KAAoB;AAC1D,OAAM,IAAI,sBAAsB,OAAO,IAAI;;AAG7C,SAAS,uBACP,QACA,WACwB;CACxB,MAAM,iBAAiB,OAAO,QAAQ,KAAK,UAAU,QAAQ,WAAW,MAAM,CAAC;AAC/E,KAAI,mBAAmB,OACrB,QAAO;AAGT,QAAO;EACL,GAAG;EACH,QAAQ;EACT;;AAGH,SAAS,2BACP,QACA,QACM;AACN,KAAI,WAAW,UAAa,WAAW,OACrC;CAGF,IAAIA;AACJ,KAAI;AACF,yBAAuB,wBAAwB,OAAO;UAC/C,OAAO;AACd,kBAAgB,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;;CAG5F,MAAM,eAAe,IAAI,IAAI,CAAC,qBAAqB,UAAU,qBAAqB,QAAQ,CAAC;AAE3F,MAAK,MAAM,SAAS,OAClB,KAAI,aAAa,IAAI,MAAM,CACzB,iBACE,4BACA,qGACD;;AAKP,SAAgB,eAAe,QAA0B,WAAqC;AAC5F,KAAI,CAAC,OAAO,SACV,QAAO;CAET,MAAM,WAAW,wBAAwB,OAAO,SAAS;CACzD,MAAM,SAAS,uBAAuB,SAAS,QAAQ,UAAU;CACjE,MAAM,SAAS,QAAQ,WAAW,SAAS,OAAO;AAElD,4BAA2B,OAAO,QAAQ,OAAO;AAEjD,QAAO;EACL,GAAG;EACH,UAAU;GACR,GAAG;GACH;GACA;GACD;EACF;;;;;AC5DH,eAAe,oBAAoB,YAAgD;CACjF,MAAM,MAAM,QAAQ,KAAK;CACzB,MAAM,qBAAqB,aAAa,QAAQ,KAAK,WAAW,GAAG;CACnE,MAAM,YAAY,qBAAqB,QAAQ,mBAAmB,GAAG;CAErE,MAAM,SAAS,MAAMC,WAAgC;EACnD,MAAM;EACN,GAAG,UAAU,cAAc,mBAAmB;EAC9C,KAAK;EACN,CAAC;AAIF,KAAI,sBAAsB,OAAO,eAAe,mBAC9C,OAAM,wBAAwB,mBAAmB;AAInD,KAAI,CAAC,OAAO,UAAU,OAAO,KAAK,OAAO,OAAO,CAAC,WAAW,EAG1D,OAAM,wBADc,OAAO,cAAc,sBAAsB,WACrB;AAI5C,gBAAe,OAAO,OAAO;CAE7B,MAAM,kBAAkB,OAAO,aAAa,QAAQ,OAAO,WAAW,GAAG;AACzE,QAAO,eAAe,OAAO,QAAQ,gBAAgB;;;;;;;;;;;AAYvD,eAAsBC,aAAW,YAAgD;AAC/E,KAAI;AACF,SAAO,MAAM,oBAAoB,WAAW;UACrC,OAAO;AACd,MAAI,iBAAiB,sBACnB,OAAM,sBAAsB,MAAM,OAAO,EACvC,KAAK,MAAM,KACZ,CAAC;AAIJ,MACE,iBAAiB,SACjB,UAAU,SACV,OAAQ,MAA2B,SAAS,SAE5C,OAAM;AAGR,MAAI,iBAAiB,OAAO;AAE1B,OACE,MAAM,QAAQ,SAAS,YAAY,IACnC,MAAM,QAAQ,SAAS,cAAc,IACrC,MAAM,QAAQ,SAAS,SAAS,CAIhC,OAAM,wBADc,aAAa,QAAQ,QAAQ,KAAK,EAAE,WAAW,GAAG,QAC3B,EACzC,KAAK,MAAM,SACZ,CAAC;AAGJ,SAAM,gBAAgB,MAAM,SAAS,EACnC,KAAK,0BAA0B,MAAM,WACtC,CAAC;;AAEJ,QAAM,gBAAgB,OAAO,MAAM,CAAC"}
@@ -1,3 +1,3 @@
1
- import { t as loadConfig } from "./config-loader-_xQZsw0i.mjs";
1
+ import { t as loadConfig } from "./config-loader-ih8ViDb_.mjs";
2
2
 
3
3
  export { loadConfig };
@@ -0,0 +1,6 @@
1
+ import "./config-loader-ih8ViDb_.mjs";
2
+ import "./cli-errors-By1iVE3z.mjs";
3
+ import { t as executeContractEmit } from "./contract-emit-RZBWzkop.mjs";
4
+ import "./framework-components-Bgcre3Z6.mjs";
5
+
6
+ export { executeContractEmit };
@@ -0,0 +1,329 @@
1
+ import { t as loadConfig } from "./config-loader-ih8ViDb_.mjs";
2
+ import { i as errorContractConfigMissing, m as errorRuntime } from "./cli-errors-By1iVE3z.mjs";
3
+ import { t as assertFrameworkComponentsCompatible } from "./framework-components-Bgcre3Z6.mjs";
4
+ import { t as enrichContract } from "./contract-enrichment-4Ptgw3Pe.mjs";
5
+ import { createRequire } from "node:module";
6
+ import { emit, getEmittedArtifactPaths } from "@prisma-next/emitter";
7
+ import { ifDefined } from "@prisma-next/utils/defined";
8
+ import { basename, dirname, join } from "pathe";
9
+ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
10
+ import { createControlStack } from "@prisma-next/framework-components/control";
11
+ import { abortable } from "@prisma-next/utils/abortable";
12
+
13
+ //#region src/utils/emit-queue.ts
14
+ /**
15
+ * Per-output FIFO queue for `executeContractEmit`.
16
+ *
17
+ * Ensures that at most one emit (load → resolve source → emit bytes → publish)
18
+ * runs per output JSON path at a time. Concurrent calls for the same path
19
+ * line up behind the in-flight one and run in submission order; the user-visible
20
+ * outcome is "last submission wins on disk" without any supersession bookkeeping.
21
+ *
22
+ * Long-lived hosts (Vite dev server, watch CLIs) must call `disposeEmitQueue`
23
+ * when they stop publishing to a path, otherwise the module-global `Map`
24
+ * accumulates one entry per unique output path for the lifetime of the process.
25
+ */
26
+ const emitQueues = /* @__PURE__ */ new Map();
27
+ function queueEmitByOutput(outputJsonPath, action) {
28
+ const next = (emitQueues.get(outputJsonPath) ?? Promise.resolve()).then(action, action);
29
+ emitQueues.set(outputJsonPath, next);
30
+ return next;
31
+ }
32
+ function disposeEmitQueue(outputJsonPath) {
33
+ emitQueues.delete(outputJsonPath);
34
+ }
35
+
36
+ //#endregion
37
+ //#region src/utils/publish-contract-artifact-pair.ts
38
+ function isRecord$1(value) {
39
+ return typeof value === "object" && value !== null;
40
+ }
41
+ function createTempArtifactPath(path, publicationToken, phase) {
42
+ return join(dirname(path), `.${basename(path)}.${process.pid}.${publicationToken}.${phase}.tmp`);
43
+ }
44
+ async function readExistingArtifact(path) {
45
+ try {
46
+ return { content: await readFile(path, "utf-8") };
47
+ } catch (error) {
48
+ if (isRecord$1(error) && error["code"] === "ENOENT") return "remove";
49
+ throw error;
50
+ }
51
+ }
52
+ async function restoreArtifact(path, previous, publicationToken) {
53
+ if (previous === "remove") {
54
+ await rm(path, { force: true });
55
+ return;
56
+ }
57
+ const restorePath = createTempArtifactPath(path, publicationToken, "rollback");
58
+ await writeFile(restorePath, previous.content, "utf-8");
59
+ try {
60
+ await rename(restorePath, path);
61
+ } finally {
62
+ await rm(restorePath, { force: true });
63
+ }
64
+ }
65
+ function withRollbackFailureCause(error, rollbackFailures) {
66
+ const rollbackCause = new AggregateError(rollbackFailures, "Failed to restore published artifacts");
67
+ if (error instanceof Error) {
68
+ Object.defineProperty(error, "cause", {
69
+ value: rollbackCause,
70
+ configurable: true,
71
+ writable: true
72
+ });
73
+ return error;
74
+ }
75
+ return new Error(String(error), { cause: rollbackCause });
76
+ }
77
+ async function publishPairWithRollback(entries, publicationToken) {
78
+ const replaced = [];
79
+ try {
80
+ for (const entry of entries) {
81
+ await rename(entry.tempPath, entry.outputPath);
82
+ replaced.push(entry);
83
+ }
84
+ } catch (error) {
85
+ const rollbackFailures = (await Promise.allSettled(replaced.map((entry) => restoreArtifact(entry.outputPath, entry.previous, publicationToken)))).flatMap((result) => result.status === "rejected" ? [result.reason] : []);
86
+ if (rollbackFailures.length > 0) throw withRollbackFailureCause(error, rollbackFailures);
87
+ throw error;
88
+ }
89
+ }
90
+ async function publishContractArtifactPair({ outputJsonPath, outputDtsPath, contractJson, contractDts, publicationToken, beforePublish }) {
91
+ const tempJsonPath = createTempArtifactPath(outputJsonPath, publicationToken, "next");
92
+ const tempDtsPath = createTempArtifactPath(outputDtsPath, publicationToken, "next");
93
+ try {
94
+ await writeFile(tempJsonPath, contractJson, "utf-8");
95
+ await writeFile(tempDtsPath, contractDts, "utf-8");
96
+ if (await beforePublish?.() === false) return false;
97
+ const previousJson = await readExistingArtifact(outputJsonPath);
98
+ await publishPairWithRollback([{
99
+ tempPath: tempDtsPath,
100
+ outputPath: outputDtsPath,
101
+ previous: await readExistingArtifact(outputDtsPath)
102
+ }, {
103
+ tempPath: tempJsonPath,
104
+ outputPath: outputJsonPath,
105
+ previous: previousJson
106
+ }], publicationToken);
107
+ return true;
108
+ } finally {
109
+ await Promise.allSettled([rm(tempJsonPath, { force: true }), rm(tempDtsPath, { force: true })]);
110
+ }
111
+ }
112
+
113
+ //#endregion
114
+ //#region src/utils/validate-contract-deps.ts
115
+ const IMPORT_PATTERN = /import\s+type\s+.*?\s+from\s+['"](@[^/]+\/[^/'"]+)/g;
116
+ function extractPackageSpecifiers(dtsContent) {
117
+ const packages = /* @__PURE__ */ new Set();
118
+ for (const match of dtsContent.matchAll(IMPORT_PATTERN)) {
119
+ const pkg = match[1];
120
+ if (pkg) packages.add(pkg);
121
+ }
122
+ return [...packages];
123
+ }
124
+ function validateContractDeps(dtsContent, projectRoot) {
125
+ const packages = extractPackageSpecifiers(dtsContent);
126
+ const resolve$1 = createRequire(`${projectRoot}/package.json`);
127
+ const missing = [];
128
+ for (const pkg of packages) try {
129
+ resolve$1.resolve(`${pkg}/package.json`);
130
+ } catch {
131
+ missing.push(pkg);
132
+ }
133
+ if (missing.length === 0) return { missing };
134
+ return {
135
+ missing,
136
+ warning: [
137
+ "contract.d.ts imports types from packages that are not installed:",
138
+ missing.map((p) => ` - ${p}`).join("\n"),
139
+ "",
140
+ "Install them with your package manager:",
141
+ ...missing.map((p) => ` ${p}`)
142
+ ].join("\n")
143
+ };
144
+ }
145
+
146
+ //#endregion
147
+ //#region src/control-api/operations/contract-emit.ts
148
+ const EMIT_ACTION = "emit";
149
+ function isRecord(value) {
150
+ return typeof value === "object" && value !== null;
151
+ }
152
+ function startSpan(onProgress, spanId, label) {
153
+ onProgress?.({
154
+ action: EMIT_ACTION,
155
+ kind: "spanStart",
156
+ spanId,
157
+ label
158
+ });
159
+ }
160
+ function endSpan(onProgress, spanId, outcome) {
161
+ onProgress?.({
162
+ action: EMIT_ACTION,
163
+ kind: "spanEnd",
164
+ spanId,
165
+ outcome
166
+ });
167
+ }
168
+ function failedToResolveContractSource(why, fix, meta) {
169
+ return errorRuntime("Failed to resolve contract source", {
170
+ why,
171
+ fix,
172
+ ...ifDefined("meta", meta)
173
+ });
174
+ }
175
+ function diagnosticLocationSuffix(diagnostic) {
176
+ const sourceId = typeof diagnostic["sourceId"] === "string" ? diagnostic["sourceId"] : void 0;
177
+ const span = isRecord(diagnostic["span"]) ? diagnostic["span"] : void 0;
178
+ const start = span && isRecord(span["start"]) ? span["start"] : void 0;
179
+ const line = start && typeof start["line"] === "number" ? start["line"] : void 0;
180
+ const column = start && typeof start["column"] === "number" ? start["column"] : void 0;
181
+ if (sourceId && line !== void 0 && column !== void 0) return ` (${sourceId}:${line}:${column})`;
182
+ if (sourceId) return ` (${sourceId})`;
183
+ return "";
184
+ }
185
+ function mapDiagnosticsToIssues(diagnostics) {
186
+ const issues = [];
187
+ for (const raw of diagnostics) {
188
+ if (!isRecord(raw)) continue;
189
+ const code = typeof raw["code"] === "string" ? raw["code"] : "diagnostic";
190
+ const message = typeof raw["message"] === "string" ? raw["message"] : "";
191
+ issues.push({
192
+ kind: code,
193
+ message: `${message}${diagnosticLocationSuffix(raw)}`
194
+ });
195
+ }
196
+ return issues;
197
+ }
198
+ function validateProviderResult(providerResult) {
199
+ if (!isRecord(providerResult) || typeof providerResult["ok"] !== "boolean") return {
200
+ ok: false,
201
+ error: failedToResolveContractSource("Contract source provider returned malformed result shape.", "Ensure contract.source.load resolves to ok(Contract) or notOk({ summary, diagnostics }).")
202
+ };
203
+ if (providerResult["ok"]) {
204
+ if (!("value" in providerResult)) return {
205
+ ok: false,
206
+ error: failedToResolveContractSource("Contract source provider returned malformed success result: missing value.", "Ensure contract.source.load success payload is ok(Contract).")
207
+ };
208
+ return {
209
+ ok: true,
210
+ value: providerResult["value"]
211
+ };
212
+ }
213
+ const failure = providerResult["failure"];
214
+ if (!isRecord(failure) || typeof failure["summary"] !== "string" || !Array.isArray(failure["diagnostics"])) return {
215
+ ok: false,
216
+ error: failedToResolveContractSource("Contract source provider returned malformed failure result: expected summary and diagnostics.", "Ensure contract.source.load failure payload is notOk({ summary, diagnostics, meta? }).")
217
+ };
218
+ return {
219
+ ok: false,
220
+ error: failedToResolveContractSource(String(failure["summary"]), "Fix contract source diagnostics and return ok(Contract).", {
221
+ diagnostics: failure["diagnostics"],
222
+ issues: mapDiagnosticsToIssues(failure["diagnostics"]),
223
+ ...ifDefined("providerMeta", failure["meta"])
224
+ })
225
+ };
226
+ }
227
+ /**
228
+ * Canonical contract emit operation.
229
+ *
230
+ * This is the SINGLE publication path used by both the CLI command
231
+ * (`prisma-next contract emit`) and the Vite plugin
232
+ * (`@prisma-next/vite-plugin-contract-emit`). New callers must go through this
233
+ * function rather than re-implementing load → emit → publish.
234
+ *
235
+ * The whole flow (load config → resolve source → emit bytes → atomic publish)
236
+ * is serialized per output JSON path via `queueEmitByOutput`. Concurrent calls
237
+ * for the same output line up FIFO; the user-visible outcome is "last
238
+ * submission wins on disk" without any supersession bookkeeping. Within a
239
+ * single emit, `publishContractArtifactPair` stages temp files, renames
240
+ * `contract.d.ts` before `contract.json`, and attempts to restore the previous
241
+ * pair if either rename fails — so type-only consumers never observe a
242
+ * mismatched pair.
243
+ *
244
+ * @throws {CliStructuredError} on config/source/validation problems
245
+ * @throws {DOMException} `AbortError` if cancelled via `signal`
246
+ */
247
+ async function executeContractEmit(options) {
248
+ const { configPath, signal = new AbortController().signal, onProgress } = options;
249
+ const unlessAborted = abortable(signal);
250
+ const config = await unlessAborted(loadConfig(configPath));
251
+ if (!config.contract) throw errorContractConfigMissing({ why: "Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ... }" });
252
+ const contractConfig = config.contract;
253
+ if (!contractConfig.output) throw errorContractConfigMissing({ why: "Contract config must have output path. This should not happen if defineConfig() was used." });
254
+ if (typeof contractConfig.source?.load !== "function") throw errorContractConfigMissing({ why: "Contract config must include a valid source provider object" });
255
+ let outputPaths;
256
+ try {
257
+ outputPaths = getEmittedArtifactPaths(contractConfig.output);
258
+ } catch (error) {
259
+ throw errorContractConfigMissing({ why: error instanceof Error ? error.message : String(error) });
260
+ }
261
+ const { jsonPath: outputJsonPath, dtsPath: outputDtsPath } = outputPaths;
262
+ return queueEmitByOutput(outputJsonPath, async () => {
263
+ const stack = createControlStack(config);
264
+ const sourceContext = {
265
+ composedExtensionPacks: stack.extensionPacks.map((p) => p.id),
266
+ scalarTypeDescriptors: stack.scalarTypeDescriptors,
267
+ authoringContributions: stack.authoringContributions,
268
+ codecLookup: stack.codecLookup,
269
+ controlMutationDefaults: stack.controlMutationDefaults,
270
+ resolvedInputs: contractConfig.source.inputs ?? []
271
+ };
272
+ startSpan(onProgress, "resolveSource", "Resolving contract source...");
273
+ let providerResult;
274
+ try {
275
+ providerResult = await unlessAborted(contractConfig.source.load(sourceContext));
276
+ } catch (error) {
277
+ endSpan(onProgress, "resolveSource", "error");
278
+ if (signal.aborted || isRecord(error) && error["name"] === "AbortError") throw error;
279
+ throw failedToResolveContractSource(error instanceof Error ? error.message : String(error), "Ensure contract.source.load resolves to ok(Contract) or returns structured diagnostics.");
280
+ }
281
+ const validatedContract = validateProviderResult(providerResult);
282
+ if (!validatedContract.ok) {
283
+ endSpan(onProgress, "resolveSource", "error");
284
+ throw validatedContract.error;
285
+ }
286
+ endSpan(onProgress, "resolveSource", "ok");
287
+ startSpan(onProgress, "emit", "Emitting contract...");
288
+ let emitResult;
289
+ try {
290
+ const familyInstance = config.family.create(stack);
291
+ const rawComponents = [
292
+ config.target,
293
+ config.adapter,
294
+ ...config.extensionPacks ?? []
295
+ ];
296
+ const frameworkComponents = assertFrameworkComponentsCompatible(config.family.familyId, config.target.targetId, rawComponents);
297
+ const enrichedIR = enrichContract(validatedContract.value, frameworkComponents);
298
+ familyInstance.validateContract(enrichedIR);
299
+ emitResult = await unlessAborted(emit(enrichedIR, stack, config.family.emission, { outputJsonPath }));
300
+ } catch (error) {
301
+ endSpan(onProgress, "emit", "error");
302
+ throw error;
303
+ }
304
+ endSpan(onProgress, "emit", "ok");
305
+ await unlessAborted(mkdir(dirname(outputJsonPath), { recursive: true }));
306
+ await publishContractArtifactPair({
307
+ outputJsonPath,
308
+ outputDtsPath,
309
+ contractJson: emitResult.contractJson,
310
+ contractDts: emitResult.contractDts,
311
+ publicationToken: String(process.hrtime.bigint())
312
+ });
313
+ const validationWarning = validateContractDeps(emitResult.contractDts, dirname(outputDtsPath)).warning;
314
+ return {
315
+ storageHash: emitResult.storageHash,
316
+ ...ifDefined("executionHash", emitResult.executionHash),
317
+ profileHash: emitResult.profileHash,
318
+ files: {
319
+ json: outputJsonPath,
320
+ dts: outputDtsPath
321
+ },
322
+ ...ifDefined("validationWarning", validationWarning)
323
+ };
324
+ });
325
+ }
326
+
327
+ //#endregion
328
+ export { disposeEmitQueue as n, executeContractEmit as t };
329
+ //# sourceMappingURL=contract-emit-RZBWzkop.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-emit-RZBWzkop.mjs","names":["isRecord","replaced: PublishEntry[]","resolve","missing: string[]","EMIT_ACTION: ControlActionName","issues: { readonly kind: string; readonly message: string }[]","outputPaths: ReturnType<typeof getEmittedArtifactPaths>","providerResult: Awaited<ReturnType<typeof contractConfig.source.load>>","emitResult: Awaited<ReturnType<typeof emit>>"],"sources":["../src/utils/emit-queue.ts","../src/utils/publish-contract-artifact-pair.ts","../src/utils/validate-contract-deps.ts","../src/control-api/operations/contract-emit.ts"],"sourcesContent":["/**\n * Per-output FIFO queue for `executeContractEmit`.\n *\n * Ensures that at most one emit (load → resolve source → emit bytes → publish)\n * runs per output JSON path at a time. Concurrent calls for the same path\n * line up behind the in-flight one and run in submission order; the user-visible\n * outcome is \"last submission wins on disk\" without any supersession bookkeeping.\n *\n * Long-lived hosts (Vite dev server, watch CLIs) must call `disposeEmitQueue`\n * when they stop publishing to a path, otherwise the module-global `Map`\n * accumulates one entry per unique output path for the lifetime of the process.\n */\nconst emitQueues = new Map<string, Promise<unknown>>();\n\nexport function queueEmitByOutput<T>(outputJsonPath: string, action: () => Promise<T>): Promise<T> {\n const previous = emitQueues.get(outputJsonPath) ?? Promise.resolve();\n // Continue regardless of the previous task's outcome — a failed emit must not\n // block subsequent ones. The current task's outcome propagates via `next`.\n const next = previous.then(action, action);\n emitQueues.set(outputJsonPath, next);\n return next;\n}\n\nexport function disposeEmitQueue(outputJsonPath: string): void {\n emitQueues.delete(outputJsonPath);\n}\n","import { readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'pathe';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction createTempArtifactPath(path: string, publicationToken: string, phase: string): string {\n return join(dirname(path), `.${basename(path)}.${process.pid}.${publicationToken}.${phase}.tmp`);\n}\n\ntype PreviousArtifact = { readonly content: string } | 'remove';\n\nasync function readExistingArtifact(path: string): Promise<PreviousArtifact> {\n try {\n return { content: await readFile(path, 'utf-8') };\n } catch (error) {\n if (isRecord(error) && error['code'] === 'ENOENT') {\n return 'remove';\n }\n throw error;\n }\n}\n\nasync function restoreArtifact(\n path: string,\n previous: PreviousArtifact,\n publicationToken: string,\n): Promise<void> {\n if (previous === 'remove') {\n await rm(path, { force: true });\n return;\n }\n\n const restorePath = createTempArtifactPath(path, publicationToken, 'rollback');\n await writeFile(restorePath, previous.content, 'utf-8');\n try {\n await rename(restorePath, path);\n } finally {\n await rm(restorePath, { force: true });\n }\n}\n\ninterface PublishEntry {\n readonly tempPath: string;\n readonly outputPath: string;\n readonly previous: PreviousArtifact;\n}\n\nfunction withRollbackFailureCause(error: unknown, rollbackFailures: readonly unknown[]): Error {\n const rollbackCause = new AggregateError(\n rollbackFailures,\n 'Failed to restore published artifacts',\n );\n\n if (error instanceof Error) {\n Object.defineProperty(error, 'cause', {\n value: rollbackCause,\n configurable: true,\n writable: true,\n });\n return error;\n }\n\n return new Error(String(error), { cause: rollbackCause });\n}\n\nasync function publishPairWithRollback(\n entries: readonly PublishEntry[],\n publicationToken: string,\n): Promise<void> {\n const replaced: PublishEntry[] = [];\n try {\n for (const entry of entries) {\n await rename(entry.tempPath, entry.outputPath);\n replaced.push(entry);\n }\n } catch (error) {\n const rollbackResults = await Promise.allSettled(\n replaced.map((entry) => restoreArtifact(entry.outputPath, entry.previous, publicationToken)),\n );\n const rollbackFailures = rollbackResults.flatMap((result) =>\n result.status === 'rejected' ? [result.reason] : [],\n );\n\n if (rollbackFailures.length > 0) {\n throw withRollbackFailureCause(error, rollbackFailures);\n }\n\n throw error;\n }\n}\n\nexport async function publishContractArtifactPair({\n outputJsonPath,\n outputDtsPath,\n contractJson,\n contractDts,\n publicationToken,\n beforePublish,\n}: {\n readonly outputJsonPath: string;\n readonly outputDtsPath: string;\n readonly contractJson: string;\n readonly contractDts: string;\n readonly publicationToken: string;\n readonly beforePublish?: () => Promise<boolean> | boolean;\n}): Promise<boolean> {\n const tempJsonPath = createTempArtifactPath(outputJsonPath, publicationToken, 'next');\n const tempDtsPath = createTempArtifactPath(outputDtsPath, publicationToken, 'next');\n\n try {\n await writeFile(tempJsonPath, contractJson, 'utf-8');\n await writeFile(tempDtsPath, contractDts, 'utf-8');\n\n if ((await beforePublish?.()) === false) {\n return false;\n }\n\n const previousJson = await readExistingArtifact(outputJsonPath);\n const previousDts = await readExistingArtifact(outputDtsPath);\n\n await publishPairWithRollback(\n [\n { tempPath: tempDtsPath, outputPath: outputDtsPath, previous: previousDts },\n { tempPath: tempJsonPath, outputPath: outputJsonPath, previous: previousJson },\n ],\n publicationToken,\n );\n return true;\n } finally {\n await Promise.allSettled([rm(tempJsonPath, { force: true }), rm(tempDtsPath, { force: true })]);\n }\n}\n","import { createRequire } from 'node:module';\n\nconst IMPORT_PATTERN = /import\\s+type\\s+.*?\\s+from\\s+['\"](@[^/]+\\/[^/'\"]+)/g;\n\nexport function extractPackageSpecifiers(dtsContent: string): string[] {\n const packages = new Set<string>();\n for (const match of dtsContent.matchAll(IMPORT_PATTERN)) {\n const pkg = match[1];\n if (pkg) packages.add(pkg);\n }\n return [...packages];\n}\n\nexport interface ContractDepsValidation {\n readonly missing: readonly string[];\n readonly warning?: string;\n}\n\nexport function validateContractDeps(\n dtsContent: string,\n projectRoot: string,\n): ContractDepsValidation {\n const packages = extractPackageSpecifiers(dtsContent);\n const resolve = createRequire(`${projectRoot}/package.json`);\n\n const missing: string[] = [];\n for (const pkg of packages) {\n try {\n resolve.resolve(`${pkg}/package.json`);\n } catch {\n missing.push(pkg);\n }\n }\n\n if (missing.length === 0) {\n return { missing };\n }\n\n const list = missing.map((p) => ` - ${p}`).join('\\n');\n const warning = [\n 'contract.d.ts imports types from packages that are not installed:',\n list,\n '',\n 'Install them with your package manager:',\n ...missing.map((p) => ` ${p}`),\n ].join('\\n');\n\n return { missing, warning };\n}\n","import { mkdir } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { emit, getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { abortable } from '@prisma-next/utils/abortable';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { dirname } from 'pathe';\nimport { loadConfig } from '../../config-loader';\nimport { errorContractConfigMissing, errorRuntime } from '../../utils/cli-errors';\nimport { queueEmitByOutput } from '../../utils/emit-queue';\nimport { assertFrameworkComponentsCompatible } from '../../utils/framework-components';\nimport { publishContractArtifactPair } from '../../utils/publish-contract-artifact-pair';\nimport { validateContractDeps } from '../../utils/validate-contract-deps';\nimport { enrichContract } from '../contract-enrichment';\nimport type {\n ContractEmitOptions,\n ContractEmitResult,\n ControlActionName,\n OnControlProgress,\n} from '../types';\n\nconst EMIT_ACTION: ControlActionName = 'emit';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction startSpan(onProgress: OnControlProgress | undefined, spanId: string, label: string): void {\n onProgress?.({ action: EMIT_ACTION, kind: 'spanStart', spanId, label });\n}\n\nfunction endSpan(\n onProgress: OnControlProgress | undefined,\n spanId: string,\n outcome: 'ok' | 'error',\n): void {\n onProgress?.({ action: EMIT_ACTION, kind: 'spanEnd', spanId, outcome });\n}\n\nfunction failedToResolveContractSource(why: string, fix: string, meta?: Record<string, unknown>) {\n return errorRuntime('Failed to resolve contract source', {\n why,\n fix,\n ...ifDefined('meta', meta),\n });\n}\n\ntype ValidatedProviderResult =\n | { readonly ok: true; readonly value: unknown }\n | { readonly ok: false; readonly error: ReturnType<typeof errorRuntime> };\n\nfunction diagnosticLocationSuffix(diagnostic: Record<string, unknown>): string {\n const sourceId = typeof diagnostic['sourceId'] === 'string' ? diagnostic['sourceId'] : undefined;\n const span = isRecord(diagnostic['span']) ? diagnostic['span'] : undefined;\n const start = span && isRecord(span['start']) ? span['start'] : undefined;\n const line = start && typeof start['line'] === 'number' ? start['line'] : undefined;\n const column = start && typeof start['column'] === 'number' ? start['column'] : undefined;\n if (sourceId && line !== undefined && column !== undefined) {\n return ` (${sourceId}:${line}:${column})`;\n }\n if (sourceId) {\n return ` (${sourceId})`;\n }\n return '';\n}\n\nfunction mapDiagnosticsToIssues(\n diagnostics: readonly unknown[],\n): ReadonlyArray<{ readonly kind: string; readonly message: string }> {\n const issues: { readonly kind: string; readonly message: string }[] = [];\n for (const raw of diagnostics) {\n if (!isRecord(raw)) continue;\n const code = typeof raw['code'] === 'string' ? raw['code'] : 'diagnostic';\n const message = typeof raw['message'] === 'string' ? raw['message'] : '';\n issues.push({ kind: code, message: `${message}${diagnosticLocationSuffix(raw)}` });\n }\n return issues;\n}\n\nfunction validateProviderResult(providerResult: unknown): ValidatedProviderResult {\n if (!isRecord(providerResult) || typeof providerResult['ok'] !== 'boolean') {\n return {\n ok: false,\n error: failedToResolveContractSource(\n 'Contract source provider returned malformed result shape.',\n 'Ensure contract.source.load resolves to ok(Contract) or notOk({ summary, diagnostics }).',\n ),\n };\n }\n\n if (providerResult['ok']) {\n if (!('value' in providerResult)) {\n return {\n ok: false,\n error: failedToResolveContractSource(\n 'Contract source provider returned malformed success result: missing value.',\n 'Ensure contract.source.load success payload is ok(Contract).',\n ),\n };\n }\n return { ok: true, value: providerResult['value'] };\n }\n\n const failure = providerResult['failure'];\n if (\n !isRecord(failure) ||\n typeof failure['summary'] !== 'string' ||\n !Array.isArray(failure['diagnostics'])\n ) {\n return {\n ok: false,\n error: failedToResolveContractSource(\n 'Contract source provider returned malformed failure result: expected summary and diagnostics.',\n 'Ensure contract.source.load failure payload is notOk({ summary, diagnostics, meta? }).',\n ),\n };\n }\n return {\n ok: false,\n error: failedToResolveContractSource(\n String(failure['summary']),\n 'Fix contract source diagnostics and return ok(Contract).',\n {\n diagnostics: failure['diagnostics'],\n issues: mapDiagnosticsToIssues(failure['diagnostics']),\n ...ifDefined('providerMeta', failure['meta']),\n },\n ),\n };\n}\n\n/**\n * Canonical contract emit operation.\n *\n * This is the SINGLE publication path used by both the CLI command\n * (`prisma-next contract emit`) and the Vite plugin\n * (`@prisma-next/vite-plugin-contract-emit`). New callers must go through this\n * function rather than re-implementing load → emit → publish.\n *\n * The whole flow (load config → resolve source → emit bytes → atomic publish)\n * is serialized per output JSON path via `queueEmitByOutput`. Concurrent calls\n * for the same output line up FIFO; the user-visible outcome is \"last\n * submission wins on disk\" without any supersession bookkeeping. Within a\n * single emit, `publishContractArtifactPair` stages temp files, renames\n * `contract.d.ts` before `contract.json`, and attempts to restore the previous\n * pair if either rename fails — so type-only consumers never observe a\n * mismatched pair.\n *\n * @throws {CliStructuredError} on config/source/validation problems\n * @throws {DOMException} `AbortError` if cancelled via `signal`\n */\nexport async function executeContractEmit(\n options: ContractEmitOptions,\n): Promise<ContractEmitResult> {\n const { configPath, signal = new AbortController().signal, onProgress } = options;\n const unlessAborted = abortable(signal);\n\n const config = await unlessAborted(loadConfig(configPath));\n\n if (!config.contract) {\n throw errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n });\n }\n\n const contractConfig = config.contract;\n\n if (!contractConfig.output) {\n throw errorContractConfigMissing({\n why: 'Contract config must have output path. This should not happen if defineConfig() was used.',\n });\n }\n\n if (typeof contractConfig.source?.load !== 'function') {\n throw errorContractConfigMissing({\n why: 'Contract config must include a valid source provider object',\n });\n }\n\n let outputPaths: ReturnType<typeof getEmittedArtifactPaths>;\n try {\n outputPaths = getEmittedArtifactPaths(contractConfig.output);\n } catch (error) {\n throw errorContractConfigMissing({\n why: error instanceof Error ? error.message : String(error),\n });\n }\n const { jsonPath: outputJsonPath, dtsPath: outputDtsPath } = outputPaths;\n\n return queueEmitByOutput(outputJsonPath, async () => {\n const stack = createControlStack(config);\n\n const sourceContext = {\n composedExtensionPacks: stack.extensionPacks.map((p) => p.id),\n scalarTypeDescriptors: stack.scalarTypeDescriptors,\n authoringContributions: stack.authoringContributions,\n codecLookup: stack.codecLookup,\n controlMutationDefaults: stack.controlMutationDefaults,\n resolvedInputs: contractConfig.source.inputs ?? [],\n };\n\n startSpan(onProgress, 'resolveSource', 'Resolving contract source...');\n let providerResult: Awaited<ReturnType<typeof contractConfig.source.load>>;\n try {\n providerResult = await unlessAborted(contractConfig.source.load(sourceContext));\n } catch (error) {\n endSpan(onProgress, 'resolveSource', 'error');\n if (signal.aborted || (isRecord(error) && error['name'] === 'AbortError')) {\n throw error;\n }\n throw failedToResolveContractSource(\n error instanceof Error ? error.message : String(error),\n 'Ensure contract.source.load resolves to ok(Contract) or returns structured diagnostics.',\n );\n }\n\n const validatedContract = validateProviderResult(providerResult);\n if (!validatedContract.ok) {\n endSpan(onProgress, 'resolveSource', 'error');\n throw validatedContract.error;\n }\n endSpan(onProgress, 'resolveSource', 'ok');\n\n startSpan(onProgress, 'emit', 'Emitting contract...');\n let emitResult: Awaited<ReturnType<typeof emit>>;\n try {\n const familyInstance = config.family.create(stack);\n const rawComponents = [config.target, config.adapter, ...(config.extensionPacks ?? [])];\n const frameworkComponents = assertFrameworkComponentsCompatible(\n config.family.familyId,\n config.target.targetId,\n rawComponents,\n );\n const enrichedIR = enrichContract(validatedContract.value as Contract, frameworkComponents);\n familyInstance.validateContract(enrichedIR);\n emitResult = await unlessAborted(\n emit(enrichedIR, stack, config.family.emission, { outputJsonPath }),\n );\n } catch (error) {\n endSpan(onProgress, 'emit', 'error');\n throw error;\n }\n endSpan(onProgress, 'emit', 'ok');\n\n await unlessAborted(mkdir(dirname(outputJsonPath), { recursive: true }));\n await publishContractArtifactPair({\n outputJsonPath,\n outputDtsPath,\n contractJson: emitResult.contractJson,\n contractDts: emitResult.contractDts,\n publicationToken: String(process.hrtime.bigint()),\n });\n\n const validationWarning = validateContractDeps(\n emitResult.contractDts,\n dirname(outputDtsPath),\n ).warning;\n\n return {\n storageHash: emitResult.storageHash,\n ...ifDefined('executionHash', emitResult.executionHash),\n profileHash: emitResult.profileHash,\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n ...ifDefined('validationWarning', validationWarning),\n };\n });\n}\n"],"mappings":"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"}