@prisma-next/cli 0.16.0-dev.3 → 0.16.0-dev.30

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 (162) hide show
  1. package/README.md +44 -45
  2. package/dist/cli.mjs +13 -13
  3. package/dist/{client-KuBQftxz.mjs → client-CMusjGV5.mjs} +24 -25
  4. package/dist/client-CMusjGV5.mjs.map +1 -0
  5. package/dist/{command-helpers-Cpq44aVa.mjs → command-helpers-CVn3U9Uz.mjs} +12 -4
  6. package/dist/command-helpers-CVn3U9Uz.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.d.mts.map +1 -1
  10. package/dist/commands/db-init.mjs +5 -4
  11. package/dist/commands/db-init.mjs.map +1 -1
  12. package/dist/commands/db-schema.mjs +3 -3
  13. package/dist/commands/db-sign.d.mts.map +1 -1
  14. package/dist/commands/db-sign.mjs +9 -11
  15. package/dist/commands/db-sign.mjs.map +1 -1
  16. package/dist/commands/db-update.d.mts.map +1 -1
  17. package/dist/commands/db-update.mjs +11 -13
  18. package/dist/commands/db-update.mjs.map +1 -1
  19. package/dist/commands/db-verify.mjs +1 -1
  20. package/dist/commands/migrate.d.mts +1 -1
  21. package/dist/commands/migrate.d.mts.map +1 -1
  22. package/dist/commands/migrate.mjs +13 -13
  23. package/dist/commands/migrate.mjs.map +1 -1
  24. package/dist/commands/migration-check.d.mts +4 -2
  25. package/dist/commands/migration-check.d.mts.map +1 -1
  26. package/dist/commands/migration-check.mjs +1 -1
  27. package/dist/commands/migration-graph.d.mts +1 -1
  28. package/dist/commands/migration-graph.mjs +4 -4
  29. package/dist/commands/migration-list.d.mts +1 -1
  30. package/dist/commands/migration-list.d.mts.map +1 -1
  31. package/dist/commands/migration-list.mjs +1 -1
  32. package/dist/commands/migration-log.d.mts +1 -1
  33. package/dist/commands/migration-log.mjs +1 -1
  34. package/dist/commands/migration-new.d.mts.map +1 -1
  35. package/dist/commands/migration-new.mjs +16 -40
  36. package/dist/commands/migration-new.mjs.map +1 -1
  37. package/dist/commands/migration-plan.d.mts +3 -4
  38. package/dist/commands/migration-plan.d.mts.map +1 -1
  39. package/dist/commands/migration-plan.mjs +1 -1
  40. package/dist/commands/migration-show.mjs +5 -5
  41. package/dist/commands/migration-show.mjs.map +1 -1
  42. package/dist/commands/migration-status.d.mts +1 -1
  43. package/dist/commands/migration-status.d.mts.map +1 -1
  44. package/dist/commands/migration-status.mjs +1 -1
  45. package/dist/commands/ref.d.mts +1 -1
  46. package/dist/commands/ref.d.mts.map +1 -1
  47. package/dist/commands/ref.mjs +13 -18
  48. package/dist/commands/ref.mjs.map +1 -1
  49. package/dist/commands/telemetry/index.mjs +1 -1
  50. package/dist/contract-at-errors-C-l4-JEY.mjs +36 -0
  51. package/dist/contract-at-errors-C-l4-JEY.mjs.map +1 -0
  52. package/dist/{contract-emit-cJQBlvGb.mjs → contract-emit-CfIbTnsR.mjs} +6 -7
  53. package/dist/{contract-emit-cJQBlvGb.mjs.map → contract-emit-CfIbTnsR.mjs.map} +1 -1
  54. package/dist/{contract-emit-CgnXSANN.mjs → contract-emit-PaY3qRdN.mjs} +3 -3
  55. package/dist/{contract-emit-CgnXSANN.mjs.map → contract-emit-PaY3qRdN.mjs.map} +1 -1
  56. package/dist/{contract-enrichment-gn9sWbPw.mjs → contract-enrichment-JUhLv-BX.mjs} +8 -8
  57. package/dist/{contract-enrichment-gn9sWbPw.mjs.map → contract-enrichment-JUhLv-BX.mjs.map} +1 -1
  58. package/dist/{contract-infer-Cg8evbeg.mjs → contract-infer-DCju2fTk.mjs} +3 -3
  59. package/dist/{contract-infer-Cg8evbeg.mjs.map → contract-infer-DCju2fTk.mjs.map} +1 -1
  60. package/dist/{contract-space-aggregate-loader-D_3VeHVb.mjs → contract-space-aggregate-loader-B6E9LGa6.mjs} +14 -14
  61. package/dist/contract-space-aggregate-loader-B6E9LGa6.mjs.map +1 -0
  62. package/dist/{db-verify-BEclUzki.mjs → db-verify-B_dKu6Yp.mjs} +5 -5
  63. package/dist/db-verify-B_dKu6Yp.mjs.map +1 -0
  64. package/dist/exports/control-api.d.mts +4 -4
  65. package/dist/exports/control-api.d.mts.map +1 -1
  66. package/dist/exports/control-api.mjs +3 -3
  67. package/dist/exports/index.mjs +2 -2
  68. package/dist/exports/init-output.d.mts.map +1 -1
  69. package/dist/exports/init-output.mjs +1 -1
  70. package/dist/{format-DAUAZqPt.mjs → format-cCyDfmRE.mjs} +8 -7
  71. package/dist/format-cCyDfmRE.mjs.map +1 -0
  72. package/dist/{framework-components-CnbUbiJw.mjs → framework-components-DUN-TYDg.mjs} +3 -3
  73. package/dist/framework-components-DUN-TYDg.mjs.map +1 -0
  74. package/dist/{init-C3JhkHg-.mjs → init-C9U3ffHH.mjs} +55 -47
  75. package/dist/init-C9U3ffHH.mjs.map +1 -0
  76. package/dist/{inspect-live-schema-CX7EA5C3.mjs → inspect-live-schema-DHXE7skX.mjs} +4 -4
  77. package/dist/{inspect-live-schema-CX7EA5C3.mjs.map → inspect-live-schema-DHXE7skX.mjs.map} +1 -1
  78. package/dist/{migration-check-MHT3w7_v.mjs → migration-check-W5XEx4d-.mjs} +58 -30
  79. package/dist/migration-check-W5XEx4d-.mjs.map +1 -0
  80. package/dist/{migration-command-scaffold-CRyYrHZ9.mjs → migration-command-scaffold-hI5cnoGe.mjs} +4 -4
  81. package/dist/{migration-command-scaffold-CRyYrHZ9.mjs.map → migration-command-scaffold-hI5cnoGe.mjs.map} +1 -1
  82. package/dist/{migration-graph-command-render-B83xrnNy.mjs → migration-graph-command-render-DgQg5App.mjs} +3 -3
  83. package/dist/migration-graph-command-render-DgQg5App.mjs.map +1 -0
  84. package/dist/{migration-list-BAKujUjh.mjs → migration-list-ClkEaoL8.mjs} +6 -6
  85. package/dist/migration-list-ClkEaoL8.mjs.map +1 -0
  86. package/dist/{migration-log-C_xam2HZ.mjs → migration-log-CjafbZ2Z.mjs} +5 -5
  87. package/dist/{migration-log-C_xam2HZ.mjs.map → migration-log-CjafbZ2Z.mjs.map} +1 -1
  88. package/dist/{migration-path-target-DpPTsRCg.mjs → migration-path-target-C0TQuV5n.mjs} +2 -2
  89. package/dist/{migration-path-target-DpPTsRCg.mjs.map → migration-path-target-C0TQuV5n.mjs.map} +1 -1
  90. package/dist/{migration-plan-CreSVtWZ.mjs → migration-plan-Pc4hCF1H.mjs} +64 -74
  91. package/dist/migration-plan-Pc4hCF1H.mjs.map +1 -0
  92. package/dist/{migration-status-YgEvXf-u.mjs → migration-status-CqAdRzs8.mjs} +13 -12
  93. package/dist/migration-status-CqAdRzs8.mjs.map +1 -0
  94. package/dist/{output-mEQ74_nd.mjs → output-DWNYqZGc.mjs} +5 -6
  95. package/dist/output-DWNYqZGc.mjs.map +1 -0
  96. package/dist/{ref-advancement-BkXlikCA.mjs → ref-advancement-BCz7X7qJ.mjs} +13 -6
  97. package/dist/ref-advancement-BCz7X7qJ.mjs.map +1 -0
  98. package/dist/{telemetry-DVr6RFnq.mjs → telemetry-BEyNMfco.mjs} +2 -2
  99. package/dist/{telemetry-DVr6RFnq.mjs.map → telemetry-BEyNMfco.mjs.map} +1 -1
  100. package/dist/{types-D4r_HI9-.d.mts → types-DgXprE3w.d.mts} +3 -3
  101. package/dist/types-DgXprE3w.d.mts.map +1 -0
  102. package/dist/{verify-CgDVZjhc.mjs → verify-C4RazDE1.mjs} +2 -2
  103. package/dist/{verify-CgDVZjhc.mjs.map → verify-C4RazDE1.mjs.map} +1 -1
  104. package/package.json +21 -21
  105. package/src/commands/db-init.ts +1 -0
  106. package/src/commands/db-sign.ts +7 -5
  107. package/src/commands/db-update.ts +14 -6
  108. package/src/commands/db-verify.ts +1 -1
  109. package/src/commands/format.ts +1 -1
  110. package/src/commands/init/hygiene-gitattributes.ts +37 -21
  111. package/src/commands/init/init.ts +6 -6
  112. package/src/commands/init/output.ts +4 -5
  113. package/src/commands/init/reinit-cleanup.ts +16 -17
  114. package/src/commands/inspect-live-schema.ts +1 -1
  115. package/src/commands/migrate.ts +6 -5
  116. package/src/commands/migration-check.ts +72 -34
  117. package/src/commands/migration-list.ts +1 -5
  118. package/src/commands/migration-log.ts +1 -1
  119. package/src/commands/migration-new.ts +17 -41
  120. package/src/commands/migration-plan.ts +64 -88
  121. package/src/commands/migration-show.ts +2 -2
  122. package/src/commands/migration-status.ts +6 -7
  123. package/src/commands/ref.ts +19 -14
  124. package/src/control-api/client.ts +7 -8
  125. package/src/control-api/contract-enrichment.ts +7 -7
  126. package/src/control-api/operations/contract-emit.ts +2 -3
  127. package/src/control-api/operations/db-init.ts +3 -3
  128. package/src/control-api/operations/db-run.ts +6 -6
  129. package/src/control-api/operations/db-update.ts +2 -2
  130. package/src/control-api/operations/db-verify.ts +4 -4
  131. package/src/control-api/operations/format.ts +5 -4
  132. package/src/control-api/operations/migrate.ts +3 -3
  133. package/src/control-api/types.ts +1 -1
  134. package/src/utils/cli-errors.ts +15 -7
  135. package/src/utils/contract-at-errors.ts +13 -22
  136. package/src/utils/contract-space-aggregate-loader.ts +8 -8
  137. package/src/utils/contract-space-seed-phase.ts +11 -9
  138. package/src/utils/extension-pack-inputs.ts +8 -8
  139. package/src/utils/formatters/migration-graph-labels.ts +1 -2
  140. package/src/utils/formatters/migration-list-data-column.ts +1 -2
  141. package/src/utils/framework-components.ts +9 -9
  142. package/src/utils/integrity-violation-to-check-failure.ts +3 -3
  143. package/src/utils/migration-command-scaffold.ts +1 -1
  144. package/src/utils/plan-resolution.ts +7 -10
  145. package/src/utils/ref-advancement.ts +22 -3
  146. package/dist/client-KuBQftxz.mjs.map +0 -1
  147. package/dist/command-helpers-Cpq44aVa.mjs.map +0 -1
  148. package/dist/contract-at-errors-D9gEjYtg.mjs +0 -42
  149. package/dist/contract-at-errors-D9gEjYtg.mjs.map +0 -1
  150. package/dist/contract-space-aggregate-loader-D_3VeHVb.mjs.map +0 -1
  151. package/dist/db-verify-BEclUzki.mjs.map +0 -1
  152. package/dist/format-DAUAZqPt.mjs.map +0 -1
  153. package/dist/framework-components-CnbUbiJw.mjs.map +0 -1
  154. package/dist/init-C3JhkHg-.mjs.map +0 -1
  155. package/dist/migration-check-MHT3w7_v.mjs.map +0 -1
  156. package/dist/migration-graph-command-render-B83xrnNy.mjs.map +0 -1
  157. package/dist/migration-list-BAKujUjh.mjs.map +0 -1
  158. package/dist/migration-plan-CreSVtWZ.mjs.map +0 -1
  159. package/dist/migration-status-YgEvXf-u.mjs.map +0 -1
  160. package/dist/output-mEQ74_nd.mjs.map +0 -1
  161. package/dist/ref-advancement-BkXlikCA.mjs.map +0 -1
  162. package/dist/types-D4r_HI9-.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"verify-CgDVZjhc.mjs","names":[],"sources":["../src/utils/formatters/verify.ts"],"sourcesContent":["import type {\n CoreSchemaView,\n ExpectationFailureReason,\n IntrospectSchemaResult,\n SchemaDiffIssue,\n SchemaTreeNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport { issueOutcome } from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { bold, cyan, dim, green, magenta, red, yellow } from 'colorette';\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim, isVerbose } from './helpers';\n\n/** Human-readable label for each outcome, prefixed onto an issue's message for display. */\nconst OUTCOME_LABEL: Record<ExpectationFailureReason, string> = {\n 'not-found': 'missing',\n 'not-expected': 'extra',\n 'not-equal': 'mismatch',\n};\n\n/**\n * The issue's display text: its own path, prefixed with a human label for\n * why it's flagged. Turning the presence-derived outcome (and the path) into\n * prose is this formatter's job, not the differ's — the differ's issue is\n * data (`path` + nodes), not prose.\n */\nfunction formatIssueMessage(issue: SchemaDiffIssue): string {\n return `${OUTCOME_LABEL[issueOutcome(issue)]}: ${issue.path.join('/')}`;\n}\n\n// ============================================================================\n// Verify Output Formatters\n// ============================================================================\n\nexport interface DbVerifyCommandSuccessResult {\n readonly ok: true;\n readonly mode: 'full' | 'marker-only';\n readonly summary: string;\n readonly contract: VerifyDatabaseResult['contract'];\n readonly marker?: VerifyDatabaseResult['marker'];\n readonly target: VerifyDatabaseResult['target'];\n readonly missingCodecs?: VerifyDatabaseResult['missingCodecs'];\n readonly codecCoverageSkipped?: VerifyDatabaseResult['codecCoverageSkipped'];\n readonly schema?: {\n readonly summary: string;\n readonly strict: boolean;\n /**\n * Warn-graded finding messages (observed-policy drift). Informational —\n * present on a passing verify; the full-mode result summarizes them as a\n * flat message list.\n */\n readonly warnings?: readonly string[];\n };\n /**\n * Live element names no contract space declares. In full success this is\n * only ever non-empty in lenient mode — strict mode fails on it — and is\n * rendered informationally.\n */\n readonly unclaimed?: readonly string[];\n readonly warning?: string;\n readonly meta?:\n | (NonNullable<VerifyDatabaseResult['meta']> & {\n readonly schemaVerification: 'performed' | 'skipped';\n })\n | {\n readonly schemaVerification: 'performed' | 'skipped';\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for database verify.\n */\nexport function formatVerifyOutput(\n result: DbVerifyCommandSuccessResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n const verificationMode =\n result.mode === 'full'\n ? `marker + schema${result.schema?.strict ? ' (strict)' : ' (tolerant)'}`\n : 'marker only (--marker-only)';\n\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n lines.push(`${formatDimText(` verification: ${verificationMode}`)}`);\n lines.push(`${formatDimText(` storageHash: ${result.contract.storageHash}`)}`);\n if (result.contract.profileHash) {\n lines.push(`${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n if (result.schema?.warnings && result.schema.warnings.length > 0) {\n lines.push('');\n lines.push(formatYellow('Schema warnings:'));\n for (const message of result.schema.warnings) {\n lines.push(` ${formatYellow('⚠')} ${message}`);\n }\n }\n\n if (result.unclaimed && result.unclaimed.length > 0) {\n lines.push('');\n lines.push(formatYellow('Unclaimed elements (declared by no contract):'));\n for (const name of result.unclaimed) {\n lines.push(` ${formatYellow('⚠')} ${name}`);\n }\n }\n\n if (result.warning) {\n lines.push('');\n lines.push(`${formatYellow('⚠')} ${result.warning}`);\n }\n\n if (isVerbose(flags, 1)) {\n if (result.codecCoverageSkipped) {\n lines.push(\n `${formatDimText(' Codec coverage check skipped (helper returned no supported types)')}`,\n );\n }\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database verify.\n */\nexport function formatVerifyJson(result: DbVerifyCommandSuccessResult): string {\n const output = {\n ok: result.ok,\n summary: result.summary,\n mode: result.mode,\n contract: result.contract,\n ...ifDefined('marker', result.marker),\n target: result.target,\n ...ifDefined('missingCodecs', result.missingCodecs),\n ...ifDefined('codecCoverageSkipped', result.codecCoverageSkipped),\n ...ifDefined('schema', result.schema),\n unclaimed: result.unclaimed ?? [],\n ...ifDefined('warning', result.warning),\n ...ifDefined('meta', result.meta),\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Formats JSON output for database introspection.\n */\nexport function formatIntrospectJson(result: IntrospectSchemaResult<unknown>): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Renders a schema tree structure from CoreSchemaView.\n * Status-glyph tree styling shared with the retired verification-tree renderer.\n */\nfunction renderSchemaTree(\n node: SchemaTreeNode,\n flags: GlobalFlags,\n options: {\n readonly isLast: boolean;\n readonly prefix: string;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly isRoot?: boolean;\n },\n): string[] {\n const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;\n const lines: string[] = [];\n\n // Format node label with color based on kind (matching schema-verify style)\n let formattedLabel: string = node.label;\n\n if (useColor) {\n switch (node.kind) {\n case 'root':\n formattedLabel = bold(node.label);\n break;\n case 'entity': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.label.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n // Fallback: color entire label with cyan\n formattedLabel = cyan(node.label);\n }\n break;\n }\n case 'collection': {\n // \"columns\" grouping node - dim the label\n formattedLabel = dim(node.label);\n break;\n }\n case 'field': {\n // Parse column name format: \"columnName: typeDisplay (nullability)\"\n // Color code: column name (cyan), type (default), nullability (dim)\n const columnMatch = node.label.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"typeDisplay (nullability)\"\n const typeMatch = rest.match(/^([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2]) {\n const typeDisplay = typeMatch[1];\n const nullability = typeMatch[2];\n formattedLabel = `${cyan(columnName)}: ${typeDisplay} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.label;\n }\n break;\n }\n case 'index': {\n // Parse index/unique constraint/primary key formats\n // \"primary key: columnName\" -> dim \"primary key\", cyan columnName\n const pkMatch = node.label.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n // \"unique name\" -> dim \"unique\", cyan \"name\"\n const uniqueMatch = node.label.match(/^unique\\s+(.+)$/);\n if (uniqueMatch?.[1]) {\n const name = uniqueMatch[1];\n formattedLabel = `${dim('unique')} ${cyan(name)}`;\n } else {\n // \"index name\" or \"unique index name\" -> dim label prefix, cyan name\n const indexMatch = node.label.match(/^(unique\\s+)?index\\s+(.+)$/);\n if (indexMatch?.[2]) {\n const indexPrefix = indexMatch[1] ? `${dim('unique')} ` : '';\n const name = indexMatch[2];\n formattedLabel = `${indexPrefix}${dim('index')} ${cyan(name)}`;\n } else {\n formattedLabel = dim(node.label);\n }\n }\n }\n break;\n }\n case 'dependency': {\n // Parse extension message formats similar to schema-verify\n // \"extensionName extension is enabled\" -> cyan extensionName, dim rest\n const extMatch = node.label.match(/^([^\\s]+)\\s+(extension is enabled)$/);\n if (extMatch?.[1] && extMatch[2]) {\n const extName = extMatch[1];\n const rest = extMatch[2];\n formattedLabel = `${cyan(extName)} ${dim(rest)}`;\n } else {\n // Fallback: color entire label with magenta\n formattedLabel = magenta(node.label);\n }\n break;\n }\n default:\n formattedLabel = node.label;\n break;\n }\n }\n\n // Root node renders without tree characters or prefix\n if (isRoot) {\n lines.push(formattedLabel);\n } else {\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${formatDimText(treeChar)}─ `;\n lines.push(`${prefix}${treePrefix}${formattedLabel}`);\n }\n\n // Render children if present\n if (node.children && node.children.length > 0) {\n const childPrefix = isRoot ? '' : `${prefix}${isLast ? ' ' : `${formatDimText('│')} `}`;\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n if (!child) continue;\n const isLastChild = i === node.children.length - 1;\n const childLines = renderSchemaTree(child, flags, {\n isLast: isLastChild,\n prefix: childPrefix,\n useColor,\n formatDimText,\n isRoot: false,\n });\n lines.push(...childLines);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats human-readable output for database introspection.\n */\nexport function formatIntrospectOutput(\n result: IntrospectSchemaResult<unknown>,\n schemaView: CoreSchemaView | undefined,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (schemaView) {\n // Render tree structure - root node is special (no tree characters)\n const treeLines = renderSchemaTree(schemaView.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n lines.push(...treeLines);\n } else {\n // Fallback: print summary when toSchemaView is not available\n lines.push(`✔ ${result.summary}`);\n if (isVerbose(flags, 1)) {\n lines.push(` Target: ${result.target.familyId}/${result.target.id}`);\n if (result.meta?.dbUrl) {\n lines.push(` Database: ${result.meta.dbUrl}`);\n }\n }\n }\n\n // Add timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats human-readable output for database schema verification.\n */\nexport function formatSchemaVerifyOutput(\n result: VerifyDatabaseSchemaResult,\n flags: GlobalFlags,\n unclaimed: readonly string[] = [],\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatRed = createColorFormatter(useColor, red);\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n const issueMessages = result.schema.issues.map(formatIssueMessage);\n if (issueMessages.length > 0) {\n lines.push(formatRed('Schema issues:'));\n for (const message of issueMessages) {\n lines.push(` ${formatRed('✖')} ${message}`);\n }\n }\n\n const warningMessages = (result.schema.warnings?.issues ?? []).map(formatIssueMessage);\n if (warningMessages.length > 0) {\n if (lines.length > 0) lines.push('');\n lines.push(formatYellow('Schema warnings:'));\n for (const message of warningMessages) {\n lines.push(` ${formatYellow('⚠')} ${message}`);\n }\n }\n\n if (unclaimed.length > 0) {\n const strict = result.meta?.strict ?? false;\n if (lines.length > 0) lines.push('');\n lines.push(\n (strict ? formatRed : formatYellow)('Unclaimed elements (declared by no contract):'),\n );\n for (const name of unclaimed) {\n lines.push(` ${(strict ? formatRed : formatYellow)(strict ? '✖' : '⚠')} ${name}`);\n }\n }\n\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n // Blank line before summary\n if (lines.length > 0) lines.push('');\n\n // Summary line at the end: verdict with status glyph\n if (result.ok) {\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n } else {\n const codeText = result.code ? ` (${result.code})` : '';\n lines.push(`${formatRed('✖')} ${result.summary}${codeText}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database schema verification. The unclaimed-elements\n * list is a top-level field alongside the combined result, reported once for\n * the whole database.\n */\nexport function formatSchemaVerifyJson(\n result: VerifyDatabaseSchemaResult,\n unclaimed: readonly string[] = [],\n): string {\n return JSON.stringify({ ...result, unclaimed }, null, 2);\n}\n\n// ============================================================================\n// Sign Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for database sign.\n */\nexport function formatSignOutput(result: SignDatabaseResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Main success message in white (not dimmed)\n lines.push(`${formatGreen('✔')} Database signed`);\n\n // Show from -> to hashes with clear labels\n const previousHash = result.marker.previous?.storageHash ?? 'none';\n const currentHash = result.contract.storageHash;\n\n lines.push(`${formatDimText(` from: ${previousHash}`)}`);\n lines.push(`${formatDimText(` to: ${currentHash}`)}`);\n\n if (isVerbose(flags, 1)) {\n if (result.contract.profileHash) {\n lines.push(`${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n if (result.marker.previous?.profileHash) {\n lines.push(\n `${formatDimText(` previous profileHash: ${result.marker.previous.profileHash}`)}`,\n );\n }\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database sign.\n */\nexport function formatSignJson(result: SignDatabaseResult): string {\n return JSON.stringify(result, null, 2);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"verify-C4RazDE1.mjs","names":[],"sources":["../src/utils/formatters/verify.ts"],"sourcesContent":["import type {\n CoreSchemaView,\n ExpectationFailureReason,\n IntrospectSchemaResult,\n SchemaDiffIssue,\n SchemaTreeNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport { issueOutcome } from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { bold, cyan, dim, green, magenta, red, yellow } from 'colorette';\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim, isVerbose } from './helpers';\n\n/** Human-readable label for each outcome, prefixed onto an issue's message for display. */\nconst OUTCOME_LABEL: Record<ExpectationFailureReason, string> = {\n 'not-found': 'missing',\n 'not-expected': 'extra',\n 'not-equal': 'mismatch',\n};\n\n/**\n * The issue's display text: its own path, prefixed with a human label for\n * why it's flagged. Turning the presence-derived outcome (and the path) into\n * prose is this formatter's job, not the differ's — the differ's issue is\n * data (`path` + nodes), not prose.\n */\nfunction formatIssueMessage(issue: SchemaDiffIssue): string {\n return `${OUTCOME_LABEL[issueOutcome(issue)]}: ${issue.path.join('/')}`;\n}\n\n// ============================================================================\n// Verify Output Formatters\n// ============================================================================\n\nexport interface DbVerifyCommandSuccessResult {\n readonly ok: true;\n readonly mode: 'full' | 'marker-only';\n readonly summary: string;\n readonly contract: VerifyDatabaseResult['contract'];\n readonly marker?: VerifyDatabaseResult['marker'];\n readonly target: VerifyDatabaseResult['target'];\n readonly missingCodecs?: VerifyDatabaseResult['missingCodecs'];\n readonly codecCoverageSkipped?: VerifyDatabaseResult['codecCoverageSkipped'];\n readonly schema?: {\n readonly summary: string;\n readonly strict: boolean;\n /**\n * Warn-graded finding messages (observed-policy drift). Informational —\n * present on a passing verify; the full-mode result summarizes them as a\n * flat message list.\n */\n readonly warnings?: readonly string[];\n };\n /**\n * Live element names no contract space declares. In full success this is\n * only ever non-empty in lenient mode — strict mode fails on it — and is\n * rendered informationally.\n */\n readonly unclaimed?: readonly string[];\n readonly warning?: string;\n readonly meta?:\n | (NonNullable<VerifyDatabaseResult['meta']> & {\n readonly schemaVerification: 'performed' | 'skipped';\n })\n | {\n readonly schemaVerification: 'performed' | 'skipped';\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for database verify.\n */\nexport function formatVerifyOutput(\n result: DbVerifyCommandSuccessResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n const verificationMode =\n result.mode === 'full'\n ? `marker + schema${result.schema?.strict ? ' (strict)' : ' (tolerant)'}`\n : 'marker only (--marker-only)';\n\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n lines.push(`${formatDimText(` verification: ${verificationMode}`)}`);\n lines.push(`${formatDimText(` storageHash: ${result.contract.storageHash}`)}`);\n if (result.contract.profileHash) {\n lines.push(`${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n if (result.schema?.warnings && result.schema.warnings.length > 0) {\n lines.push('');\n lines.push(formatYellow('Schema warnings:'));\n for (const message of result.schema.warnings) {\n lines.push(` ${formatYellow('⚠')} ${message}`);\n }\n }\n\n if (result.unclaimed && result.unclaimed.length > 0) {\n lines.push('');\n lines.push(formatYellow('Unclaimed elements (declared by no contract):'));\n for (const name of result.unclaimed) {\n lines.push(` ${formatYellow('⚠')} ${name}`);\n }\n }\n\n if (result.warning) {\n lines.push('');\n lines.push(`${formatYellow('⚠')} ${result.warning}`);\n }\n\n if (isVerbose(flags, 1)) {\n if (result.codecCoverageSkipped) {\n lines.push(\n `${formatDimText(' Codec coverage check skipped (helper returned no supported types)')}`,\n );\n }\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database verify.\n */\nexport function formatVerifyJson(result: DbVerifyCommandSuccessResult): string {\n const output = {\n ok: result.ok,\n summary: result.summary,\n mode: result.mode,\n contract: result.contract,\n ...ifDefined('marker', result.marker),\n target: result.target,\n ...ifDefined('missingCodecs', result.missingCodecs),\n ...ifDefined('codecCoverageSkipped', result.codecCoverageSkipped),\n ...ifDefined('schema', result.schema),\n unclaimed: result.unclaimed ?? [],\n ...ifDefined('warning', result.warning),\n ...ifDefined('meta', result.meta),\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Formats JSON output for database introspection.\n */\nexport function formatIntrospectJson(result: IntrospectSchemaResult<unknown>): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Renders a schema tree structure from CoreSchemaView.\n * Status-glyph tree styling shared with the retired verification-tree renderer.\n */\nfunction renderSchemaTree(\n node: SchemaTreeNode,\n flags: GlobalFlags,\n options: {\n readonly isLast: boolean;\n readonly prefix: string;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly isRoot?: boolean;\n },\n): string[] {\n const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;\n const lines: string[] = [];\n\n // Format node label with color based on kind (matching schema-verify style)\n let formattedLabel: string = node.label;\n\n if (useColor) {\n switch (node.kind) {\n case 'root':\n formattedLabel = bold(node.label);\n break;\n case 'entity': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.label.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n // Fallback: color entire label with cyan\n formattedLabel = cyan(node.label);\n }\n break;\n }\n case 'collection': {\n // \"columns\" grouping node - dim the label\n formattedLabel = dim(node.label);\n break;\n }\n case 'field': {\n // Parse column name format: \"columnName: typeDisplay (nullability)\"\n // Color code: column name (cyan), type (default), nullability (dim)\n const columnMatch = node.label.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"typeDisplay (nullability)\"\n const typeMatch = rest.match(/^([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2]) {\n const typeDisplay = typeMatch[1];\n const nullability = typeMatch[2];\n formattedLabel = `${cyan(columnName)}: ${typeDisplay} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.label;\n }\n break;\n }\n case 'index': {\n // Parse index/unique constraint/primary key formats\n // \"primary key: columnName\" -> dim \"primary key\", cyan columnName\n const pkMatch = node.label.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n // \"unique name\" -> dim \"unique\", cyan \"name\"\n const uniqueMatch = node.label.match(/^unique\\s+(.+)$/);\n if (uniqueMatch?.[1]) {\n const name = uniqueMatch[1];\n formattedLabel = `${dim('unique')} ${cyan(name)}`;\n } else {\n // \"index name\" or \"unique index name\" -> dim label prefix, cyan name\n const indexMatch = node.label.match(/^(unique\\s+)?index\\s+(.+)$/);\n if (indexMatch?.[2]) {\n const indexPrefix = indexMatch[1] ? `${dim('unique')} ` : '';\n const name = indexMatch[2];\n formattedLabel = `${indexPrefix}${dim('index')} ${cyan(name)}`;\n } else {\n formattedLabel = dim(node.label);\n }\n }\n }\n break;\n }\n case 'dependency': {\n // Parse extension message formats similar to schema-verify\n // \"extensionName extension is enabled\" -> cyan extensionName, dim rest\n const extMatch = node.label.match(/^([^\\s]+)\\s+(extension is enabled)$/);\n if (extMatch?.[1] && extMatch[2]) {\n const extName = extMatch[1];\n const rest = extMatch[2];\n formattedLabel = `${cyan(extName)} ${dim(rest)}`;\n } else {\n // Fallback: color entire label with magenta\n formattedLabel = magenta(node.label);\n }\n break;\n }\n default:\n formattedLabel = node.label;\n break;\n }\n }\n\n // Root node renders without tree characters or prefix\n if (isRoot) {\n lines.push(formattedLabel);\n } else {\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${formatDimText(treeChar)}─ `;\n lines.push(`${prefix}${treePrefix}${formattedLabel}`);\n }\n\n // Render children if present\n if (node.children && node.children.length > 0) {\n const childPrefix = isRoot ? '' : `${prefix}${isLast ? ' ' : `${formatDimText('│')} `}`;\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n if (!child) continue;\n const isLastChild = i === node.children.length - 1;\n const childLines = renderSchemaTree(child, flags, {\n isLast: isLastChild,\n prefix: childPrefix,\n useColor,\n formatDimText,\n isRoot: false,\n });\n lines.push(...childLines);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats human-readable output for database introspection.\n */\nexport function formatIntrospectOutput(\n result: IntrospectSchemaResult<unknown>,\n schemaView: CoreSchemaView | undefined,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (schemaView) {\n // Render tree structure - root node is special (no tree characters)\n const treeLines = renderSchemaTree(schemaView.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n lines.push(...treeLines);\n } else {\n // Fallback: print summary when toSchemaView is not available\n lines.push(`✔ ${result.summary}`);\n if (isVerbose(flags, 1)) {\n lines.push(` Target: ${result.target.familyId}/${result.target.id}`);\n if (result.meta?.dbUrl) {\n lines.push(` Database: ${result.meta.dbUrl}`);\n }\n }\n }\n\n // Add timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats human-readable output for database schema verification.\n */\nexport function formatSchemaVerifyOutput(\n result: VerifyDatabaseSchemaResult,\n flags: GlobalFlags,\n unclaimed: readonly string[] = [],\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatRed = createColorFormatter(useColor, red);\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n const issueMessages = result.schema.issues.map(formatIssueMessage);\n if (issueMessages.length > 0) {\n lines.push(formatRed('Schema issues:'));\n for (const message of issueMessages) {\n lines.push(` ${formatRed('✖')} ${message}`);\n }\n }\n\n const warningMessages = (result.schema.warnings?.issues ?? []).map(formatIssueMessage);\n if (warningMessages.length > 0) {\n if (lines.length > 0) lines.push('');\n lines.push(formatYellow('Schema warnings:'));\n for (const message of warningMessages) {\n lines.push(` ${formatYellow('⚠')} ${message}`);\n }\n }\n\n if (unclaimed.length > 0) {\n const strict = result.meta?.strict ?? false;\n if (lines.length > 0) lines.push('');\n lines.push(\n (strict ? formatRed : formatYellow)('Unclaimed elements (declared by no contract):'),\n );\n for (const name of unclaimed) {\n lines.push(` ${(strict ? formatRed : formatYellow)(strict ? '✖' : '⚠')} ${name}`);\n }\n }\n\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n // Blank line before summary\n if (lines.length > 0) lines.push('');\n\n // Summary line at the end: verdict with status glyph\n if (result.ok) {\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n } else {\n const codeText = result.code ? ` (${result.code})` : '';\n lines.push(`${formatRed('✖')} ${result.summary}${codeText}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database schema verification. The unclaimed-elements\n * list is a top-level field alongside the combined result, reported once for\n * the whole database.\n */\nexport function formatSchemaVerifyJson(\n result: VerifyDatabaseSchemaResult,\n unclaimed: readonly string[] = [],\n): string {\n return JSON.stringify({ ...result, unclaimed }, null, 2);\n}\n\n// ============================================================================\n// Sign Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for database sign.\n */\nexport function formatSignOutput(result: SignDatabaseResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Main success message in white (not dimmed)\n lines.push(`${formatGreen('✔')} Database signed`);\n\n // Show from -> to hashes with clear labels\n const previousHash = result.marker.previous?.storageHash ?? 'none';\n const currentHash = result.contract.storageHash;\n\n lines.push(`${formatDimText(` from: ${previousHash}`)}`);\n lines.push(`${formatDimText(` to: ${currentHash}`)}`);\n\n if (isVerbose(flags, 1)) {\n if (result.contract.profileHash) {\n lines.push(`${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n if (result.marker.previous?.profileHash) {\n lines.push(\n `${formatDimText(` previous profileHash: ${result.marker.previous.profileHash}`)}`,\n );\n }\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database sign.\n */\nexport function formatSignJson(result: SignDatabaseResult): string {\n return JSON.stringify(result, null, 2);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma-next/cli",
3
- "version": "0.16.0-dev.3",
3
+ "version": "0.16.0-dev.30",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -9,18 +9,18 @@
9
9
  },
10
10
  "dependencies": {
11
11
  "@clack/prompts": "^1.7.0",
12
- "@prisma-next/config": "0.16.0-dev.3",
13
- "@prisma-next/config-loader": "0.16.0-dev.3",
14
- "@prisma-next/contract": "0.16.0-dev.3",
15
- "@prisma-next/emitter": "0.16.0-dev.3",
16
- "@prisma-next/errors": "0.16.0-dev.3",
17
- "@prisma-next/framework-components": "0.16.0-dev.3",
18
- "@prisma-next/language-server": "0.16.0-dev.3",
19
- "@prisma-next/migration-tools": "0.16.0-dev.3",
20
- "@prisma-next/psl-parser": "0.16.0-dev.3",
21
- "@prisma-next/psl-printer": "0.16.0-dev.3",
22
- "@prisma-next/cli-telemetry": "0.16.0-dev.3",
23
- "@prisma-next/utils": "0.16.0-dev.3",
12
+ "@prisma-next/config": "0.16.0-dev.30",
13
+ "@prisma-next/config-loader": "0.16.0-dev.30",
14
+ "@prisma-next/contract": "0.16.0-dev.30",
15
+ "@prisma-next/emitter": "0.16.0-dev.30",
16
+ "@prisma-next/errors": "0.16.0-dev.30",
17
+ "@prisma-next/framework-components": "0.16.0-dev.30",
18
+ "@prisma-next/language-server": "0.16.0-dev.30",
19
+ "@prisma-next/migration-tools": "0.16.0-dev.30",
20
+ "@prisma-next/psl-parser": "0.16.0-dev.30",
21
+ "@prisma-next/psl-printer": "0.16.0-dev.30",
22
+ "@prisma-next/cli-telemetry": "0.16.0-dev.30",
23
+ "@prisma-next/utils": "0.16.0-dev.30",
24
24
  "arktype": "^2.2.2",
25
25
  "ci-info": "^4.3.1",
26
26
  "clipanion": "4.0.0-rc.4",
@@ -36,14 +36,14 @@
36
36
  "wrap-ansi": "^10.0.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@prisma-next/sql-contract": "0.16.0-dev.3",
40
- "@prisma-next/sql-contract-emitter": "0.16.0-dev.3",
41
- "@prisma-next/sql-contract-ts": "0.16.0-dev.3",
42
- "@prisma-next/sql-operations": "0.16.0-dev.3",
43
- "@prisma-next/sql-runtime": "0.16.0-dev.3",
44
- "@prisma-next/test-utils": "0.16.0-dev.3",
45
- "@prisma-next/tsconfig": "0.16.0-dev.3",
46
- "@prisma-next/tsdown": "0.16.0-dev.3",
39
+ "@prisma-next/sql-contract": "0.16.0-dev.30",
40
+ "@prisma-next/sql-contract-emitter": "0.16.0-dev.30",
41
+ "@prisma-next/sql-contract-ts": "0.16.0-dev.30",
42
+ "@prisma-next/sql-operations": "0.16.0-dev.30",
43
+ "@prisma-next/sql-runtime": "0.16.0-dev.30",
44
+ "@prisma-next/test-utils": "0.16.0-dev.30",
45
+ "@prisma-next/tsconfig": "0.16.0-dev.30",
46
+ "@prisma-next/tsdown": "0.16.0-dev.30",
47
47
  "@types/node": "25.9.4",
48
48
  "tsdown": "0.22.8",
49
49
  "typescript": "5.9.3",
@@ -176,6 +176,7 @@ async function executeDbInitCommand(
176
176
  ...ifDefined('advanceRef', options.advanceRef),
177
177
  ...ifDefined('db', options.db),
178
178
  refsDir,
179
+ migrationsDir,
179
180
  contractIR,
180
181
  mode: result.value.mode,
181
182
  hash: advancementHash,
@@ -4,11 +4,12 @@ import type {
4
4
  SignDatabaseResult,
5
5
  VerifyDatabaseSchemaResult,
6
6
  } from '@prisma-next/framework-components/control';
7
+ import { readContractSnapshotJson } from '@prisma-next/migration-tools/contract-snapshot-store';
7
8
  import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
8
9
  import { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';
9
10
  import { notOk, ok, type Result } from '@prisma-next/utils/result';
10
11
  import { Command } from 'commander';
11
- import { join, relative, resolve } from 'pathe';
12
+ import { relative, resolve } from 'pathe';
12
13
  import { createControlClient } from '../control-api/client';
13
14
  import { ContractValidationError } from '../control-api/errors';
14
15
  import {
@@ -113,9 +114,10 @@ async function executeDbSignCommand(
113
114
  const targetHash = refResult.value.hash;
114
115
  const matchingBundle = bundles.find((p) => p.metadata.to === targetHash);
115
116
  if (matchingBundle) {
116
- const endContractPath = join(matchingBundle.dirPath, 'end-contract.json');
117
- const raw = await readFile(endContractPath, 'utf-8');
118
- contractJson = JSON.parse(raw) as Record<string, unknown>;
117
+ contractJson = (await readContractSnapshotJson(migrationsDir, targetHash)) as Record<
118
+ string,
119
+ unknown
120
+ >;
119
121
  } else {
120
122
  const defaultRaw = await readFile(contractPathAbsolute, 'utf-8');
121
123
  const defaultContract = JSON.parse(defaultRaw) as Record<string, unknown>;
@@ -196,7 +198,7 @@ async function executeDbSignCommand(
196
198
  target: config.target,
197
199
  adapter: config.adapter,
198
200
  driver: config.driver,
199
- extensionPacks: config.extensionPacks ?? [],
201
+ extensions: config.extensions ?? [],
200
202
  });
201
203
 
202
204
  // Create progress adapter
@@ -1,4 +1,7 @@
1
- import { readFile } from 'node:fs/promises';
1
+ import {
2
+ contractSnapshotDir,
3
+ readContractSnapshotJson,
4
+ } from '@prisma-next/migration-tools/contract-snapshot-store';
2
5
  import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
3
6
  import { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';
4
7
  import { ifDefined } from '@prisma-next/utils/defined';
@@ -135,16 +138,20 @@ async function executeDbUpdateCommand(
135
138
  errorUnexpected(
136
139
  `No migration bundle found for --to "${options.to}" (resolved hash: ${targetHash})`,
137
140
  {
138
- why: `The ref resolved successfully but no on-disk migration package has an end-contract hash matching ${targetHash}.`,
141
+ why: `The ref resolved successfully but no on-disk migration package has a destination (\`to\`) hash matching ${targetHash}.`,
139
142
  fix: 'Provide a ref or hash that corresponds to an existing migration package, or run `migration list` to see available migrations.',
140
143
  },
141
144
  ),
142
145
  );
143
146
  }
144
- const endContractPath = join(matchingBundle.dirPath, 'end-contract.json');
145
- const raw = await readFile(endContractPath, 'utf-8');
146
- contractJson = JSON.parse(raw) as Record<string, unknown>;
147
- contractJsonPathForSnapshot = endContractPath;
147
+ contractJson = (await readContractSnapshotJson(migrationsDir, targetHash)) as Record<
148
+ string,
149
+ unknown
150
+ >;
151
+ contractJsonPathForSnapshot = join(
152
+ contractSnapshotDir(migrationsDir, targetHash),
153
+ 'contract.json',
154
+ );
148
155
  } catch (error) {
149
156
  if (MigrationToolsError.is(error)) {
150
157
  return notOk(mapMigrationToolsError(error));
@@ -193,6 +200,7 @@ async function executeDbUpdateCommand(
193
200
  ...ifDefined('advanceRef', options.advanceRef),
194
201
  ...ifDefined('db', options.db),
195
202
  refsDir,
203
+ migrationsDir,
196
204
  contractIR,
197
205
  mode: result.value.mode,
198
206
  hash: advancementHash,
@@ -318,7 +318,7 @@ function createVerifyClient(setup: VerifySetup) {
318
318
  target: setup.config.target,
319
319
  adapter: setup.config.adapter,
320
320
  driver: setup.config.driver!,
321
- extensionPacks: setup.config.extensionPacks ?? [],
321
+ extensions: setup.config.extensions ?? [],
322
322
  });
323
323
  }
324
324
 
@@ -23,7 +23,7 @@ export function createFormatCommand(): Command {
23
23
  command,
24
24
  'Format your PSL contract source',
25
25
  'Formats the Prisma schema (PSL) contract source declared in your config\n' +
26
- '(contract.source.inputs[0]) in place. Only runs when contract.source.sourceFormat\n' +
26
+ '(contract.source.inputs[0]) in place. Only runs when contract.source.format\n' +
27
27
  "is 'psl'; a TypeScript or unset source is left untouched. Indent and newline are\n" +
28
28
  'read from the optional formatter config section, defaulting to two spaces and the\n' +
29
29
  'system newline.',
@@ -1,47 +1,60 @@
1
1
  import type { TargetId } from './templates/code-templates';
2
2
 
3
3
  /**
4
- * The schema-relative `.gitattributes` entries written for a freshly
5
- * initialised project (FR3.4). Mirrors the relevant subset of the
6
- * repo-root [`.gitattributes`](../../../../../../../../.gitattributes):
4
+ * The `.gitattributes` entries written for a freshly initialised project
5
+ * (FR3.4). Mirrors the relevant subset of the repo-root
6
+ * [`.gitattributes`](../../../../../../../../.gitattributes):
7
7
  *
8
8
  * - **Today**: `contract.json`, `contract.d.ts` are emitted on every
9
9
  * `prisma-next contract emit`. Marking them `linguist-generated`
10
10
  * keeps GitHub's diff stats honest and collapses the file in code
11
11
  * review by default.
12
- * - **Forward-looking**: `end-contract.*`, `start-contract.*`, `ops.json`,
13
- * `migration.json` are not yet emitted by `init` flows but will be
14
- * produced by adjacent commands (lower / migration tooling). Adding
15
- * them now matches Decision 5 (forward-looking subset) so the file
16
- * does not need to be amended every time a new artefact lands.
12
+ * - **Forward-looking**: `ops.json`, `migration.json` are not yet emitted
13
+ * by `init` flows but will be produced by adjacent commands (lower /
14
+ * migration tooling). Adding them now matches Decision 5
15
+ * (forward-looking subset) so the file does not need to be amended
16
+ * every time a new artifact lands.
17
17
  *
18
- * Patterns are written relative to the schema directory so a user
19
- * who runs `init --schema-path db/contract.prisma` gets
20
- * `db/contract.json linguist-generated` — not the workspace-glob form
21
- * `<glob>/contract.json` (which would over-match any unrelated
18
+ * `ARTIFACT_FILENAMES` entries are written relative to the schema
19
+ * directory so a user who runs `init --schema-path db/contract.prisma`
20
+ * gets `db/contract.json linguist-generated` — not the workspace-glob
21
+ * form `<glob>/contract.json` (which would over-match any unrelated
22
22
  * `contract.json` the user has elsewhere) and not the absolute
23
- * `DEFAULT_CONTRACT_SOURCE_DIR/contract.json` (which would silently break for a non-default
24
- * schema path).
23
+ * `DEFAULT_CONTRACT_SOURCE_DIR/contract.json` (which would silently
24
+ * break for a non-default schema path).
25
+ *
26
+ * The migration contract snapshot store (`migrations/snapshots/<hex>/`)
27
+ * is anchored to the migrations root instead, not the schema directory:
28
+ * migration package depth under `migrations/` varies (`app/<pkg>`,
29
+ * `<space>/<pkg>`, or a bare `<pkg>` in extension source repos), so no
30
+ * single schema-dir-relative pattern can reach every snapshot. See
31
+ * `STORE_GITATTRIBUTES_LINES` below.
25
32
  */
26
- const ARTEFACT_FILENAMES: readonly string[] = [
33
+ const ARTIFACT_FILENAMES: readonly string[] = [
27
34
  'contract.json',
28
35
  'contract.d.ts',
29
- 'end-contract.json',
30
- 'end-contract.d.ts',
31
- 'start-contract.json',
32
- 'start-contract.d.ts',
33
36
  'ops.json',
34
37
  'migration.json',
35
38
  ];
36
39
 
37
40
  const ATTRIBUTE = 'linguist-generated';
38
41
 
42
+ /**
43
+ * Full `.gitattributes` lines for the migration contract snapshot store,
44
+ * already anchored to the migrations root — unlike `ARTIFACT_FILENAMES`,
45
+ * these are not combined with the schema-relative prefix.
46
+ */
47
+ const STORE_GITATTRIBUTES_LINES: readonly string[] = [
48
+ `migrations/snapshots/**/contract.json ${ATTRIBUTE}`,
49
+ `migrations/snapshots/**/contract.d.ts ${ATTRIBUTE}`,
50
+ ];
51
+
39
52
  /**
40
53
  * Computes the `.gitattributes` lines this scaffold expects to own. Each
41
54
  * line has the shape `<path> linguist-generated`. The `target` parameter
42
55
  * is currently unused but accepted for symmetry with the other hygiene
43
56
  * helpers and to leave room for target-specific entries (e.g. a future
44
- * Mongo-only artefact) without a signature break.
57
+ * family-specific artifact) without a signature break.
45
58
  */
46
59
  export function requiredGitattributesLines(
47
60
  schemaDir: string,
@@ -49,7 +62,10 @@ export function requiredGitattributesLines(
49
62
  ): readonly string[] {
50
63
  const dir = schemaDir === '.' ? '' : schemaDir.replace(/\/+$/, '');
51
64
  const prefix = dir === '' ? '' : `${dir}/`;
52
- return ARTEFACT_FILENAMES.map((file) => `${prefix}${file} ${ATTRIBUTE}`);
65
+ return [
66
+ ...ARTIFACT_FILENAMES.map((file) => `${prefix}${file} ${ATTRIBUTE}`),
67
+ ...STORE_GITATTRIBUTES_LINES,
68
+ ];
53
69
  }
54
70
 
55
71
  /**
@@ -48,7 +48,7 @@ import {
48
48
  renderInitOutro,
49
49
  } from './output';
50
50
  import { type ProbeOutcome, type ProbeOverrides, probeServerVersion } from './probe-db';
51
- import { findStaleArtefacts, removeDependency } from './reinit-cleanup';
51
+ import { findStaleArtifacts, removeDependency } from './reinit-cleanup';
52
52
  import {
53
53
  DEFAULT_SKILL_SOURCES,
54
54
  formatSkillInstallCommand,
@@ -175,14 +175,14 @@ export async function runInit(
175
175
  { path: '.env.example', content: envExampleContent(inputs.target) },
176
176
  ];
177
177
 
178
- // FR9.1 — on re-init, queue the previously-emitted contract artefacts
178
+ // FR9.1 — on re-init, queue the previously-emitted contract artifacts
179
179
  // for deletion so a target switch (or schema-shape change) does not
180
180
  // leave a stale `contract.json` / `contract.d.ts` next to the new
181
181
  // schema source. Detection is filesystem-only (no parsing of the
182
182
  // previous config) so the cleanup is safe to run before the write
183
183
  // phase: each path is checked for existence in the precondition,
184
184
  // and missing-on-disk-at-write-time is tolerated.
185
- const filesToDelete: string[] = inputs.reinit ? [...findStaleArtefacts(baseDir, schemaDir)] : [];
185
+ const filesToDelete: string[] = inputs.reinit ? [...findStaleArtifacts(baseDir, schemaDir)] : [];
186
186
 
187
187
  // `init` delegates the skill to `npx skills add prisma/prisma-next#v<version>`,
188
188
  // so a hand-rolled `.agents/skills/prisma-next/SKILL.md` in the project
@@ -245,7 +245,7 @@ export async function runInit(
245
245
  }
246
246
 
247
247
  // FR3.4: idempotent .gitattributes — linguist-generated entries for
248
- // the emitted artefacts so GitHub diff stats / code review collapse
248
+ // the emitted artifacts so GitHub diff stats / code review collapse
249
249
  // them by default.
250
250
  const gitattributesPath = join(baseDir, '.gitattributes');
251
251
  const existingGitattributes = existsSync(gitattributesPath)
@@ -373,7 +373,7 @@ export async function runInit(
373
373
  }
374
374
  }
375
375
 
376
- // FR9.1 — delete stale artefacts after the new templates are written.
376
+ // FR9.1 — delete stale artifacts after the new templates are written.
377
377
  // Order is intentional: the names do not collide with `filesToWrite`
378
378
  // (we never write `contract.json` from this command — that's `contract
379
379
  // emit`'s job), so deletion *after* the writes guarantees we never
@@ -847,7 +847,7 @@ function formatCatalogWarning(
847
847
  /**
848
848
  * Recognised pnpm error signatures that justify a fallback to npm.
849
849
  *
850
- * These patterns indicate the published artefact itself is at fault
850
+ * These patterns indicate the published artifact itself is at fault
851
851
  * (a leaked `workspace:*` or `catalog:` specifier), not the user's
852
852
  * environment — pnpm is faithfully reporting "I cannot resolve this
853
853
  * registry version", and npm is willing to install it because npm
@@ -24,10 +24,9 @@ export const InitOutputSchema = type({
24
24
  filesWritten: 'string[]',
25
25
  /**
26
26
  * FR9.1 — files removed from disk during this run. Populated only on
27
- * re-init when previously-emitted contract artefacts (`contract.json`,
28
- * `contract.d.ts`, `start-/end-contract.*`, `ops.json`,
29
- * `migration.json`) were left behind by an earlier run. Empty on a
30
- * green-field init.
27
+ * re-init when previously-emitted contract artifacts (`contract.json`,
28
+ * `contract.d.ts`, `ops.json`, `migration.json`) were left behind by an
29
+ * earlier run. Empty on a green-field init.
31
30
  */
32
31
  filesDeleted: 'string[]',
33
32
  packagesInstalled: {
@@ -80,7 +79,7 @@ export function renderInitOutro(ui: TerminalUI, output: InitOutput, flags: Globa
80
79
 
81
80
  if (output.filesDeleted.length > 0) {
82
81
  lines.push('');
83
- lines.push('Files deleted (stale contract artefacts):');
82
+ lines.push('Files deleted (stale contract artifacts):');
84
83
  for (const file of output.filesDeleted) {
85
84
  lines.push(` • ${file}`);
86
85
  }
@@ -4,41 +4,40 @@ import { join } from 'pathe';
4
4
  /**
5
5
  * Filenames the contract pipeline emits next to the user's schema source
6
6
  * (`<schemaDir>/contract.json`, `<schemaDir>/contract.d.ts`, …). Mirrors
7
- * `ARTEFACT_FILENAMES` in `hygiene-gitattributes.ts`; kept as a separate
8
- * constant here because the cleanup contract is target-agnostic and we
9
- * deliberately do not want a stale `start-contract.json` from a previous
10
- * target lingering after a re-init.
7
+ * the schema-dir-relative `ARTIFACT_FILENAMES` in `hygiene-gitattributes.ts`
8
+ * (not that file's migrations-root-anchored store lines, which are outside
9
+ * this command's scope reinit only ever touches `schemaDir`); kept as a
10
+ * separate constant here because the cleanup contract is target-agnostic
11
+ * and we deliberately do not want a stale artifact from a previous target
12
+ * lingering after a re-init.
11
13
  *
12
- * If a future emit pipeline produces an additional artefact, add it here
13
- * **and** to the gitattributes list — the two stay in lockstep so the
14
- * file `init` advertises as `linguist-generated` is exactly the file
15
- * `init` is willing to delete on re-init.
14
+ * If a future emit pipeline produces an additional schema-dir artifact,
15
+ * add it here **and** to `ARTIFACT_FILENAMES` in `hygiene-gitattributes.ts`
16
+ * the two stay in lockstep so the file `init` advertises as
17
+ * `linguist-generated` is exactly the file `init` is willing to delete on
18
+ * re-init.
16
19
  */
17
- const ARTEFACT_FILENAMES: readonly string[] = [
20
+ const ARTIFACT_FILENAMES: readonly string[] = [
18
21
  'contract.json',
19
22
  'contract.d.ts',
20
- 'end-contract.json',
21
- 'end-contract.d.ts',
22
- 'start-contract.json',
23
- 'start-contract.d.ts',
24
23
  'ops.json',
25
24
  'migration.json',
26
25
  ];
27
26
 
28
27
  /**
29
- * Returns the schema-relative paths of stale contract artefacts the
28
+ * Returns the schema-relative paths of stale contract artifacts the
30
29
  * previous `init` run (or a `contract emit`) left behind in `schemaDir`.
31
30
  * Paths are returned relative to `baseDir` so the caller can plumb them
32
31
  * into `filesWritten`-style logging without re-deriving the path.
33
32
  *
34
33
  * Pure function: no filesystem mutation. Used by `runInit`'s precondition
35
34
  * phase (FR6.2 / NFR3 atomicity) so a downstream parse failure leaves
36
- * the artefacts on disk and the project byte-identical to its pre-init
35
+ * the artifacts on disk and the project byte-identical to its pre-init
37
36
  * state.
38
37
  */
39
- export function findStaleArtefacts(baseDir: string, schemaDir: string): readonly string[] {
38
+ export function findStaleArtifacts(baseDir: string, schemaDir: string): readonly string[] {
40
39
  const result: string[] = [];
41
- for (const filename of ARTEFACT_FILENAMES) {
40
+ for (const filename of ARTIFACT_FILENAMES) {
42
41
  const rel = join(schemaDir, filename);
43
42
  if (existsSync(join(baseDir, rel))) {
44
43
  result.push(rel);
@@ -131,7 +131,7 @@ export async function inspectLiveSchema(
131
131
  target: config.target,
132
132
  adapter: config.adapter,
133
133
  driver: config.driver,
134
- extensionPacks: config.extensionPacks ?? [],
134
+ extensions: config.extensions ?? [],
135
135
  });
136
136
  const onProgress = createProgressAdapter({ ui, flags });
137
137
 
@@ -330,7 +330,7 @@ async function executeMigrateShowCommand(
330
330
  target: config.target,
331
331
  adapter: config.adapter,
332
332
  driver: config.driver!,
333
- extensionPacks: config.extensionPacks ?? [],
333
+ extensions: config.extensions ?? [],
334
334
  });
335
335
  try {
336
336
  await client.connect(dbConnection);
@@ -675,7 +675,7 @@ async function executeMigrateCommand(
675
675
  targetId: config.target.targetId,
676
676
  migrationsDir,
677
677
  appContract: contractRaw,
678
- extensionPacks: config.extensionPacks ?? [],
678
+ extensions: config.extensions ?? [],
679
679
  deserializeContract: (json) => familyInstance.deserializeContract(json),
680
680
  });
681
681
  if (!loadedAggregate.ok) {
@@ -684,7 +684,7 @@ async function executeMigrateCommand(
684
684
  const aggregate = loadedAggregate.value;
685
685
  const integrityFailure = refuseContractSpaceIntegrity(aggregate, {
686
686
  declaredExtensions: toDeclaredExtensionsFromRaw(
687
- (config.extensionPacks ?? []) as ReadonlyArray<unknown>,
687
+ (config.extensions ?? []) as ReadonlyArray<unknown>,
688
688
  ),
689
689
  checkContracts: true,
690
690
  });
@@ -740,7 +740,7 @@ async function executeMigrateCommand(
740
740
  target: config.target,
741
741
  adapter: config.adapter,
742
742
  driver: config.driver,
743
- extensionPacks: config.extensionPacks ?? [],
743
+ extensions: config.extensions ?? [],
744
744
  });
745
745
 
746
746
  try {
@@ -831,6 +831,7 @@ async function executeMigrateCommand(
831
831
  : await readContractIR(snapshotContractJson, contractPathAbsolute);
832
832
  advancedRef = await executeRefAdvancement(
833
833
  refsDir,
834
+ migrationsDir,
834
835
  options.advanceRef,
835
836
  value.markerHash,
836
837
  contractIR,
@@ -886,7 +887,7 @@ export function createMigrateCommand(): Command {
886
887
  setCommandExamples(command, [
887
888
  'prisma-next migrate --db $DATABASE_URL',
888
889
  'prisma-next migrate --to production --db $DATABASE_URL',
889
- 'prisma-next migrate --to sha256:abc123 --db $DATABASE_URL',
890
+ 'prisma-next migrate --to abc123 --db $DATABASE_URL',
890
891
  'prisma-next migrate --show --db $DATABASE_URL',
891
892
  'prisma-next migrate --show --from @contract --to production',
892
893
  ]);