prisma-next 0.8.0 → 0.9.0-dev.1

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 (126) hide show
  1. package/README.md +1 -1
  2. package/dist/{cli-errors-D3_sMh2K.mjs → cli-errors-CF60g2cG.mjs} +40 -2
  3. package/dist/cli-errors-CF60g2cG.mjs.map +1 -0
  4. package/dist/cli.mjs +67 -19
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/{client-BCnP7cHo.mjs → client-Brv4qlfB.mjs} +28 -30
  7. package/dist/client-Brv4qlfB.mjs.map +1 -0
  8. package/dist/{command-helpers-BeZHkxV8.mjs → command-helpers-D3vL5yi8.mjs} +29 -6
  9. package/dist/command-helpers-D3vL5yi8.mjs.map +1 -0
  10. package/dist/commands/contract-emit.mjs +1 -1
  11. package/dist/commands/contract-infer.mjs +1 -1
  12. package/dist/commands/db-init.mjs +7 -7
  13. package/dist/commands/db-schema.mjs +5 -5
  14. package/dist/commands/db-sign.d.mts.map +1 -1
  15. package/dist/commands/db-sign.mjs +67 -25
  16. package/dist/commands/db-sign.mjs.map +1 -1
  17. package/dist/commands/db-update.d.mts.map +1 -1
  18. package/dist/commands/db-update.mjs +37 -9
  19. package/dist/commands/db-update.mjs.map +1 -1
  20. package/dist/commands/db-verify.d.mts.map +1 -1
  21. package/dist/commands/db-verify.mjs +1 -1
  22. package/dist/commands/migrate.d.mts +28 -0
  23. package/dist/commands/migrate.d.mts.map +1 -0
  24. package/dist/commands/{migration-apply.mjs → migrate.mjs} +65 -39
  25. package/dist/commands/migrate.mjs.map +1 -0
  26. package/dist/commands/migration-check.d.mts +18 -0
  27. package/dist/commands/migration-check.d.mts.map +1 -0
  28. package/dist/commands/migration-check.mjs +284 -0
  29. package/dist/commands/migration-check.mjs.map +1 -0
  30. package/dist/commands/migration-graph.d.mts +16 -0
  31. package/dist/commands/migration-graph.d.mts.map +1 -0
  32. package/dist/commands/migration-graph.mjs +141 -0
  33. package/dist/commands/migration-graph.mjs.map +1 -0
  34. package/dist/commands/migration-list.d.mts +20 -0
  35. package/dist/commands/migration-list.d.mts.map +1 -0
  36. package/dist/commands/migration-list.mjs +107 -0
  37. package/dist/commands/migration-list.mjs.map +1 -0
  38. package/dist/commands/migration-log.d.mts +21 -0
  39. package/dist/commands/migration-log.d.mts.map +1 -0
  40. package/dist/commands/migration-log.mjs +146 -0
  41. package/dist/commands/migration-log.mjs.map +1 -0
  42. package/dist/commands/migration-new.d.mts.map +1 -1
  43. package/dist/commands/migration-new.mjs +30 -29
  44. package/dist/commands/migration-new.mjs.map +1 -1
  45. package/dist/commands/migration-plan.d.mts +2 -2
  46. package/dist/commands/migration-plan.d.mts.map +1 -1
  47. package/dist/commands/migration-plan.mjs +1 -1
  48. package/dist/commands/migration-show.d.mts +1 -1
  49. package/dist/commands/migration-show.d.mts.map +1 -1
  50. package/dist/commands/migration-show.mjs +90 -52
  51. package/dist/commands/migration-show.mjs.map +1 -1
  52. package/dist/commands/migration-status.d.mts +5 -17
  53. package/dist/commands/migration-status.d.mts.map +1 -1
  54. package/dist/commands/migration-status.mjs +732 -1
  55. package/dist/commands/migration-status.mjs.map +1 -0
  56. package/dist/commands/ref.d.mts +34 -0
  57. package/dist/commands/ref.d.mts.map +1 -0
  58. package/dist/commands/{migration-ref.mjs → ref.mjs} +28 -57
  59. package/dist/commands/ref.mjs.map +1 -0
  60. package/dist/{contract-emit-9DBda5Ou.mjs → contract-emit-C3STUIBg.mjs} +6 -6
  61. package/dist/{contract-emit-9DBda5Ou.mjs.map → contract-emit-C3STUIBg.mjs.map} +1 -1
  62. package/dist/{contract-emit-B77TsJqf.mjs → contract-emit-iynA3BCA.mjs} +9 -5
  63. package/dist/contract-emit-iynA3BCA.mjs.map +1 -0
  64. package/dist/{contract-infer-ByxhPjpW.mjs → contract-infer-Cnj8G1E2.mjs} +5 -5
  65. package/dist/{contract-infer-ByxhPjpW.mjs.map → contract-infer-Cnj8G1E2.mjs.map} +1 -1
  66. package/dist/{contract-space-aggregate-loader-BrwKK6Q6.mjs → contract-space-aggregate-loader-pAc8CDfY.mjs} +4 -4
  67. package/dist/{contract-space-aggregate-loader-BrwKK6Q6.mjs.map → contract-space-aggregate-loader-pAc8CDfY.mjs.map} +1 -1
  68. package/dist/{db-verify-Czm5T-J4.mjs → db-verify-D7cyH_zz.mjs} +12 -9
  69. package/dist/db-verify-D7cyH_zz.mjs.map +1 -0
  70. package/dist/errors-Cw6kyTyV.mjs +56 -0
  71. package/dist/errors-Cw6kyTyV.mjs.map +1 -0
  72. package/dist/exports/control-api.d.mts +1 -1
  73. package/dist/exports/control-api.d.mts.map +1 -1
  74. package/dist/exports/control-api.mjs +2 -2
  75. package/dist/exports/index.mjs +1 -1
  76. package/dist/exports/index.mjs.map +1 -1
  77. package/dist/exports/init-output.mjs +1 -1
  78. package/dist/{framework-components-ChqVUxR-.mjs → framework-components-xFLFpZUO.mjs} +2 -2
  79. package/dist/{framework-components-ChqVUxR-.mjs.map → framework-components-xFLFpZUO.mjs.map} +1 -1
  80. package/dist/{global-flags-Icqpxk23.d.mts → global-flags-DGmw6Kqg.d.mts} +1 -1
  81. package/dist/{global-flags-Icqpxk23.d.mts.map → global-flags-DGmw6Kqg.d.mts.map} +1 -1
  82. package/dist/{migration-status-By9G5p2H.mjs → graph-render-eJDcLWny.mjs} +3 -692
  83. package/dist/graph-render-eJDcLWny.mjs.map +1 -0
  84. package/dist/{init-B-k3a1Qw.mjs → init-Bqg5JWg7.mjs} +133 -61
  85. package/dist/init-Bqg5JWg7.mjs.map +1 -0
  86. package/dist/{inspect-live-schema-DxdBd4Er.mjs → inspect-live-schema-CWLK_lgs.mjs} +4 -4
  87. package/dist/{inspect-live-schema-DxdBd4Er.mjs.map → inspect-live-schema-CWLK_lgs.mjs.map} +1 -1
  88. package/dist/migration-cli.mjs +1 -1
  89. package/dist/migration-cli.mjs.map +1 -1
  90. package/dist/{migration-command-scaffold-BdV8JYXV.mjs → migration-command-scaffold-CmXXC1UZ.mjs} +4 -4
  91. package/dist/{migration-command-scaffold-BdV8JYXV.mjs.map → migration-command-scaffold-CmXXC1UZ.mjs.map} +1 -1
  92. package/dist/{migration-plan-mRu5K81L.mjs → migration-plan-CHyUlBV0.mjs} +76 -37
  93. package/dist/migration-plan-CHyUlBV0.mjs.map +1 -0
  94. package/dist/migration-types-D2FW63pr.d.mts +15 -0
  95. package/dist/migration-types-D2FW63pr.d.mts.map +1 -0
  96. package/dist/{migrations-CTsyBXCA.mjs → migrations-DyUf5lTt.mjs} +2 -2
  97. package/dist/migrations-DyUf5lTt.mjs.map +1 -0
  98. package/dist/{output-BVj6a971.mjs → output-B60Gw5fu.mjs} +12 -11
  99. package/dist/{output-BVj6a971.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
  100. package/dist/{result-handler-rmPVKIP2.mjs → result-handler-Bm_6dDYg.mjs} +2 -2
  101. package/dist/{result-handler-rmPVKIP2.mjs.map → result-handler-Bm_6dDYg.mjs.map} +1 -1
  102. package/dist/{terminal-ui-C_hFNbAn.mjs → terminal-ui-XtOQsqe9.mjs} +2 -54
  103. package/dist/terminal-ui-XtOQsqe9.mjs.map +1 -0
  104. package/dist/{types-LItU7E4l.d.mts → types-0aS865QN.d.mts} +14 -8
  105. package/dist/types-0aS865QN.d.mts.map +1 -0
  106. package/dist/{verify-CiwNWM9N.mjs → verify-D7ypCCe6.mjs} +1 -1
  107. package/dist/{verify-CiwNWM9N.mjs.map → verify-D7ypCCe6.mjs.map} +1 -1
  108. package/package.json +10 -10
  109. package/dist/cli-errors-D3_sMh2K.mjs.map +0 -1
  110. package/dist/client-BCnP7cHo.mjs.map +0 -1
  111. package/dist/command-helpers-BeZHkxV8.mjs.map +0 -1
  112. package/dist/commands/migration-apply.d.mts +0 -51
  113. package/dist/commands/migration-apply.d.mts.map +0 -1
  114. package/dist/commands/migration-apply.mjs.map +0 -1
  115. package/dist/commands/migration-ref.d.mts +0 -45
  116. package/dist/commands/migration-ref.d.mts.map +0 -1
  117. package/dist/commands/migration-ref.mjs.map +0 -1
  118. package/dist/contract-emit-B77TsJqf.mjs.map +0 -1
  119. package/dist/db-verify-Czm5T-J4.mjs.map +0 -1
  120. package/dist/init-B-k3a1Qw.mjs.map +0 -1
  121. package/dist/migration-plan-mRu5K81L.mjs.map +0 -1
  122. package/dist/migration-status-By9G5p2H.mjs.map +0 -1
  123. package/dist/migrations-CTsyBXCA.mjs.map +0 -1
  124. package/dist/terminal-ui-C_hFNbAn.mjs.map +0 -1
  125. package/dist/types-LItU7E4l.d.mts.map +0 -1
  126. /package/dist/{cli-errors-B9OBbled.d.mts → cli-errors-DdcjVLJV.d.mts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations-DyUf5lTt.mjs","names":[],"sources":["../src/utils/formatters/migrations.ts"],"sourcesContent":["import type { OperationPreview } from '@prisma-next/framework-components/control';\nimport { cyan, green, yellow } from 'colorette';\n\nimport type { AggregatePerSpaceExecutionEntry } from '../../control-api/types';\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim, isVerbose } from './helpers';\n\n/**\n * Render a single statement of an `OperationPreview` for the human-readable\n * preview block. SQL statements get a trailing `;` if missing so the rendered\n * preview is byte-identical to the legacy `string[]`-based renderer for SQL\n * targets. Other languages (`'mongodb-shell'`) render verbatim.\n */\nfunction renderPreviewStatement(text: string, language: string): string | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n if (language === 'sql') {\n return trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n }\n return trimmed;\n}\n\n/**\n * Choose the header label for a preview block. SQL-only previews keep the\n * legacy `DDL preview` label so the rendered output is byte-identical to the\n * pre-aggregate SQL CLI; previews from any other family — or a mix that\n * includes any non-SQL language — use the family-agnostic `Operation preview`\n * label.\n *\n * An empty `statements` array deliberately renders as `Operation preview`\n * rather than `DDL preview`: `Array.prototype.every` is vacuously true for\n * empty arrays, but we have no evidence the preview is SQL-only when no\n * statements are present, so the family-agnostic label is the safer default.\n */\nexport function previewBlockHeader(preview: OperationPreview): string {\n const allSql =\n preview.statements.length > 0 && preview.statements.every((s) => s.language === 'sql');\n return allSql ? 'DDL preview' : 'Operation preview';\n}\n\n// ============================================================================\n// Migration Command Output Formatters (shared by db init and db update)\n// ============================================================================\n\n/**\n * Shared CLI output type for migration commands (db init, db update).\n */\nexport interface MigrationCommandResult {\n readonly ok: true;\n readonly mode: 'plan' | 'apply';\n readonly plan: {\n readonly targetId: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\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 planned operations. Replaces the\n * previous `sql?: readonly string[]`. Consumers should read\n * `plan.preview?.statements`.\n */\n readonly preview?: OperationPreview;\n };\n readonly execution?: {\n readonly operationsPlanned: number;\n readonly operationsExecuted: number;\n };\n readonly marker?: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n /**\n * Per-space execution breakdown in canonical schedule order\n * (extensions alphabetically, then app). Surfaces per-space markers\n * and the ops grouped by space, so the CLI summary can name which\n * space each op and marker belongs to instead of flattening them\n * into a single ambiguous list. See {@link AggregatePerSpaceExecutionEntry}.\n */\n readonly perSpace?: ReadonlyArray<AggregatePerSpaceExecutionEntry>;\n readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Render the shared per-space execution block consumed by the `db init`\n * / `db update` / `migrate` summaries. Always shows: space\n * label (`Extension space: <id>` or `App space`) → per-op lines under\n * each space → per-space marker hash (when known).\n *\n * `mode` controls the marker label phrasing — `'apply'` shows\n * `marker → <hash>` (post-apply), `'plan'` omits the marker line\n * entirely (no marker has been written yet).\n */\nexport function formatPerSpaceBlock(\n perSpace: ReadonlyArray<AggregatePerSpaceExecutionEntry>,\n mode: 'plan' | 'apply',\n useColor: boolean,\n): readonly string[] {\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatCyan = createColorFormatter(useColor, cyan);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n const lines: string[] = [];\n for (let s = 0; s < perSpace.length; s++) {\n const space = perSpace[s]!;\n if (s > 0) lines.push('');\n const header =\n space.kind === 'app'\n ? formatCyan('App space')\n : formatCyan(`Extension space: ${space.spaceId}`);\n lines.push(header);\n if (space.operations.length === 0) {\n lines.push(` ${formatDimText('(no operations)')}`);\n } else {\n for (let i = 0; i < space.operations.length; i++) {\n const op = space.operations[i]!;\n const isLast = i === space.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${formatYellow('(destructive)')}` : '';\n lines.push(` ${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);\n }\n }\n if (mode === 'apply' && space.marker) {\n lines.push(` ${formatDimText(`marker: ${space.marker.storageHash}`)}`);\n }\n }\n return lines;\n}\n\n/**\n * Formats human-readable output for migration commands (db init, db update) in plan mode.\n */\nexport function formatMigrationPlanOutput(\n result: MigrationCommandResult,\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 formatDimText = (text: string) => formatDim(useColor, text);\n\n // Plan summary\n const operationCount = result.plan?.operations.length ?? 0;\n const spaceCount = result.perSpace?.length ?? 0;\n if (spaceCount > 0) {\n lines.push(\n `${formatGreen('✔')} Planned ${operationCount} operation(s) across ${spaceCount} contract space${spaceCount === 1 ? '' : 's'}`,\n );\n } else {\n lines.push(`${formatGreen('✔')} Planned ${operationCount} operation(s)`);\n }\n\n const formatYellow = createColorFormatter(useColor, yellow);\n\n // Per-space breakdown takes precedence over the flat ops tree when\n // the aggregate flow surfaced one.\n if (result.perSpace && result.perSpace.length > 0) {\n lines.push('');\n lines.push(...formatPerSpaceBlock(result.perSpace, 'plan', useColor));\n const hasDestructive = result.perSpace.some((s) =>\n s.operations.some((op) => op.operationClass === 'destructive'),\n );\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${formatYellow('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n } else if (result.plan?.operations && result.plan.operations.length > 0) {\n // Single-space fallback (no aggregate breakdown). Same flat tree\n // we've always rendered.\n lines.push(`${formatDimText('│')}`);\n for (let i = 0; i < result.plan.operations.length; i++) {\n const op = result.plan.operations[i];\n if (!op) continue;\n const isLast = i === result.plan.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${formatYellow('(destructive)')}` : '';\n lines.push(`${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);\n }\n\n const hasDestructive = result.plan.operations.some((op) => op.operationClass === 'destructive');\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${formatYellow('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n }\n\n // Destination hash\n if (result.plan?.destination) {\n lines.push('');\n lines.push(`${formatDimText(`Destination hash: ${result.plan.destination.storageHash}`)}`);\n }\n\n // Statement preview (any family that implements OperationPreviewCapable)\n const preview = result.plan?.preview;\n if (preview) {\n lines.push('');\n lines.push(`${formatDimText(previewBlockHeader(preview))}`);\n if (preview.statements.length === 0) {\n lines.push(`${formatDimText('No operations.')}`);\n } else {\n lines.push('');\n for (const statement of preview.statements) {\n const rendered = renderPreviewStatement(statement.text, statement.language);\n if (rendered) {\n lines.push(rendered);\n }\n }\n }\n }\n\n // Timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(`Total time: ${result.timings.total}ms`)}`);\n }\n\n // Note about dry run\n lines.push('');\n lines.push(`${formatDimText('This is a dry run. No changes were applied.')}`);\n lines.push(`${formatDimText('Run without --dry-run to apply changes.')}`);\n\n return lines.join('\\n');\n}\n\nexport interface MigrationApplyCommandOutputResult {\n readonly migrationsApplied: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName?: string;\n readonly migrationHash?: string;\n readonly from?: string;\n readonly to?: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n /**\n * Per-space breakdown in canonical schedule order (extensions\n * alphabetically, then app). Always present for the aggregate-walking\n * `migrate` command.\n */\n readonly perSpace: readonly AggregatePerSpaceExecutionEntry[];\n readonly timings?: {\n readonly total: number;\n };\n}\n\nexport function formatMigrationApplyCommandOutput(\n result: MigrationApplyCommandOutputResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n\n if (result.perSpace.length > 0) {\n lines.push('');\n for (const line of formatPerSpaceBlock(result.perSpace, 'apply', useColor)) {\n lines.push(line);\n }\n }\n\n lines.push('');\n lines.push(formatDimText('Next: prisma-next migration status'));\n\n if (isVerbose(flags, 1) && result.timings) {\n lines.push('');\n lines.push(formatDimText(`Total time: ${result.timings.total}ms`));\n }\n\n return lines.join('\\n');\n}\n\ninterface MigrationShowSpacePresent {\n readonly kind: 'present';\n readonly spaceId: string;\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 readonly preview: OperationPreview;\n readonly summary: string;\n}\n\ninterface MigrationShowSpaceMissing {\n readonly kind: 'missing';\n readonly spaceId: string;\n readonly summary: string;\n}\n\ntype MigrationShowSpaceResult = MigrationShowSpacePresent | MigrationShowSpaceMissing;\n\ninterface MigrationShowResult {\n readonly spaces: readonly MigrationShowSpaceResult[];\n}\n\nfunction formatSpaceShowBlock(\n space: MigrationShowSpacePresent,\n useColor: boolean,\n): readonly string[] {\n const formatGreen = createColorFormatter(useColor, green);\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n const lines: string[] = [];\n lines.push(`${formatGreen('✔')} ${space.dirName}`);\n lines.push(`${formatDimText(` from: ${space.from ?? '(baseline)'}`)}`);\n lines.push(`${formatDimText(` to: ${space.to}`)}`);\n lines.push(`${formatDimText(` migrationHash: ${space.migrationHash}`)}`);\n lines.push(`${formatDimText(` created: ${space.createdAt}`)}`);\n\n lines.push('');\n lines.push(`${space.operations.length} operation(s)`);\n\n if (space.operations.length > 0) {\n lines.push(`${formatDimText('│')}`);\n for (let i = 0; i < space.operations.length; i++) {\n const op = space.operations[i]!;\n const isLast = i === space.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const destructiveMarker =\n op.operationClass === 'destructive' ? ` ${formatYellow('(destructive)')}` : '';\n lines.push(`${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);\n }\n\n const hasDestructive = space.operations.some((op) => op.operationClass === 'destructive');\n if (hasDestructive) {\n lines.push('');\n lines.push(\n `${formatYellow('⚠')} This migration contains destructive operations that may cause data loss.`,\n );\n }\n }\n\n if (space.preview.statements.length > 0) {\n lines.push('');\n lines.push(`${formatDimText(previewBlockHeader(space.preview))}`);\n lines.push('');\n for (const statement of space.preview.statements) {\n const rendered = renderPreviewStatement(statement.text, statement.language);\n if (rendered) {\n lines.push(rendered);\n }\n }\n }\n\n return lines;\n}\n\nexport function formatMigrationShowOutput(result: MigrationShowResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n const multipleSpaces = result.spaces.length > 1;\n const lines: string[] = [];\n\n for (let i = 0; i < result.spaces.length; i++) {\n const space = result.spaces[i]!;\n if (multipleSpaces) {\n lines.push(formatDimText(`── ${space.spaceId} ──`));\n }\n if (space.kind === 'missing') {\n lines.push(formatDimText(` ${space.summary}`));\n } else {\n for (const line of formatSpaceShowBlock(space, useColor)) {\n lines.push(line);\n }\n }\n if (i < result.spaces.length - 1) {\n lines.push('');\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats human-readable output for migration commands (db init, db update) in apply mode.\n */\nexport function formatMigrationApplyOutput(\n result: MigrationCommandResult,\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 formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Success summary\n const executed = result.execution?.operationsExecuted ?? 0;\n const spaceCount = result.perSpace?.length ?? 0;\n\n if (executed === 0) {\n const acrossClause =\n spaceCount > 0 ? ` across ${spaceCount} contract space${spaceCount === 1 ? '' : 's'}` : '';\n lines.push(`${formatGreen('✔')} Database already matches contract${acrossClause}`);\n } else if (spaceCount > 0) {\n lines.push(\n `${formatGreen('✔')} Applied ${executed} operation(s) across ${spaceCount} contract space${spaceCount === 1 ? '' : 's'}`,\n );\n } else {\n lines.push(`${formatGreen('✔')} Applied ${executed} operation(s)`);\n }\n\n // Per-space breakdown — replaces the single ambiguous `Signature:`\n // line with a per-space marker + ops listing.\n if (result.perSpace && result.perSpace.length > 0) {\n lines.push('');\n lines.push(...formatPerSpaceBlock(result.perSpace, 'apply', useColor));\n lines.push('');\n lines.push(\n formatDimText(\n `Run 'prisma-next migration status' to confirm ${\n spaceCount === 1 ? 'the space is' : 'all spaces are'\n } up to date.`,\n ),\n );\n } else if (result.marker) {\n // Single-space fallback (no aggregate breakdown surfaced — e.g.\n // older callers / non-aggregate code paths). The label is\n // `App-space marker` (not `Signature`) so that when only one\n // marker is observable we still name what it covers explicitly.\n lines.push(`${formatDimText(` App-space marker: ${result.marker.storageHash}`)}`);\n if (result.marker.profileHash) {\n lines.push(`${formatDimText(` Profile hash: ${result.marker.profileHash}`)}`);\n }\n }\n\n // Timings in verbose mode\n if (isVerbose(flags, 1)) {\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 migration commands (db init, db update).\n */\nexport function formatMigrationJson(result: MigrationCommandResult): string {\n return JSON.stringify(result, null, 2);\n}\n"],"mappings":"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"}
@@ -90,20 +90,21 @@ function renderInitOutro(ui, output, flags) {
90
90
  */
91
91
  function buildNextSteps(options) {
92
92
  const steps = [];
93
- steps.push("1. Set DATABASE_URL in your environment (export it or add it to .env).");
93
+ let stepNumber = 1;
94
+ const push = (text) => {
95
+ steps.push(`${stepNumber}. ${text}`);
96
+ stepNumber += 1;
97
+ };
98
+ push("Set DATABASE_URL in your environment (export it or add it to .env).");
94
99
  if (!options.contractEmitted) {
95
- steps.push(`2. Emit the contract: \`${options.emitCommand}\``);
96
- steps.push(`3. Edit your schema at ${options.schemaPath}, then re-run the emit command.`);
97
- steps.push("4. Open prisma-next.md for a quick reference on how to write your first typed query.");
98
- steps.push("5. @prisma-next/agent-skill is registered with your agent runtime open the project in your IDE and ask the agent to add a model, run a query, or plan a migration.");
99
- } else {
100
- steps.push(`2. Edit your schema at ${options.schemaPath}, then re-run \`${options.emitCommand}\`.`);
101
- steps.push("3. Open prisma-next.md for a quick reference on how to write your first typed query.");
102
- steps.push("4. @prisma-next/agent-skill is registered with your agent runtime — open the project in your IDE and ask the agent to add a model, run a query, or plan a migration.");
103
- }
100
+ push(`Emit the contract: \`${options.emitCommand}\``);
101
+ push(`Edit your schema at ${options.schemaPath}, then re-run the emit command.`);
102
+ } else push(`Edit your schema at ${options.schemaPath}, then re-run \`${options.emitCommand}\`.`);
103
+ push("Open prisma-next.md for a quick reference on how to write your first typed query.");
104
+ if (options.skillRegistered) push("Prisma Next skills are registered with your agent runtime — open the project in your IDE and ask the agent to add a model, run a query, or plan a migration.");
104
105
  return steps;
105
106
  }
106
107
  //#endregion
107
108
  export { renderInitOutro as i, buildNextSteps as n, formatInitJson as r, InitOutputSchema as t };
108
109
 
109
- //# sourceMappingURL=output-BVj6a971.mjs.map
110
+ //# sourceMappingURL=output-B60Gw5fu.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"output-BVj6a971.mjs","names":[],"sources":["../src/commands/init/output.ts"],"sourcesContent":["import { type } from 'arktype';\nimport type { GlobalFlags } from '../../utils/global-flags';\nimport type { TerminalUI } from '../../utils/terminal-ui';\n\n/**\n * arktype schema for the structured success document `init --json` writes\n * to stdout (FR1.5). The same shape backs the human-readable outro\n * renderer (FR10), so the two output modes carry identical information.\n *\n * `target` is normalised to the user-facing flag value (`mongodb` rather\n * than the internal `mongo`) so consumers can round-trip the document\n * straight into a follow-up `--target` invocation.\n *\n * The `ok: true` literal is the documented success/error discriminator —\n * see [Style Guide § JSON Semantics](../../../../../../../docs/CLI%20Style%20Guide.md#json-semantics).\n * Error envelopes (`CliErrorEnvelope`) carry `ok: false` so consumers can\n * branch with `if (doc.ok)` without inspecting the rest of the structure.\n */\nexport const InitOutputSchema = type({\n ok: 'true',\n target: \"'postgres'|'mongodb'\",\n authoring: \"'psl'|'typescript'\",\n schemaPath: 'string',\n filesWritten: 'string[]',\n /**\n * FR9.1 — files removed from disk during this run. Populated only on\n * re-init when previously-emitted contract artefacts (`contract.json`,\n * `contract.d.ts`, `start-/end-contract.*`, `ops.json`,\n * `migration.json`) were left behind by an earlier run. Empty on a\n * green-field init.\n */\n filesDeleted: 'string[]',\n packagesInstalled: {\n skipped: 'boolean',\n deps: 'string[]',\n devDeps: 'string[]',\n },\n contractEmitted: 'boolean',\n nextSteps: 'string[]',\n warnings: 'string[]',\n});\n\nexport type InitOutput = typeof InitOutputSchema.infer;\n\n/**\n * Serialises the output document for `--json`. Sorted keys are not enforced\n * — `JSON.stringify` preserves insertion order, and the schema field order\n * is the documented order, which matches what users will see when they\n * `jq .` the result.\n */\nexport function formatInitJson(output: InitOutput): string {\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Renders the human-readable outro on stderr (FR10.1). Re-uses the same\n * data structure as the JSON output so the two stay in lock-step.\n *\n * Warnings come before \"Next steps\" because they describe state the user\n * needs to be aware of before acting on the next-steps list.\n */\nexport function renderInitOutro(ui: TerminalUI, output: InitOutput, flags: GlobalFlags): void {\n if (flags.quiet || flags.json) {\n return;\n }\n\n for (const warning of output.warnings) {\n ui.warn(warning);\n }\n\n const lines: string[] = [];\n lines.push(`Target: ${output.target}`);\n lines.push(`Authoring: ${output.authoring}`);\n lines.push(`Schema: ${output.schemaPath}`);\n lines.push('');\n lines.push('Files written:');\n for (const file of output.filesWritten) {\n lines.push(` • ${file}`);\n }\n\n if (output.filesDeleted.length > 0) {\n lines.push('');\n lines.push('Files deleted (stale contract artefacts):');\n for (const file of output.filesDeleted) {\n lines.push(` • ${file}`);\n }\n }\n\n if (!output.packagesInstalled.skipped) {\n lines.push('');\n lines.push('Packages installed:');\n for (const dep of output.packagesInstalled.deps) {\n lines.push(` • ${dep}`);\n }\n for (const dep of output.packagesInstalled.devDeps) {\n lines.push(` • ${dep} (dev)`);\n }\n }\n\n lines.push('');\n lines.push('Next steps:');\n for (const step of output.nextSteps) {\n lines.push(` ${step}`);\n }\n\n ui.note(lines.join('\\n'), 'Done');\n}\n\n/**\n * Builds the `nextSteps` array from the resolved scaffold state. Steps are\n * ordered by the workflow a user needs to follow: configure connection →\n * (emit if not yet done) → run a starter query → docs / agent skill.\n *\n * The strings are stable and human-readable; agents wanting to act on them\n * should match on substrings (e.g. \"DATABASE_URL\") rather than exact text,\n * since copy may evolve.\n */\nexport function buildNextSteps(options: {\n readonly target: 'postgres' | 'mongodb';\n readonly contractEmitted: boolean;\n readonly emitCommand: string;\n readonly schemaPath: string;\n}): string[] {\n const steps: string[] = [];\n steps.push('1. Set DATABASE_URL in your environment (export it or add it to .env).');\n if (!options.contractEmitted) {\n steps.push(`2. Emit the contract: \\`${options.emitCommand}\\``);\n steps.push(`3. Edit your schema at ${options.schemaPath}, then re-run the emit command.`);\n steps.push(\n '4. Open prisma-next.md for a quick reference on how to write your first typed query.',\n );\n steps.push(\n '5. @prisma-next/agent-skill is registered with your agent runtime — open the project in your IDE and ask the agent to add a model, run a query, or plan a migration.',\n );\n } else {\n steps.push(\n `2. Edit your schema at ${options.schemaPath}, then re-run \\`${options.emitCommand}\\`.`,\n );\n steps.push(\n '3. Open prisma-next.md for a quick reference on how to write your first typed query.',\n );\n steps.push(\n '4. @prisma-next/agent-skill is registered with your agent runtime — open the project in your IDE and ask the agent to add a model, run a query, or plan a migration.',\n );\n }\n return steps;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,MAAa,mBAAmB,KAAK;CACnC,IAAI;CACJ,QAAQ;CACR,WAAW;CACX,YAAY;CACZ,cAAc;;;;;;;;CAQd,cAAc;CACd,mBAAmB;EACjB,SAAS;EACT,MAAM;EACN,SAAS;EACV;CACD,iBAAiB;CACjB,WAAW;CACX,UAAU;CACX,CAAC;;;;;;;AAUF,SAAgB,eAAe,QAA4B;CACzD,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE;;;;;;;;;AAUxC,SAAgB,gBAAgB,IAAgB,QAAoB,OAA0B;CAC5F,IAAI,MAAM,SAAS,MAAM,MACvB;CAGF,KAAK,MAAM,WAAW,OAAO,UAC3B,GAAG,KAAK,QAAQ;CAGlB,MAAM,QAAkB,EAAE;CAC1B,MAAM,KAAK,cAAc,OAAO,SAAS;CACzC,MAAM,KAAK,cAAc,OAAO,YAAY;CAC5C,MAAM,KAAK,cAAc,OAAO,aAAa;CAC7C,MAAM,KAAK,GAAG;CACd,MAAM,KAAK,iBAAiB;CAC5B,KAAK,MAAM,QAAQ,OAAO,cACxB,MAAM,KAAK,OAAO,OAAO;CAG3B,IAAI,OAAO,aAAa,SAAS,GAAG;EAClC,MAAM,KAAK,GAAG;EACd,MAAM,KAAK,4CAA4C;EACvD,KAAK,MAAM,QAAQ,OAAO,cACxB,MAAM,KAAK,OAAO,OAAO;;CAI7B,IAAI,CAAC,OAAO,kBAAkB,SAAS;EACrC,MAAM,KAAK,GAAG;EACd,MAAM,KAAK,sBAAsB;EACjC,KAAK,MAAM,OAAO,OAAO,kBAAkB,MACzC,MAAM,KAAK,OAAO,MAAM;EAE1B,KAAK,MAAM,OAAO,OAAO,kBAAkB,SACzC,MAAM,KAAK,OAAO,IAAI,QAAQ;;CAIlC,MAAM,KAAK,GAAG;CACd,MAAM,KAAK,cAAc;CACzB,KAAK,MAAM,QAAQ,OAAO,WACxB,MAAM,KAAK,KAAK,OAAO;CAGzB,GAAG,KAAK,MAAM,KAAK,KAAK,EAAE,OAAO;;;;;;;;;;;AAYnC,SAAgB,eAAe,SAKlB;CACX,MAAM,QAAkB,EAAE;CAC1B,MAAM,KAAK,yEAAyE;CACpF,IAAI,CAAC,QAAQ,iBAAiB;EAC5B,MAAM,KAAK,2BAA2B,QAAQ,YAAY,IAAI;EAC9D,MAAM,KAAK,0BAA0B,QAAQ,WAAW,iCAAiC;EACzF,MAAM,KACJ,uFACD;EACD,MAAM,KACJ,uKACD;QACI;EACL,MAAM,KACJ,0BAA0B,QAAQ,WAAW,kBAAkB,QAAQ,YAAY,KACpF;EACD,MAAM,KACJ,uFACD;EACD,MAAM,KACJ,uKACD;;CAEH,OAAO"}
1
+ {"version":3,"file":"output-B60Gw5fu.mjs","names":[],"sources":["../src/commands/init/output.ts"],"sourcesContent":["import { type } from 'arktype';\nimport type { GlobalFlags } from '../../utils/global-flags';\nimport type { TerminalUI } from '../../utils/terminal-ui';\n\n/**\n * arktype schema for the structured success document `init --json` writes\n * to stdout (FR1.5). The same shape backs the human-readable outro\n * renderer (FR10), so the two output modes carry identical information.\n *\n * `target` is normalised to the user-facing flag value (`mongodb` rather\n * than the internal `mongo`) so consumers can round-trip the document\n * straight into a follow-up `--target` invocation.\n *\n * The `ok: true` literal is the documented success/error discriminator —\n * see [Style Guide § JSON Semantics](../../../../../../../docs/CLI%20Style%20Guide.md#json-semantics).\n * Error envelopes (`CliErrorEnvelope`) carry `ok: false` so consumers can\n * branch with `if (doc.ok)` without inspecting the rest of the structure.\n */\nexport const InitOutputSchema = type({\n ok: 'true',\n target: \"'postgres'|'mongodb'\",\n authoring: \"'psl'|'typescript'\",\n schemaPath: 'string',\n filesWritten: 'string[]',\n /**\n * FR9.1 — files removed from disk during this run. Populated only on\n * re-init when previously-emitted contract artefacts (`contract.json`,\n * `contract.d.ts`, `start-/end-contract.*`, `ops.json`,\n * `migration.json`) were left behind by an earlier run. Empty on a\n * green-field init.\n */\n filesDeleted: 'string[]',\n packagesInstalled: {\n skipped: 'boolean',\n deps: 'string[]',\n devDeps: 'string[]',\n },\n contractEmitted: 'boolean',\n nextSteps: 'string[]',\n warnings: 'string[]',\n});\n\nexport type InitOutput = typeof InitOutputSchema.infer;\n\n/**\n * Serialises the output document for `--json`. Sorted keys are not enforced\n * — `JSON.stringify` preserves insertion order, and the schema field order\n * is the documented order, which matches what users will see when they\n * `jq .` the result.\n */\nexport function formatInitJson(output: InitOutput): string {\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Renders the human-readable outro on stderr (FR10.1). Re-uses the same\n * data structure as the JSON output so the two stay in lock-step.\n *\n * Warnings come before \"Next steps\" because they describe state the user\n * needs to be aware of before acting on the next-steps list.\n */\nexport function renderInitOutro(ui: TerminalUI, output: InitOutput, flags: GlobalFlags): void {\n if (flags.quiet || flags.json) {\n return;\n }\n\n for (const warning of output.warnings) {\n ui.warn(warning);\n }\n\n const lines: string[] = [];\n lines.push(`Target: ${output.target}`);\n lines.push(`Authoring: ${output.authoring}`);\n lines.push(`Schema: ${output.schemaPath}`);\n lines.push('');\n lines.push('Files written:');\n for (const file of output.filesWritten) {\n lines.push(` • ${file}`);\n }\n\n if (output.filesDeleted.length > 0) {\n lines.push('');\n lines.push('Files deleted (stale contract artefacts):');\n for (const file of output.filesDeleted) {\n lines.push(` • ${file}`);\n }\n }\n\n if (!output.packagesInstalled.skipped) {\n lines.push('');\n lines.push('Packages installed:');\n for (const dep of output.packagesInstalled.deps) {\n lines.push(` • ${dep}`);\n }\n for (const dep of output.packagesInstalled.devDeps) {\n lines.push(` • ${dep} (dev)`);\n }\n }\n\n lines.push('');\n lines.push('Next steps:');\n for (const step of output.nextSteps) {\n lines.push(` ${step}`);\n }\n\n ui.note(lines.join('\\n'), 'Done');\n}\n\n/**\n * Builds the `nextSteps` array from the resolved scaffold state. Steps are\n * ordered by the workflow a user needs to follow: configure connection →\n * (emit if not yet done) → run a starter query → docs / agent skill.\n *\n * The strings are stable and human-readable; agents wanting to act on them\n * should match on substrings (e.g. \"DATABASE_URL\") rather than exact text,\n * since copy may evolve.\n */\nexport function buildNextSteps(options: {\n readonly target: 'postgres' | 'mongodb';\n readonly contractEmitted: boolean;\n readonly emitCommand: string;\n readonly schemaPath: string;\n /**\n * Whether the project-level Prisma Next skills install actually ran\n * and succeeded during this `init`. When false (the user passed\n * `--no-skill` or `--no-install`, so the install was skipped), the\n * \"registered with your agent runtime\" step is omitted — the skip is\n * already surfaced in the warnings array with a manual-install hint.\n */\n readonly skillRegistered: boolean;\n}): string[] {\n const steps: string[] = [];\n let stepNumber = 1;\n const push = (text: string): void => {\n steps.push(`${stepNumber}. ${text}`);\n stepNumber += 1;\n };\n push('Set DATABASE_URL in your environment (export it or add it to .env).');\n if (!options.contractEmitted) {\n push(`Emit the contract: \\`${options.emitCommand}\\``);\n push(`Edit your schema at ${options.schemaPath}, then re-run the emit command.`);\n } else {\n push(`Edit your schema at ${options.schemaPath}, then re-run \\`${options.emitCommand}\\`.`);\n }\n push('Open prisma-next.md for a quick reference on how to write your first typed query.');\n if (options.skillRegistered) {\n push(\n 'Prisma Next skills are registered with your agent runtime — open the project in your IDE and ask the agent to add a model, run a query, or plan a migration.',\n );\n }\n return steps;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,MAAa,mBAAmB,KAAK;CACnC,IAAI;CACJ,QAAQ;CACR,WAAW;CACX,YAAY;CACZ,cAAc;;;;;;;;CAQd,cAAc;CACd,mBAAmB;EACjB,SAAS;EACT,MAAM;EACN,SAAS;EACV;CACD,iBAAiB;CACjB,WAAW;CACX,UAAU;CACX,CAAC;;;;;;;AAUF,SAAgB,eAAe,QAA4B;CACzD,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE;;;;;;;;;AAUxC,SAAgB,gBAAgB,IAAgB,QAAoB,OAA0B;CAC5F,IAAI,MAAM,SAAS,MAAM,MACvB;CAGF,KAAK,MAAM,WAAW,OAAO,UAC3B,GAAG,KAAK,QAAQ;CAGlB,MAAM,QAAkB,EAAE;CAC1B,MAAM,KAAK,cAAc,OAAO,SAAS;CACzC,MAAM,KAAK,cAAc,OAAO,YAAY;CAC5C,MAAM,KAAK,cAAc,OAAO,aAAa;CAC7C,MAAM,KAAK,GAAG;CACd,MAAM,KAAK,iBAAiB;CAC5B,KAAK,MAAM,QAAQ,OAAO,cACxB,MAAM,KAAK,OAAO,OAAO;CAG3B,IAAI,OAAO,aAAa,SAAS,GAAG;EAClC,MAAM,KAAK,GAAG;EACd,MAAM,KAAK,4CAA4C;EACvD,KAAK,MAAM,QAAQ,OAAO,cACxB,MAAM,KAAK,OAAO,OAAO;;CAI7B,IAAI,CAAC,OAAO,kBAAkB,SAAS;EACrC,MAAM,KAAK,GAAG;EACd,MAAM,KAAK,sBAAsB;EACjC,KAAK,MAAM,OAAO,OAAO,kBAAkB,MACzC,MAAM,KAAK,OAAO,MAAM;EAE1B,KAAK,MAAM,OAAO,OAAO,kBAAkB,SACzC,MAAM,KAAK,OAAO,IAAI,QAAQ;;CAIlC,MAAM,KAAK,GAAG;CACd,MAAM,KAAK,cAAc;CACzB,KAAK,MAAM,QAAQ,OAAO,WACxB,MAAM,KAAK,KAAK,OAAO;CAGzB,GAAG,KAAK,MAAM,KAAK,KAAK,EAAE,OAAO;;;;;;;;;;;AAYnC,SAAgB,eAAe,SAalB;CACX,MAAM,QAAkB,EAAE;CAC1B,IAAI,aAAa;CACjB,MAAM,QAAQ,SAAuB;EACnC,MAAM,KAAK,GAAG,WAAW,IAAI,OAAO;EACpC,cAAc;;CAEhB,KAAK,sEAAsE;CAC3E,IAAI,CAAC,QAAQ,iBAAiB;EAC5B,KAAK,wBAAwB,QAAQ,YAAY,IAAI;EACrD,KAAK,uBAAuB,QAAQ,WAAW,iCAAiC;QAEhF,KAAK,uBAAuB,QAAQ,WAAW,kBAAkB,QAAQ,YAAY,KAAK;CAE5F,KAAK,oFAAoF;CACzF,IAAI,QAAQ,iBACV,KACE,+JACD;CAEH,OAAO"}
@@ -1,4 +1,4 @@
1
- import { i as formatErrorOutput, r as formatErrorJson } from "./terminal-ui-C_hFNbAn.mjs";
1
+ import { n as formatErrorOutput, t as formatErrorJson } from "./errors-Cw6kyTyV.mjs";
2
2
  //#region src/utils/result-handler.ts
3
3
  /**
4
4
  * Processes a CLI command result, handling both success and error cases.
@@ -22,4 +22,4 @@ function handleResult(result, flags, ui, onSuccess) {
22
22
  //#endregion
23
23
  export { handleResult as t };
24
24
 
25
- //# sourceMappingURL=result-handler-rmPVKIP2.mjs.map
25
+ //# sourceMappingURL=result-handler-Bm_6dDYg.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"result-handler-rmPVKIP2.mjs","names":[],"sources":["../src/utils/result-handler.ts"],"sourcesContent":["import type { Result } from '@prisma-next/utils/result';\nimport type { CliStructuredError } from './cli-errors';\nimport { formatErrorJson, formatErrorOutput } from './formatters/errors';\nimport type { GlobalFlags } from './global-flags';\nimport type { TerminalUI } from './terminal-ui';\n\n/**\n * Processes a CLI command result, handling both success and error cases.\n * Formats output appropriately and returns the exit code.\n * Never throws - returns exit code for commands to use with process.exit().\n *\n * Error output:\n * - JSON mode: JSON error to stdout (piped) via ui.output(), human sees nothing on stderr.\n * - Interactive: human-readable error to stderr.\n */\nexport function handleResult<T>(\n result: Result<T, CliStructuredError>,\n flags: GlobalFlags,\n ui: TerminalUI,\n onSuccess?: (value: T) => void,\n): number {\n if (result.ok) {\n if (onSuccess) {\n onSuccess(result.value);\n }\n return 0;\n }\n\n // Convert to CLI envelope\n const envelope = result.failure.toEnvelope();\n\n if (flags.json) {\n // JSON error → stdout only\n ui.output(formatErrorJson(envelope));\n } else {\n // Human-readable error → stderr\n ui.error(formatErrorOutput(envelope, flags));\n }\n\n // Infer exit code from error domain: CLI errors = 2, RUN errors = 1\n const exitCode = result.failure.domain === 'CLI' ? 2 : 1;\n return exitCode;\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgB,aACd,QACA,OACA,IACA,WACQ;CACR,IAAI,OAAO,IAAI;EACb,IAAI,WACF,UAAU,OAAO,MAAM;EAEzB,OAAO;;CAIT,MAAM,WAAW,OAAO,QAAQ,YAAY;CAE5C,IAAI,MAAM,MAER,GAAG,OAAO,gBAAgB,SAAS,CAAC;MAGpC,GAAG,MAAM,kBAAkB,UAAU,MAAM,CAAC;CAK9C,OADiB,OAAO,QAAQ,WAAW,QAAQ,IAAI"}
1
+ {"version":3,"file":"result-handler-Bm_6dDYg.mjs","names":[],"sources":["../src/utils/result-handler.ts"],"sourcesContent":["import type { Result } from '@prisma-next/utils/result';\nimport type { CliStructuredError } from './cli-errors';\nimport { formatErrorJson, formatErrorOutput } from './formatters/errors';\nimport type { GlobalFlags } from './global-flags';\nimport type { TerminalUI } from './terminal-ui';\n\n/**\n * Processes a CLI command result, handling both success and error cases.\n * Formats output appropriately and returns the exit code.\n * Never throws - returns exit code for commands to use with process.exit().\n *\n * Error output:\n * - JSON mode: JSON error to stdout (piped) via ui.output(), human sees nothing on stderr.\n * - Interactive: human-readable error to stderr.\n */\nexport function handleResult<T>(\n result: Result<T, CliStructuredError>,\n flags: GlobalFlags,\n ui: TerminalUI,\n onSuccess?: (value: T) => void,\n): number {\n if (result.ok) {\n if (onSuccess) {\n onSuccess(result.value);\n }\n return 0;\n }\n\n // Convert to CLI envelope\n const envelope = result.failure.toEnvelope();\n\n if (flags.json) {\n // JSON error → stdout only\n ui.output(formatErrorJson(envelope));\n } else {\n // Human-readable error → stderr\n ui.error(formatErrorOutput(envelope, flags));\n }\n\n // Infer exit code from error domain: CLI errors = 2, RUN errors = 1\n const exitCode = result.failure.domain === 'CLI' ? 2 : 1;\n return exitCode;\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgB,aACd,QACA,OACA,IACA,WACQ;CACR,IAAI,OAAO,IAAI;EACb,IAAI,WACF,UAAU,OAAO,MAAM;EAEzB,OAAO;;CAIT,MAAM,WAAW,OAAO,QAAQ,YAAY;CAE5C,IAAI,MAAM,MAER,GAAG,OAAO,gBAAgB,SAAS,CAAC;MAGpC,GAAG,MAAM,kBAAkB,UAAU,MAAM,CAAC;CAK9C,OADiB,OAAO,QAAQ,WAAW,QAAQ,IAAI"}
@@ -1,57 +1,5 @@
1
- import { n as formatDim, r as isVerbose, t as createColorFormatter } from "./helpers-eqdN8tH6.mjs";
2
1
  import { bold, cyan, dim, green, red, yellow } from "colorette";
3
2
  import * as clack from "@clack/prompts";
4
- //#region src/utils/formatters/errors.ts
5
- /**
6
- * Formats error output for human-readable display.
7
- */
8
- function formatErrorOutput(error, flags) {
9
- const lines = [];
10
- const useColor = flags.color !== false;
11
- const formatRed = createColorFormatter(useColor, red);
12
- const formatDimText = (text) => formatDim(useColor, text);
13
- lines.push(`${formatRed("✖")} ${error.summary} (${error.code})`);
14
- if (error.why) lines.push(`${formatDimText(` Why: ${error.why}`)}`);
15
- if (error.fix) lines.push(`${formatDimText(` Fix: ${error.fix}`)}`);
16
- if (error.where?.path) {
17
- const whereLine = error.where.line ? `${error.where.path}:${error.where.line}` : error.where.path;
18
- lines.push(`${formatDimText(` Where: ${whereLine}`)}`);
19
- }
20
- if (error.meta?.["conflicts"]) {
21
- const conflicts = error.meta["conflicts"];
22
- if (conflicts.length > 0) {
23
- const maxToShow = isVerbose(flags, 1) ? conflicts.length : Math.min(3, conflicts.length);
24
- const header = isVerbose(flags, 1) ? " Conflicts:" : ` Conflicts (showing ${maxToShow} of ${conflicts.length}):`;
25
- lines.push(`${formatDimText(header)}`);
26
- for (const conflict of conflicts.slice(0, maxToShow)) lines.push(`${formatDimText(` - [${conflict.kind}] ${conflict.summary}`)}`);
27
- if (!isVerbose(flags, 1) && conflicts.length > maxToShow) lines.push(`${formatDimText(" Re-run with -v/--verbose to see all conflicts")}`);
28
- }
29
- }
30
- if (error.meta?.["issues"]) {
31
- const issues = error.meta["issues"];
32
- if (issues.length > 0) {
33
- const maxToShow = isVerbose(flags, 1) ? issues.length : Math.min(3, issues.length);
34
- const header = isVerbose(flags, 1) ? " Issues:" : ` Issues (showing ${maxToShow} of ${issues.length}):`;
35
- lines.push(`${formatDimText(header)}`);
36
- for (const issue of issues.slice(0, maxToShow)) {
37
- const kind = issue.kind ?? "issue";
38
- const message = issue.message ?? "";
39
- lines.push(`${formatDimText(` - [${kind}] ${message}`)}`);
40
- }
41
- if (!isVerbose(flags, 1) && issues.length > maxToShow) lines.push(`${formatDimText(" Re-run with -v/--verbose to see all issues")}`);
42
- }
43
- }
44
- if (error.docsUrl && isVerbose(flags, 1)) lines.push(formatDimText(error.docsUrl));
45
- if (isVerbose(flags, 2) && error.meta) lines.push(`${formatDimText(` Meta: ${JSON.stringify(error.meta, null, 2)}`)}`);
46
- return lines.join("\n");
47
- }
48
- /**
49
- * Formats error output as JSON.
50
- */
51
- function formatErrorJson(error) {
52
- return JSON.stringify(error, null, 2);
53
- }
54
- //#endregion
55
3
  //#region src/utils/shutdown.ts
56
4
  function createShutdownHandler(options) {
57
5
  const exit = options?.exit ?? ((code) => process.exit(code));
@@ -319,6 +267,6 @@ var TerminalUI = class TerminalUI {
319
267
  }
320
268
  };
321
269
  //#endregion
322
- export { formatErrorOutput as i, installShutdownHandlers as n, formatErrorJson as r, TerminalUI as t };
270
+ export { installShutdownHandlers as n, TerminalUI as t };
323
271
 
324
- //# sourceMappingURL=terminal-ui-C_hFNbAn.mjs.map
272
+ //# sourceMappingURL=terminal-ui-XtOQsqe9.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-ui-XtOQsqe9.mjs","names":[],"sources":["../src/utils/shutdown.ts","../src/utils/terminal-ui.ts"],"sourcesContent":["/**\n * Global shutdown controller for graceful SIGINT/SIGTERM handling.\n *\n * The CLI installs signal handlers once at startup. When a signal fires:\n * 1. The AbortController is aborted — in-flight async work (DB queries, emit) can check `signal.aborted`.\n * 2. A 3-second grace timer starts — gives `finally` blocks time to close connections.\n * 3. If the process hasn't exited by then, force-exit with code 130 (128 + SIGINT).\n * 4. A second signal during the grace period force-exits immediately.\n */\n\n/**\n * Creates a shutdown handler with its own AbortController.\n * Exposed for testing — production code uses the singleton below.\n */\nexport interface ShutdownHandler {\n readonly signal: AbortSignal;\n readonly isShuttingDown: () => boolean;\n readonly onSignal: () => void;\n readonly clearGraceTimer: () => void;\n}\n\nexport function createShutdownHandler(options?: {\n readonly exit?: (code: number) => void;\n readonly gracePeriodMs?: number;\n}): ShutdownHandler {\n const exit = options?.exit ?? ((code: number) => process.exit(code));\n const gracePeriodMs = options?.gracePeriodMs ?? 3000;\n\n const controller = new AbortController();\n let shuttingDown = false;\n let graceTimer: ReturnType<typeof setTimeout> | undefined;\n\n const onSignal = () => {\n if (shuttingDown) {\n // Second signal — force exit\n exit(130);\n return;\n }\n shuttingDown = true;\n controller.abort();\n\n // Give finally blocks time to clean up, then force-exit\n graceTimer = setTimeout(() => exit(130), gracePeriodMs);\n graceTimer.unref();\n };\n\n return {\n signal: controller.signal,\n isShuttingDown: () => shuttingDown,\n onSignal,\n clearGraceTimer: () => {\n if (graceTimer !== undefined) {\n clearTimeout(graceTimer);\n graceTimer = undefined;\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Singleton for production use\n// ---------------------------------------------------------------------------\n\nconst globalHandler = createShutdownHandler();\n\n/**\n * The global AbortSignal. Pass this to any async operation that should\n * be cancellable on Ctrl+C (e.g., DB queries, long-running emit).\n */\nexport const shutdownSignal: AbortSignal = globalHandler.signal;\n\n/**\n * Whether a shutdown has been initiated.\n */\nexport function isShuttingDown(): boolean {\n return globalHandler.isShuttingDown();\n}\n\n/**\n * Installs SIGINT and SIGTERM handlers. Call once at CLI startup.\n *\n * - First signal: aborts the controller, starts a 3s grace timer.\n * - Second signal: force-exits immediately.\n */\nlet installed = false;\n\nexport function installShutdownHandlers(): void {\n if (installed) return;\n installed = true;\n process.on('SIGINT', globalHandler.onSignal);\n process.on('SIGTERM', globalHandler.onSignal);\n}\n","import * as clack from '@clack/prompts';\nimport { bold, cyan, dim, green, red, yellow } from 'colorette';\nimport { shutdownSignal } from './shutdown';\n\n/**\n * Composable CLI output abstraction.\n *\n * Follows the Unix convention of separating data from decoration:\n * - **stdout** — data output only (`ui.output()`). This is what scripts and pipes capture.\n * - **stderr** — all decoration (spinners, logs, notes, intro/outro). Visible in terminal, invisible in pipes.\n *\n * Rules:\n * 1. All methods except `output()` and `error()` write to stderr only in interactive mode.\n * 2. `output(data)` always writes to stdout — if a command calls it, there is data to emit.\n * 3. `error()` always writes to stderr — errors matter even when piped.\n * 4. All other decoration is suppressed when piped — `isInteractive` gates every other decoration method.\n * 5. Never write data to stderr — decoration methods are for human context only.\n * 6. Never write decoration to stdout — it breaks pipes, `$(...)` captures, and `> file` redirects.\n */\nexport class TerminalUI {\n /**\n * True when stdout is a TTY (interactive terminal).\n * False when piped (e.g., `prisma-next db verify | jq`).\n */\n readonly isInteractive: boolean;\n\n /**\n * Whether color output is enabled.\n */\n readonly useColor: boolean;\n\n private static readonly stderrOpts = { output: process.stderr } as const;\n\n constructor(options?: {\n readonly color?: boolean | undefined;\n readonly interactive?: boolean | undefined;\n }) {\n // --interactive/--no-interactive override TTY detection\n this.isInteractive = options?.interactive ?? !!process.stdout.isTTY;\n this.useColor = options?.color ?? this.isInteractive;\n }\n\n // ---------------------------------------------------------------------------\n // Decoration → stderr (only in interactive mode)\n // ---------------------------------------------------------------------------\n\n /**\n * Log a message line to stderr. No-op when piped.\n */\n log(message: string): void {\n if (!this.isInteractive) return;\n clack.log.message(message, TerminalUI.stderrOpts);\n }\n\n /**\n * Log a success message to stderr. No-op when piped.\n */\n success(message: string): void {\n if (!this.isInteractive) return;\n clack.log.success(message, TerminalUI.stderrOpts);\n }\n\n /**\n * Log a warning message to stderr. No-op when piped.\n */\n warn(message: string): void {\n if (!this.isInteractive) return;\n clack.log.warn(message, TerminalUI.stderrOpts);\n }\n\n /**\n * Log an error message to stderr. Always writes (errors matter even in pipes).\n */\n error(message: string): void {\n clack.log.error(message, TerminalUI.stderrOpts);\n }\n\n /**\n * Log an info message to stderr. No-op when piped.\n */\n info(message: string): void {\n if (!this.isInteractive) return;\n clack.log.info(message, TerminalUI.stderrOpts);\n }\n\n /**\n * Log a step message to stderr. No-op when piped.\n */\n step(message: string): void {\n if (!this.isInteractive) return;\n clack.log.step(message, TerminalUI.stderrOpts);\n }\n\n /**\n * Display a note box on stderr. No-op when piped.\n */\n note(message: string, title?: string): void {\n if (!this.isInteractive) return;\n clack.note(message, title, TerminalUI.stderrOpts);\n }\n\n /**\n * Display intro banner on stderr. No-op when piped.\n */\n intro(title?: string): void {\n if (!this.isInteractive) return;\n clack.intro(title, TerminalUI.stderrOpts);\n }\n\n /**\n * Display outro banner on stderr. No-op when piped.\n */\n outro(message?: string): void {\n if (!this.isInteractive) return;\n clack.outro(message, TerminalUI.stderrOpts);\n }\n\n /**\n * Create a Clack spinner on stderr with a 100ms delay threshold.\n * The spinner only appears if the operation takes longer than the threshold,\n * avoiding flicker for fast operations. Returns a no-op spinner when not interactive.\n */\n spinner(delayMs = 100): clack.SpinnerResult {\n const noop: clack.SpinnerResult = {\n start: () => {},\n stop: () => {},\n cancel: () => {},\n error: () => {},\n message: () => {},\n clear: () => {},\n get isCancelled() {\n return false;\n },\n };\n\n if (!this.isInteractive) {\n return noop;\n }\n\n // Wrap the real spinner with a delay: only show it after `delayMs`\n let inner: clack.SpinnerResult | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let pendingMsg: string | undefined;\n let settled = false;\n\n const ensureCleared = () => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n // Cancel the spinner if a shutdown signal fires\n const onAbort = () => {\n if (!settled) {\n settled = true;\n ensureCleared();\n if (inner) {\n inner.cancel('Interrupted');\n }\n }\n };\n if (!shutdownSignal.aborted) {\n shutdownSignal.addEventListener('abort', onAbort, { once: true });\n }\n\n return {\n start(msg?: string) {\n pendingMsg = msg;\n timer = setTimeout(() => {\n if (!settled) {\n inner = clack.spinner(TerminalUI.stderrOpts);\n inner.start(pendingMsg);\n }\n }, delayMs);\n },\n stop(msg?: string) {\n settled = true;\n ensureCleared();\n if (inner) {\n inner.stop(msg);\n }\n },\n cancel(msg?: string) {\n settled = true;\n ensureCleared();\n if (inner) {\n inner.cancel(msg);\n }\n },\n error(msg?: string) {\n settled = true;\n ensureCleared();\n if (inner) {\n inner.error(msg);\n }\n },\n message(msg?: string) {\n pendingMsg = msg;\n if (inner) {\n inner.message(msg);\n }\n },\n clear() {\n settled = true;\n ensureCleared();\n if (inner) {\n inner.clear();\n }\n },\n get isCancelled() {\n return inner?.isCancelled ?? false;\n },\n };\n }\n\n /**\n * Prompt for yes/no confirmation on stderr. Returns true if confirmed.\n * In non-interactive mode or when cancelled (Ctrl-C), returns false.\n */\n async confirm(message: string): Promise<boolean> {\n if (!this.isInteractive) return false;\n const result = await clack.confirm({\n message,\n ...TerminalUI.stderrOpts,\n });\n if (clack.isCancel(result)) return false;\n return result;\n }\n\n /**\n * Write a raw line to stderr. No-op when piped.\n * Use for decoration that doesn't fit Clack's log format (e.g. styled headers).\n */\n stderr(message: string): void {\n if (!this.isInteractive) return;\n process.stderr.write(`${message}\\n`);\n }\n\n // ---------------------------------------------------------------------------\n // Data → stdout (only when piped)\n // ---------------------------------------------------------------------------\n\n /**\n * Write machine-readable data to stdout.\n * Always writes — if a command calls output(), there is data to emit.\n *\n * This is what scripts and pipes capture: `prisma-next db verify --json | jq .ok`\n */\n output(data: string): void {\n process.stdout.write(`${data}\\n`);\n }\n\n // ---------------------------------------------------------------------------\n // Color helpers\n // ---------------------------------------------------------------------------\n\n green(text: string): string {\n return this.useColor ? green(text) : text;\n }\n red(text: string): string {\n return this.useColor ? red(text) : text;\n }\n cyan(text: string): string {\n return this.useColor ? cyan(text) : text;\n }\n dim(text: string): string {\n return this.useColor ? dim(text) : text;\n }\n bold(text: string): string {\n return this.useColor ? bold(text) : text;\n }\n yellow(text: string): string {\n return this.useColor ? yellow(text) : text;\n }\n}\n"],"mappings":";;;AAqBA,SAAgB,sBAAsB,SAGlB;CAClB,MAAM,OAAO,SAAS,UAAU,SAAiB,QAAQ,KAAK,KAAK;CACnE,MAAM,gBAAgB,SAAS,iBAAiB;CAEhD,MAAM,aAAa,IAAI,iBAAiB;CACxC,IAAI,eAAe;CACnB,IAAI;CAEJ,MAAM,iBAAiB;EACrB,IAAI,cAAc;GAEhB,KAAK,IAAI;GACT;;EAEF,eAAe;EACf,WAAW,OAAO;EAGlB,aAAa,iBAAiB,KAAK,IAAI,EAAE,cAAc;EACvD,WAAW,OAAO;;CAGpB,OAAO;EACL,QAAQ,WAAW;EACnB,sBAAsB;EACtB;EACA,uBAAuB;GACrB,IAAI,eAAe,KAAA,GAAW;IAC5B,aAAa,WAAW;IACxB,aAAa,KAAA;;;EAGlB;;AAOH,MAAM,gBAAgB,uBAAuB;;;;;AAM7C,MAAa,iBAA8B,cAAc;;;;;;;AAezD,IAAI,YAAY;AAEhB,SAAgB,0BAAgC;CAC9C,IAAI,WAAW;CACf,YAAY;CACZ,QAAQ,GAAG,UAAU,cAAc,SAAS;CAC5C,QAAQ,GAAG,WAAW,cAAc,SAAS;;;;;;;;;;;;;;;;;;;ACvE/C,IAAa,aAAb,MAAa,WAAW;;;;;CAKtB;;;;CAKA;CAEA,OAAwB,aAAa,EAAE,QAAQ,QAAQ,QAAQ;CAE/D,YAAY,SAGT;EAED,KAAK,gBAAgB,SAAS,eAAe,CAAC,CAAC,QAAQ,OAAO;EAC9D,KAAK,WAAW,SAAS,SAAS,KAAK;;;;;CAUzC,IAAI,SAAuB;EACzB,IAAI,CAAC,KAAK,eAAe;EACzB,MAAM,IAAI,QAAQ,SAAS,WAAW,WAAW;;;;;CAMnD,QAAQ,SAAuB;EAC7B,IAAI,CAAC,KAAK,eAAe;EACzB,MAAM,IAAI,QAAQ,SAAS,WAAW,WAAW;;;;;CAMnD,KAAK,SAAuB;EAC1B,IAAI,CAAC,KAAK,eAAe;EACzB,MAAM,IAAI,KAAK,SAAS,WAAW,WAAW;;;;;CAMhD,MAAM,SAAuB;EAC3B,MAAM,IAAI,MAAM,SAAS,WAAW,WAAW;;;;;CAMjD,KAAK,SAAuB;EAC1B,IAAI,CAAC,KAAK,eAAe;EACzB,MAAM,IAAI,KAAK,SAAS,WAAW,WAAW;;;;;CAMhD,KAAK,SAAuB;EAC1B,IAAI,CAAC,KAAK,eAAe;EACzB,MAAM,IAAI,KAAK,SAAS,WAAW,WAAW;;;;;CAMhD,KAAK,SAAiB,OAAsB;EAC1C,IAAI,CAAC,KAAK,eAAe;EACzB,MAAM,KAAK,SAAS,OAAO,WAAW,WAAW;;;;;CAMnD,MAAM,OAAsB;EAC1B,IAAI,CAAC,KAAK,eAAe;EACzB,MAAM,MAAM,OAAO,WAAW,WAAW;;;;;CAM3C,MAAM,SAAwB;EAC5B,IAAI,CAAC,KAAK,eAAe;EACzB,MAAM,MAAM,SAAS,WAAW,WAAW;;;;;;;CAQ7C,QAAQ,UAAU,KAA0B;EAC1C,MAAM,OAA4B;GAChC,aAAa;GACb,YAAY;GACZ,cAAc;GACd,aAAa;GACb,eAAe;GACf,aAAa;GACb,IAAI,cAAc;IAChB,OAAO;;GAEV;EAED,IAAI,CAAC,KAAK,eACR,OAAO;EAIT,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI,UAAU;EAEd,MAAM,sBAAsB;GAC1B,IAAI,UAAU,KAAA,GAAW;IACvB,aAAa,MAAM;IACnB,QAAQ,KAAA;;;EAKZ,MAAM,gBAAgB;GACpB,IAAI,CAAC,SAAS;IACZ,UAAU;IACV,eAAe;IACf,IAAI,OACF,MAAM,OAAO,cAAc;;;EAIjC,IAAI,CAAC,eAAe,SAClB,eAAe,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;EAGnE,OAAO;GACL,MAAM,KAAc;IAClB,aAAa;IACb,QAAQ,iBAAiB;KACvB,IAAI,CAAC,SAAS;MACZ,QAAQ,MAAM,QAAQ,WAAW,WAAW;MAC5C,MAAM,MAAM,WAAW;;OAExB,QAAQ;;GAEb,KAAK,KAAc;IACjB,UAAU;IACV,eAAe;IACf,IAAI,OACF,MAAM,KAAK,IAAI;;GAGnB,OAAO,KAAc;IACnB,UAAU;IACV,eAAe;IACf,IAAI,OACF,MAAM,OAAO,IAAI;;GAGrB,MAAM,KAAc;IAClB,UAAU;IACV,eAAe;IACf,IAAI,OACF,MAAM,MAAM,IAAI;;GAGpB,QAAQ,KAAc;IACpB,aAAa;IACb,IAAI,OACF,MAAM,QAAQ,IAAI;;GAGtB,QAAQ;IACN,UAAU;IACV,eAAe;IACf,IAAI,OACF,MAAM,OAAO;;GAGjB,IAAI,cAAc;IAChB,OAAO,OAAO,eAAe;;GAEhC;;;;;;CAOH,MAAM,QAAQ,SAAmC;EAC/C,IAAI,CAAC,KAAK,eAAe,OAAO;EAChC,MAAM,SAAS,MAAM,MAAM,QAAQ;GACjC;GACA,GAAG,WAAW;GACf,CAAC;EACF,IAAI,MAAM,SAAS,OAAO,EAAE,OAAO;EACnC,OAAO;;;;;;CAOT,OAAO,SAAuB;EAC5B,IAAI,CAAC,KAAK,eAAe;EACzB,QAAQ,OAAO,MAAM,GAAG,QAAQ,IAAI;;;;;;;;CAatC,OAAO,MAAoB;EACzB,QAAQ,OAAO,MAAM,GAAG,KAAK,IAAI;;CAOnC,MAAM,MAAsB;EAC1B,OAAO,KAAK,WAAW,MAAM,KAAK,GAAG;;CAEvC,IAAI,MAAsB;EACxB,OAAO,KAAK,WAAW,IAAI,KAAK,GAAG;;CAErC,KAAK,MAAsB;EACzB,OAAO,KAAK,WAAW,KAAK,KAAK,GAAG;;CAEtC,IAAI,MAAsB;EACxB,OAAO,KAAK,WAAW,IAAI,KAAK,GAAG;;CAErC,KAAK,MAAsB;EACzB,OAAO,KAAK,WAAW,KAAK,KAAK,GAAG;;CAEtC,OAAO,MAAsB;EAC3B,OAAO,KAAK,WAAW,OAAO,KAAK,GAAG"}
@@ -1,4 +1,4 @@
1
- import { t as CliStructuredError } from "./cli-errors-B9OBbled.mjs";
1
+ import { t as CliStructuredError } from "./cli-errors-DdcjVLJV.mjs";
2
2
  import { Result } from "@prisma-next/utils/result";
3
3
  import { ContractSourceDiagnostics, ContractSourceProvider } from "@prisma-next/config/config-types";
4
4
  import { ControlAdapterDescriptor, ControlDriverDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyDescriptor, ControlFamilyInstance, ControlTargetDescriptor, CoreSchemaView, MigrationPlanOperation, MigrationPlannerConflict, OperationPreview, SignDatabaseResult, VerifyDatabaseResult, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
@@ -131,7 +131,7 @@ type OnControlProgress = (event: ControlProgressEvent) => void;
131
131
  * Options for the verify operation.
132
132
  */
133
133
  interface VerifyOptions {
134
- /** Contract or unvalidated JSON - validated at runtime via familyInstance.validateContract() */
134
+ /** Contract or unvalidated JSON - validated at runtime via familyInstance.deserializeContract() */
135
135
  readonly contract: unknown;
136
136
  /**
137
137
  * Database connection. If provided, verify will connect before executing.
@@ -146,7 +146,7 @@ interface VerifyOptions {
146
146
  * Options for the schemaVerify operation.
147
147
  */
148
148
  interface SchemaVerifyOptions {
149
- /** Contract or unvalidated JSON - validated at runtime via familyInstance.validateContract() */
149
+ /** Contract or unvalidated JSON - validated at runtime via familyInstance.deserializeContract() */
150
150
  readonly contract: unknown;
151
151
  /**
152
152
  * Whether to use strict mode for schema verification.
@@ -167,7 +167,7 @@ interface SchemaVerifyOptions {
167
167
  * Options for the sign operation.
168
168
  */
169
169
  interface SignOptions {
170
- /** Contract or unvalidated JSON - validated at runtime via familyInstance.validateContract() */
170
+ /** Contract or unvalidated JSON - validated at runtime via familyInstance.deserializeContract() */
171
171
  readonly contract: unknown;
172
172
  /**
173
173
  * Path to the contract file (for metadata in the result).
@@ -190,7 +190,7 @@ interface SignOptions {
190
190
  * Options for the dbInit operation.
191
191
  */
192
192
  interface DbInitOptions {
193
- /** Contract or unvalidated JSON - validated at runtime via familyInstance.validateContract() */
193
+ /** Contract or unvalidated JSON - validated at runtime via familyInstance.deserializeContract() */
194
194
  readonly contract: unknown;
195
195
  /**
196
196
  * Mode for the dbInit operation.
@@ -218,7 +218,7 @@ interface DbInitOptions {
218
218
  * Options for the dbUpdate operation.
219
219
  */
220
220
  interface DbUpdateOptions {
221
- /** Contract or unvalidated JSON - validated at runtime via familyInstance.validateContract() */
221
+ /** Contract or unvalidated JSON - validated at runtime via familyInstance.deserializeContract() */
222
222
  readonly contract: unknown;
223
223
  /**
224
224
  * Mode for the dbUpdate operation.
@@ -259,7 +259,13 @@ interface DbUpdateOptions {
259
259
  * portion of the verifier.
260
260
  */
261
261
  interface DbVerifyOptions {
262
- readonly contract: unknown;
262
+ /**
263
+ * Already-deserialized contract. Callers cross the family
264
+ * `deserializeContract` seam at the read site (TML-2536) and pass the
265
+ * hydrated value through unchanged; this op no longer re-runs the
266
+ * SerializerBase pipeline.
267
+ */
268
+ readonly contract: Contract;
263
269
  readonly migrationsDir: string;
264
270
  readonly strict: boolean;
265
271
  readonly skipSchema: boolean;
@@ -853,4 +859,4 @@ interface ControlClient {
853
859
  }
854
860
  //#endregion
855
861
  export { ExecuteDbVerifyOptions as A, EmitSuccess as C, SchemaVerifyOptions as D, OnControlProgress as E, executeDbVerify as M, SignOptions as O, EmitResult as S, MigrationApplyPathDecision as T, DbUpdateSuccess as _, ControlClient as a, EmitFailureCode as b, DbInitFailure as c, DbInitResult as d, DbInitSuccess as f, DbUpdateResult as g, DbUpdateOptions as h, ControlActionName as i, ExecuteDbVerifyResult as j, VerifyOptions as k, DbInitFailureCode as l, DbUpdateFailureCode as m, ContractEmitOptions as n, ControlClientOptions as o, DbUpdateFailure as p, ContractEmitResult as r, ControlProgressEvent as s, AggregatePerSpaceExecutionEntry as t, DbInitOptions as u, EmitContractConfig as v, IntrospectOptions as w, EmitOptions as x, EmitFailure as y };
856
- //# sourceMappingURL=types-LItU7E4l.d.mts.map
862
+ //# sourceMappingURL=types-0aS865QN.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-0aS865QN.d.mts","names":[],"sources":["../src/control-api/operations/db-verify.ts","../src/control-api/types.ts"],"mappings":";;;;;;;;;;;;;;AAwCA;;;;;UAAiB,sBAAA;EAAA,SACN,MAAA,EAAQ,qBAAA,CAAsB,SAAA,EAAW,SAAA;EAAA,SACzC,cAAA,EAAgB,qBAAA,CAAsB,SAAA;EAAA,SACtC,QAAA,EAAU,QAAA;EAAA,SACV,aAAA;EAAA,SACA,QAAA,EAAU,SAAA;EAAA,SACV,cAAA,EAAgB,aAAA,CAAc,0BAAA,CAA2B,SAAA,EAAW,SAAA;EAAA,SACpE,mBAAA,EAAqB,aAAA,CAAc,8BAAA,CAA+B,SAAA,EAAW,SAAA;EAAA,SAC7E,IAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA,GAAa,iBAAA;AAAA;;;;;;;;;;;;;UAeP,sBAAA;EAAA,SACN,aAAA,EAAe,WAAA,SAAoB,0BAAA;EAAA,SACnC,WAAA;EAAA,SACA,UAAA;AAAA;AAAA,KAGC,qBAAA,GAAwB,MAAA,CAAO,sBAAA,EAAwB,kBAAA;;;;;;;;;;;;;;;;;iBAkB7C,eAAA,oDAAA,CACpB,OAAA,EAAS,sBAAA,CAAuB,SAAA,EAAW,SAAA,IAC1C,OAAA,CAAQ,qBAAA;;;;;;AApDX;;;;;;;;UCDiB,oBAAA;EAAA,SAEN,MAAA,EAAQ,uBAAA;EAAA,SAER,MAAA,EAAQ,uBAAA;EAAA,SAER,OAAA,EAAS,wBAAA;EDCqB;EAAA,SCE9B,MAAA,GAAS,uBAAA;EAAA,SAET,cAAA,GAAiB,aAAA,CAAc,0BAAA;EDH8C;;;;;EAAA,SCS7E,UAAA;AAAA;;;;KAUC,iBAAA;;;;;;;;;;;;;;KAwBA,oBAAA;EAAA,SAEG,MAAA,EAAQ,iBAAA;EAAA,SACR,IAAA;EAAA,SACA,MAAA;EAAA,SACA,YAAA;EAAA,SACA,KAAA;AAAA;EAAA,SAGA,MAAA,EAAQ,iBAAA;EAAA,SACR,IAAA;EAAA,SACA,MAAA;EAAA,SACA,OAAA;AAAA;;ADpCf;;;;KC4CY,iBAAA,IAAqB,KAAA,EAAO,oBAAA;;;;UASvB,aAAA;EDlDI;EAAA,SCoDV,QAAA;EDjDC;;;;;EAAA,SCuDD,UAAA;EDvD+B;EAAA,SCyD/B,UAAA,GAAa,iBAAA;AAAA;;;;UAMP,mBAAA;ED7CK;EAAA,SC+CX,QAAA;ED/C0B;;;;;EAAA,SCqD1B,MAAA;EDnDD;;;;;EAAA,SCyDC,UAAA;ED1DkC;EAAA,SC4DlC,UAAA,GAAa,iBAAA;AAAA;;;;UAMP,WAAA;;WAEN,QAAA;EAxHM;;;EAAA,SA4HN,YAAA;EAxHQ;;;EAAA,SA4HR,UAAA;EArHiB;;;;;EAAA,SA2HjB,UAAA;EAlIQ;EAAA,SAoIR,UAAA,GAAa,iBAAA;AAAA;;;;UAMP,aAAA;EAnIyB;EAAA,SAqI/B,QAAA;EA/HU;;AAUrB;;;EAVqB,SAqIV,IAAA;EA3HkB;AAwB7B;;;;EAxB6B,SAiIlB,UAAA;EAvGY;;;;;;EAAA,SA8GZ,aAAA;EAtGI;EAAA,SAwGJ,UAAA,GAAa,iBAAA;AAAA;;;AA9FxB;UAoGiB,eAAA;;WAEN,QAAA;EAtGiD;AAS5D;;;;EAT4D,SA4GjD,IAAA;EA3FA;;;;;EAAA,SAiGA,UAAA;EAzFyB;;;;;;;EAAA,SAiGzB,cAAA;EAjF8B;;AAMzC;;;;EANyC,SAwF9B,aAAA;EA5EA;EAAA,SA8EA,UAAA,GAAa,iBAAA;AAAA;;;;;AA5DxB;;;;UAuEiB,eAAA;EA/DN;;;;;;EAAA,SAsEA,QAAA,EAAU,QAAA;EAAA,SACV,aAAA;EAAA,SACA,MAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA,GAAa,iBAAA;AAAA;;;;UAMP,iBAAA;EA9BwB;;AAWzC;EAXyC,SAkC9B,MAAA;;;;;;WAMA,UAAA;EAnBA;EAAA,SAqBA,UAAA,GAAa,iBAAA;AAAA;;;;UAMP,kBAAA;EAlBA;;;EAAA,SAsBN,MAAA,EAAQ,sBAAA;EAlBR;;;;EAAA,SAuBA,MAAA;AAAA;AATX;;;AAAA,UAeiB,WAAA;EAXN;;;EAAA,SAeA,cAAA,EAAgB,kBAAA;EAVV;EAAA,SAYN,UAAA,GAAa,iBAAA;AAAA;;;;;;;;;AAmBxB;;;;UAAiB,+BAAA;EAAA,SACN,OAAA;EAQA;EAAA,SANA,IAAA;EAOE;;;;;EAAA,SADF,UAAA,EAAY,aAAA;IAAA,SACV,EAAA;IAAA,SACA,KAAA;IAAA,SACA,cAAA;EAAA;EAkBY;;;;;EAAA,SAXd,MAAA;IAAA,SACE,WAAA;EAAA;AAAA;;;;UAOI,aAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;IAAA,SACE,UAAA,EAAY,aAAA;MAAA,SACV,EAAA;MAAA,SACA,KAAA;MAAA,SACA,cAAA;IAAA;IAiBF;;;;;;;IAAA,SARA,OAAA,GAAU,gBAAA;EAAA;EAAA,SAEZ,WAAA;IAAA,SACE,WAAA;IAAA,SACA,WAAA;EAAA;EAAA,SAEF,SAAA;IAAA,SACE,iBAAA;IAAA,SACA,kBAAA;EAAA;EAAA,SAEF,MAAA;IAAA,SACE,WAAA;IAAA,SACA,WAAA;EAAA;EA0BI;;;;;;;EAAA,SAjBN,QAAA,GAAW,aAAA,CAAc,+BAAA;EAAA,SACzB,OAAA;AAAA;;;;KAMC,iBAAA;;;;UAKK,aAAA;EAAA,SACN,IAAA,EAAM,iBAAA;EAAA,SACN,OAAA;EAAA,SACA,GAAA;EAAA,SACA,SAAA,EAAW,aAAA,CAAc,wBAAA;EAAA,SACzB,IAAA,EAAM,MAAA;EAAA,SACN,MAAA;IAAA,SACE,WAAA;IAAA,SACA,WAAA;EAAA;EAAA,SAEF,WAAA;IAAA,SACE,WAAA;IAAA,SACA,WAAA;EAAA;AAAA;;AAab;;;KALY,YAAA,GAAe,MAAA,CAAO,aAAA,EAAe,aAAA;;;;UAKhC,eAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;IAAA,SACE,UAAA,EAAY,aAAA;MAAA,SACV,EAAA;MAAA,SACA,KAAA;MAAA,SACA,cAAA;IAAA;IAAA;;;;;;;IAAA,SASF,OAAA,GAAU,gBAAA;EAAA;EAAA,SAEZ,WAAA;IAAA,SACE,WAAA;IAAA,SACA,WAAA;EAAA;EAAA,SAEF,SAAA;IAAA,SACE,iBAAA;IAAA,SACA,kBAAA;EAAA;EAAA,SAEF,MAAA;IAAA,SACE,WAAA;IAAA,SACA,WAAA;EAAA;EAakB;;AAK/B;;EAL+B,SAPpB,QAAA,GAAW,aAAA,CAAc,+BAAA;EAAA,SACzB,OAAA;AAAA;;;;KAMC,mBAAA;;;;UAKK,eAAA;EAAA,SACN,IAAA,EAAM,mBAAA;EAAA,SACN,OAAA;EAAA,SACA,GAAA;EAAA,SACA,SAAA,EAAW,aAAA,CAAc,wBAAA;EAAA,SACzB,IAAA,EAAM,MAAA;AAAA;;AAOjB;;;KAAY,cAAA,GAAiB,MAAA,CAAO,eAAA,EAAiB,eAAA;;;;;UAMpC,WAAA;EANmB;EAAA,SAQzB,WAAA;EARyD;EAAA,SAUzD,aAAA;EAJM;EAAA,SAMN,WAAA;;WAEA,YAAA;EANA;EAAA,SAQA,WAAA;AAAA;;;;KAMC,eAAA;AAAZ;;;AAAA,UAQiB,WAAA;EAAA,SACN,IAAA,EAAM,eAAA;EAAA,SACN,OAAA;EAAA,SACA,GAAA;EAAA,SACA,IAAA,EAAM,MAAA;EAAA,SACN,WAAA,GAAc,yBAAA;AAAA;;;;;KAOb,UAAA,GAAa,MAAA,CAAO,WAAA,EAAa,WAAA;;;;;;;;;AAA7C;;;UAiBiB,qBAAA;EAjB4B;EAAA,SAmBlC,QAAA;EAnBoB;EAAA,SAqBpB,aAAA;EArBc;;;;;EAAA,SA2Bd,oBAAA,EAAsB,aAAA,CAAc,sBAAA;EAVT;;;;;EAAA,SAgB3B,OAAA;EAoB8B;;;;;EAAA,SAd9B,aAAA;EANA;;;;;;EAAA,SAaA,OAAA;EAO8B;AAuCzC;;;EAvCyC,SAF9B,UAAA;EA0CA;EAAA,SAxCA,UAAA,GAAa,iBAAA;AAAA;;;AAiFxB;;;;;;;;;;;UA1CiB,0BAAA;EAAA,SACN,OAAA;EAAA,SACA,OAAA;EAAA,SACA,aAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,kBAAA;AAAA;;;AA2DX;;;;;AAKA;;;;;;;;;AAAA,UA7CiB,0BAAA;EAAA,SACN,QAAA;EAAA,SACA,MAAA;EAAA,SACA,gBAAA;EAAA,SACA,eAAA;EAAA,SACA,OAAA;EAAA,SACA,kBAAA;EAAA,SACA,mBAAA;EAAA,SACA,YAAA;IAAA,SACE,OAAA;IAAA,SACA,aAAA;IAAA,SACA,IAAA;IAAA,SACA,EAAA;IAAA,SACA,UAAA;EAAA;AAAA;AAAA,UAII,qBAAA;EAAA,SACN,iBAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA,WAAkB,0BAAA;EAAA,SAClB,OAAA;EAwDA;;;;;EAAA,SAlDA,QAAA,EAAU,aAAA,CAAc,+BAAA;EA8DlB;;;;;;EAAA,SAvDN,YAAA,GAAe,0BAAA;AAAA;;;;KAMd,yBAAA;;AAqFZ;;UAhFiB,qBAAA;EAAA,SACN,IAAA,EAAM,yBAAA;EAAA,SACN,OAAA;EAAA,SACA,GAAA;EAAA,SACA,IAAA,EAAM,MAAA;AAAA;;;;KAML,oBAAA,GAAuB,MAAA,CAAO,qBAAA,EAAuB,qBAAA;;;;;;;;;;;;;UAkBhD,mBAAA;EA+J+B;EAAA,SA7JrC,UAAA;EA6JS;EAAA,SA3JT,MAAA,GAAS,WAAA;EAwKsC;EAAA,SAtK/C,UAAA,GAAa,iBAAA;AAAA;;;;;;;;UAUP,kBAAA;EAyMoB;EAAA,SAvM1B,WAAA;EA0CT;EAAA,SAxCS,aAAA;EAqDD;EAAA,SAnDC,WAAA;EA0DT;EAAA,SAxDS,KAAA;IAiET,sDA/DW,IAAA,UA+DJ;IAAA,SA7DI,GAAA;EAAA;EAsEX;;;;;EAAA,SA/DS,iBAAA;AAAA;;;;;;;;;;;UAiBM,aAAA;EA6EqB;;;;;;;EArEpC,IAAA;EA4Fc;;;;;;;;;;;EA/Ed,OAAA,CAAQ,UAAA,aAAuB,OAAA;EA2GV;;;;;EApGrB,KAAA,IAAS,OAAA;EAsHT;;;;;;;EA7GA,MAAA,CAAO,OAAA,EAAS,aAAA,GAAgB,OAAA,CAAQ,oBAAA;EAgI1B;;;;;;;EAvHd,YAAA,CAAa,OAAA,EAAS,mBAAA,GAAsB,OAAA,CAAQ,0BAAA;;;;;;;;;EAUpD,IAAA,CAAK,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,kBAAA;;;;;;;;;EAUpC,MAAA,CAAO,OAAA,EAAS,aAAA,GAAgB,OAAA,CAAQ,YAAA;;;;;;;;;;EAWxC,QAAA,CAAS,OAAA,EAAS,eAAA,GAAkB,OAAA,CAAQ,cAAA;;;;;;;;;;;;;;EAe5C,QAAA,CAAS,OAAA,EAAS,eAAA,GAAkB,OAAA,CAAQ,qBAAA;;;;;;;EAQ5C,UAAA,IAAc,OAAA,CAAQ,oBAAA;;;;;;EAOtB,cAAA,IAAkB,OAAA,CAAQ,WAAA,SAAoB,oBAAA;;;;;;;;;;;;EAa9C,cAAA,CAAe,OAAA,EAAS,qBAAA,GAAwB,OAAA,CAAQ,oBAAA;;;;;;;EAQxD,UAAA,CAAW,OAAA,GAAU,iBAAA,GAAoB,OAAA;;;;;;;;EASzC,YAAA,CAAa,QAAA,YAAoB,cAAA;;;;;;;;EASjC,gBAAA,CAAiB,QAAA,YAAoB,cAAA;;;;;;;;;EAUrC,kBAAA,CAAmB,UAAA,WAAqB,sBAAA,KAA2B,gBAAA;;;;;;;;EASnE,IAAA,CAAK,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;AAAA"}
@@ -381,4 +381,4 @@ function formatSignJson(result) {
381
381
  //#endregion
382
382
  export { formatSignJson as a, formatVerifyOutput as c, formatSchemaVerifyOutput as i, formatIntrospectOutput as n, formatSignOutput as o, formatSchemaVerifyJson as r, formatVerifyJson as s, formatIntrospectJson as t };
383
383
 
384
- //# sourceMappingURL=verify-CiwNWM9N.mjs.map
384
+ //# sourceMappingURL=verify-D7ypCCe6.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-CiwNWM9N.mjs","names":[],"sources":["../src/utils/formatters/verify.ts"],"sourcesContent":["import type {\n CoreSchemaView,\n IntrospectSchemaResult,\n SchemaTreeNode,\n SchemaVerificationNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} 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// ============================================================================\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 counts: VerifyDatabaseSchemaResult['schema']['counts'];\n readonly strict: boolean;\n };\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.mode === 'full' && result.schema && isVerbose(flags, 1)) {\n lines.push(\n `${formatDimText(` schema: pass=${result.schema.counts.pass} warn=${result.schema.counts.warn} fail=${result.schema.counts.fail}`)}`,\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 ...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 * Matches the style of renderSchemaVerificationTree for consistency.\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 * Renders a schema verification tree structure from SchemaVerificationNode.\n * Similar to renderSchemaTree but for verification nodes with status-based colors and glyphs.\n */\nfunction renderSchemaVerificationTree(\n node: SchemaVerificationNode,\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 status glyph and color based on status\n let statusGlyph = '';\n let statusColor: (text: string) => string = (text) => text;\n if (useColor) {\n switch (node.status) {\n case 'pass':\n statusGlyph = '✔';\n statusColor = green;\n break;\n case 'warn':\n statusGlyph = '⚠';\n statusColor = (text) => (useColor ? yellow(text) : text);\n break;\n case 'fail':\n statusGlyph = '✖';\n statusColor = red;\n break;\n }\n } else {\n switch (node.status) {\n case 'pass':\n statusGlyph = '✔';\n break;\n case 'warn':\n statusGlyph = '⚠';\n break;\n case 'fail':\n statusGlyph = '✖';\n break;\n }\n }\n\n // Format node label with color based on kind\n // For column nodes, we need to parse the name to color code different parts\n let labelColor: (text: string) => string = (text) => text;\n let formattedLabel: string = node.name;\n\n if (useColor) {\n switch (node.kind) {\n case 'contract':\n case 'schema':\n labelColor = bold;\n formattedLabel = labelColor(node.name);\n break;\n case 'table': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.name.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n formattedLabel = dim(node.name);\n }\n break;\n }\n case 'columns':\n labelColor = dim;\n formattedLabel = labelColor(node.name);\n break;\n case 'column': {\n // Parse column name format: \"columnName: contractType -> nativeType (nullability)\"\n // Color code: column name (cyan), contract type (default), native type (dim), nullability (dim)\n const columnMatch = node.name.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"contractType -> nativeType (nullability)\"\n // Match contract type (can contain /, @, etc.), arrow, native type, then nullability in parentheses\n const typeMatch = rest.match(/^([^\\s→]+)\\s*→\\s*([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2] && typeMatch[3]) {\n const contractType = typeMatch[1];\n const nativeType = typeMatch[2];\n const nullability = typeMatch[3];\n formattedLabel = `${cyan(columnName)}: ${contractType} → ${dim(nativeType)} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match (e.g., no native type or no nullability)\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.name;\n }\n break;\n }\n case 'type':\n case 'nullability':\n labelColor = (text) => text; // Default color\n formattedLabel = labelColor(node.name);\n break;\n case 'primaryKey': {\n // Parse \"primary key: columnName\" format - color \"primary key\" dim, columnName cyan\n const pkMatch = node.name.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n formattedLabel = dim(node.name);\n }\n break;\n }\n case 'foreignKey':\n case 'unique':\n case 'index':\n labelColor = dim;\n formattedLabel = labelColor(node.name);\n break;\n case 'dependency': {\n // Parse specific extension message formats\n // \"database is postgres\" -> dim \"database is\", cyan \"postgres\"\n const dbMatch = node.name.match(/^database is\\s+(.+)$/);\n if (dbMatch?.[1]) {\n const dbName = dbMatch[1];\n formattedLabel = `${dim('database is')} ${cyan(dbName)}`;\n } else {\n // \"vector extension is enabled\" -> dim everything except extension name\n // Match pattern: \"extensionName extension is enabled\"\n const extMatch = node.name.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 name with magenta\n labelColor = magenta;\n formattedLabel = labelColor(node.name);\n }\n }\n break;\n }\n default:\n formattedLabel = node.name;\n break;\n }\n } else {\n formattedLabel = node.name;\n }\n\n const statusGlyphColored = statusColor(statusGlyph);\n\n // Build the label with optional message for failure/warn nodes\n let nodeLabel = formattedLabel;\n if (\n (node.status === 'fail' || node.status === 'warn') &&\n node.message &&\n node.message.length > 0\n ) {\n // Always show message for failure/warn nodes - it provides crucial context\n // For parent nodes, the message summarizes child failures\n // For leaf nodes, the message explains the specific issue\n const messageText = formatDimText(`(${node.message})`);\n nodeLabel = `${formattedLabel} ${messageText}`;\n }\n\n // Root node renders without tree characters or | prefix\n // Root node renders without tree characters or prefix\n if (isRoot) {\n lines.push(`${statusGlyphColored} ${nodeLabel}`);\n } else {\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${formatDimText(treeChar)}─ `;\n lines.push(`${prefix}${treePrefix}${statusGlyphColored} ${nodeLabel}`);\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 = renderSchemaVerificationTree(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 schema verification.\n */\nexport function formatSchemaVerifyOutput(\n result: VerifyDatabaseSchemaResult,\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 formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Render verification tree first\n const treeLines = renderSchemaVerificationTree(result.schema.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n lines.push(...treeLines);\n\n // Add counts and timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n lines.push(\n `${formatDimText(` pass=${result.schema.counts.pass} warn=${result.schema.counts.warn} fail=${result.schema.counts.fail}`)}`,\n );\n }\n\n // Blank line before summary\n lines.push('');\n\n // Summary line at the end: summary 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.\n */\nexport function formatSchemaVerifyJson(result: VerifyDatabaseSchemaResult): string {\n return JSON.stringify(result, 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":";;;;;;;AAgDA,SAAgB,mBACd,QACA,OACQ;CACR,IAAI,MAAM,OACR,OAAO;CAGT,MAAM,QAAkB,EAAE;CAE1B,MAAM,WAAW,MAAM,UAAU;CACjC,MAAM,cAAc,qBAAqB,UAAU,MAAM;CACzD,MAAM,eAAe,qBAAqB,UAAU,OAAO;CAC3D,MAAM,iBAAiB,SAAiB,UAAU,UAAU,KAAK;CACjE,MAAM,mBACJ,OAAO,SAAS,SACZ,kBAAkB,OAAO,QAAQ,SAAS,cAAc,kBACxD;CAEN,MAAM,KAAK,GAAG,YAAY,IAAI,CAAC,GAAG,OAAO,UAAU;CACnD,MAAM,KAAK,GAAG,cAAc,mBAAmB,mBAAmB,GAAG;CACrE,MAAM,KAAK,GAAG,cAAc,kBAAkB,OAAO,SAAS,cAAc,GAAG;CAC/E,IAAI,OAAO,SAAS,aAClB,MAAM,KAAK,GAAG,cAAc,kBAAkB,OAAO,SAAS,cAAc,GAAG;CAEjF,IAAI,OAAO,SAAS,UAAU,OAAO,UAAU,UAAU,OAAO,EAAE,EAChE,MAAM,KACJ,GAAG,cAAc,kBAAkB,OAAO,OAAO,OAAO,KAAK,QAAQ,OAAO,OAAO,OAAO,KAAK,QAAQ,OAAO,OAAO,OAAO,OAAO,GACpI;CAEH,IAAI,OAAO,SAAS;EAClB,MAAM,KAAK,GAAG;EACd,MAAM,KAAK,GAAG,aAAa,IAAI,CAAC,GAAG,OAAO,UAAU;;CAGtD,IAAI,UAAU,OAAO,EAAE,EAAE;EACvB,IAAI,OAAO,sBACT,MAAM,KACJ,GAAG,cAAc,sEAAsE,GACxF;EAEH,MAAM,KAAK,GAAG,cAAc,iBAAiB,OAAO,QAAQ,MAAM,IAAI,GAAG;;CAG3E,OAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAgB,iBAAiB,QAA8C;CAC7E,MAAM,SAAS;EACb,IAAI,OAAO;EACX,SAAS,OAAO;EAChB,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,GAAG,UAAU,UAAU,OAAO,OAAO;EACrC,QAAQ,OAAO;EACf,GAAG,UAAU,iBAAiB,OAAO,cAAc;EACnD,GAAG,UAAU,wBAAwB,OAAO,qBAAqB;EACjE,GAAG,UAAU,UAAU,OAAO,OAAO;EACrC,GAAG,UAAU,WAAW,OAAO,QAAQ;EACvC,GAAG,UAAU,QAAQ,OAAO,KAAK;EACjC,SAAS,OAAO;EACjB;CAED,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE;;;;;AAMxC,SAAgB,qBAAqB,QAAiD;CACpF,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE;;;;;;AAOxC,SAAS,iBACP,MACA,OACA,SAOU;CACV,MAAM,EAAE,QAAQ,QAAQ,UAAU,eAAe,SAAS,UAAU;CACpE,MAAM,QAAkB,EAAE;CAG1B,IAAI,iBAAyB,KAAK;CAElC,IAAI,UACF,QAAQ,KAAK,MAAb;EACE,KAAK;GACH,iBAAiB,KAAK,KAAK,MAAM;GACjC;EACF,KAAK,UAAU;GAEb,MAAM,aAAa,KAAK,MAAM,MAAM,iBAAiB;GACrD,IAAI,aAAa,IAAI;IACnB,MAAM,YAAY,WAAW;IAC7B,iBAAiB,GAAG,IAAI,QAAQ,CAAC,GAAG,KAAK,UAAU;UAGnD,iBAAiB,KAAK,KAAK,MAAM;GAEnC;;EAEF,KAAK;GAEH,iBAAiB,IAAI,KAAK,MAAM;GAChC;EAEF,KAAK,SAAS;GAGZ,MAAM,cAAc,KAAK,MAAM,MAAM,oBAAoB;GACzD,IAAI,cAAc,MAAM,YAAY,IAAI;IACtC,MAAM,aAAa,YAAY;IAC/B,MAAM,OAAO,YAAY;IAEzB,MAAM,YAAY,KAAK,MAAM,4BAA4B;IACzD,IAAI,YAAY,MAAM,UAAU,IAAI;KAClC,MAAM,cAAc,UAAU;KAC9B,MAAM,cAAc,UAAU;KAC9B,iBAAiB,GAAG,KAAK,WAAW,CAAC,IAAI,YAAY,GAAG,IAAI,YAAY;WAGxE,iBAAiB,GAAG,KAAK,WAAW,CAAC,IAAI;UAG3C,iBAAiB,KAAK;GAExB;;EAEF,KAAK,SAAS;GAGZ,MAAM,UAAU,KAAK,MAAM,MAAM,wBAAwB;GACzD,IAAI,UAAU,IAAI;IAChB,MAAM,cAAc,QAAQ;IAC5B,iBAAiB,GAAG,IAAI,cAAc,CAAC,IAAI,KAAK,YAAY;UACvD;IAEL,MAAM,cAAc,KAAK,MAAM,MAAM,kBAAkB;IACvD,IAAI,cAAc,IAAI;KACpB,MAAM,OAAO,YAAY;KACzB,iBAAiB,GAAG,IAAI,SAAS,CAAC,GAAG,KAAK,KAAK;WAC1C;KAEL,MAAM,aAAa,KAAK,MAAM,MAAM,6BAA6B;KACjE,IAAI,aAAa,IAAI;MACnB,MAAM,cAAc,WAAW,KAAK,GAAG,IAAI,SAAS,CAAC,KAAK;MAC1D,MAAM,OAAO,WAAW;MACxB,iBAAiB,GAAG,cAAc,IAAI,QAAQ,CAAC,GAAG,KAAK,KAAK;YAE5D,iBAAiB,IAAI,KAAK,MAAM;;;GAItC;;EAEF,KAAK,cAAc;GAGjB,MAAM,WAAW,KAAK,MAAM,MAAM,sCAAsC;GACxE,IAAI,WAAW,MAAM,SAAS,IAAI;IAChC,MAAM,UAAU,SAAS;IACzB,MAAM,OAAO,SAAS;IACtB,iBAAiB,GAAG,KAAK,QAAQ,CAAC,GAAG,IAAI,KAAK;UAG9C,iBAAiB,QAAQ,KAAK,MAAM;GAEtC;;EAEF;GACE,iBAAiB,KAAK;GACtB;;CAKN,IAAI,QACF,MAAM,KAAK,eAAe;MACrB;EAEL,MAAM,aAAa,GAAG,cADL,SAAS,MAAM,IACa,CAAC;EAC9C,MAAM,KAAK,GAAG,SAAS,aAAa,iBAAiB;;CAIvD,IAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;EAC7C,MAAM,cAAc,SAAS,KAAK,GAAG,SAAS,SAAS,QAAQ,GAAG,cAAc,IAAI,CAAC;EACrF,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;GAC7C,MAAM,QAAQ,KAAK,SAAS;GAC5B,IAAI,CAAC,OAAO;GAEZ,MAAM,aAAa,iBAAiB,OAAO,OAAO;IAChD,QAFkB,MAAM,KAAK,SAAS,SAAS;IAG/C,QAAQ;IACR;IACA;IACA,QAAQ;IACT,CAAC;GACF,MAAM,KAAK,GAAG,WAAW;;;CAI7B,OAAO;;;;;AAMT,SAAgB,uBACd,QACA,YACA,OACQ;CACR,IAAI,MAAM,OACR,OAAO;CAGT,MAAM,QAAkB,EAAE;CAE1B,MAAM,WAAW,MAAM,UAAU;CACjC,MAAM,iBAAiB,SAAiB,UAAU,UAAU,KAAK;CAEjE,IAAI,YAAY;EAEd,MAAM,YAAY,iBAAiB,WAAW,MAAM,OAAO;GACzD,QAAQ;GACR,QAAQ;GACR;GACA;GACA,QAAQ;GACT,CAAC;EACF,MAAM,KAAK,GAAG,UAAU;QACnB;EAEL,MAAM,KAAK,KAAK,OAAO,UAAU;EACjC,IAAI,UAAU,OAAO,EAAE,EAAE;GACvB,MAAM,KAAK,aAAa,OAAO,OAAO,SAAS,GAAG,OAAO,OAAO,KAAK;GACrE,IAAI,OAAO,MAAM,OACf,MAAM,KAAK,eAAe,OAAO,KAAK,QAAQ;;;CAMpD,IAAI,UAAU,OAAO,EAAE,EACrB,MAAM,KAAK,GAAG,cAAc,iBAAiB,OAAO,QAAQ,MAAM,IAAI,GAAG;CAG3E,OAAO,MAAM,KAAK,KAAK;;;;;;AAOzB,SAAS,6BACP,MACA,OACA,SAOU;CACV,MAAM,EAAE,QAAQ,QAAQ,UAAU,eAAe,SAAS,UAAU;CACpE,MAAM,QAAkB,EAAE;CAG1B,IAAI,cAAc;CAClB,IAAI,eAAyC,SAAS;CACtD,IAAI,UACF,QAAQ,KAAK,QAAb;EACE,KAAK;GACH,cAAc;GACd,cAAc;GACd;EACF,KAAK;GACH,cAAc;GACd,eAAe,SAAU,WAAW,OAAO,KAAK,GAAG;GACnD;EACF,KAAK;GACH,cAAc;GACd,cAAc;GACd;;MAGJ,QAAQ,KAAK,QAAb;EACE,KAAK;GACH,cAAc;GACd;EACF,KAAK;GACH,cAAc;GACd;EACF,KAAK;GACH,cAAc;GACd;;CAMN,IAAI,cAAwC,SAAS;CACrD,IAAI,iBAAyB,KAAK;CAElC,IAAI,UACF,QAAQ,KAAK,MAAb;EACE,KAAK;EACL,KAAK;GACH,aAAa;GACb,iBAAiB,WAAW,KAAK,KAAK;GACtC;EACF,KAAK,SAAS;GAEZ,MAAM,aAAa,KAAK,KAAK,MAAM,iBAAiB;GACpD,IAAI,aAAa,IAAI;IACnB,MAAM,YAAY,WAAW;IAC7B,iBAAiB,GAAG,IAAI,QAAQ,CAAC,GAAG,KAAK,UAAU;UAEnD,iBAAiB,IAAI,KAAK,KAAK;GAEjC;;EAEF,KAAK;GACH,aAAa;GACb,iBAAiB,WAAW,KAAK,KAAK;GACtC;EACF,KAAK,UAAU;GAGb,MAAM,cAAc,KAAK,KAAK,MAAM,oBAAoB;GACxD,IAAI,cAAc,MAAM,YAAY,IAAI;IACtC,MAAM,aAAa,YAAY;IAC/B,MAAM,OAAO,YAAY;IAGzB,MAAM,YAAY,KAAK,MAAM,4CAA4C;IACzE,IAAI,YAAY,MAAM,UAAU,MAAM,UAAU,IAAI;KAClD,MAAM,eAAe,UAAU;KAC/B,MAAM,aAAa,UAAU;KAC7B,MAAM,cAAc,UAAU;KAC9B,iBAAiB,GAAG,KAAK,WAAW,CAAC,IAAI,aAAa,KAAK,IAAI,WAAW,CAAC,GAAG,IAAI,YAAY;WAG9F,iBAAiB,GAAG,KAAK,WAAW,CAAC,IAAI;UAG3C,iBAAiB,KAAK;GAExB;;EAEF,KAAK;EACL,KAAK;GACH,cAAc,SAAS;GACvB,iBAAiB,WAAW,KAAK,KAAK;GACtC;EACF,KAAK,cAAc;GAEjB,MAAM,UAAU,KAAK,KAAK,MAAM,wBAAwB;GACxD,IAAI,UAAU,IAAI;IAChB,MAAM,cAAc,QAAQ;IAC5B,iBAAiB,GAAG,IAAI,cAAc,CAAC,IAAI,KAAK,YAAY;UAE5D,iBAAiB,IAAI,KAAK,KAAK;GAEjC;;EAEF,KAAK;EACL,KAAK;EACL,KAAK;GACH,aAAa;GACb,iBAAiB,WAAW,KAAK,KAAK;GACtC;EACF,KAAK,cAAc;GAGjB,MAAM,UAAU,KAAK,KAAK,MAAM,uBAAuB;GACvD,IAAI,UAAU,IAAI;IAChB,MAAM,SAAS,QAAQ;IACvB,iBAAiB,GAAG,IAAI,cAAc,CAAC,GAAG,KAAK,OAAO;UACjD;IAGL,MAAM,WAAW,KAAK,KAAK,MAAM,sCAAsC;IACvE,IAAI,WAAW,MAAM,SAAS,IAAI;KAChC,MAAM,UAAU,SAAS;KACzB,MAAM,OAAO,SAAS;KACtB,iBAAiB,GAAG,KAAK,QAAQ,CAAC,GAAG,IAAI,KAAK;WACzC;KAEL,aAAa;KACb,iBAAiB,WAAW,KAAK,KAAK;;;GAG1C;;EAEF;GACE,iBAAiB,KAAK;GACtB;;MAGJ,iBAAiB,KAAK;CAGxB,MAAM,qBAAqB,YAAY,YAAY;CAGnD,IAAI,YAAY;CAChB,KACG,KAAK,WAAW,UAAU,KAAK,WAAW,WAC3C,KAAK,WACL,KAAK,QAAQ,SAAS,GACtB;EAIA,MAAM,cAAc,cAAc,IAAI,KAAK,QAAQ,GAAG;EACtD,YAAY,GAAG,eAAe,GAAG;;CAKnC,IAAI,QACF,MAAM,KAAK,GAAG,mBAAmB,GAAG,YAAY;MAC3C;EAEL,MAAM,aAAa,GAAG,cADL,SAAS,MAAM,IACa,CAAC;EAC9C,MAAM,KAAK,GAAG,SAAS,aAAa,mBAAmB,GAAG,YAAY;;CAIxE,IAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;EAC7C,MAAM,cAAc,SAAS,KAAK,GAAG,SAAS,SAAS,QAAQ,GAAG,cAAc,IAAI,CAAC;EACrF,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;GAC7C,MAAM,QAAQ,KAAK,SAAS;GAC5B,IAAI,CAAC,OAAO;GAEZ,MAAM,aAAa,6BAA6B,OAAO,OAAO;IAC5D,QAFkB,MAAM,KAAK,SAAS,SAAS;IAG/C,QAAQ;IACR;IACA;IACA,QAAQ;IACT,CAAC;GACF,MAAM,KAAK,GAAG,WAAW;;;CAI7B,OAAO;;;;;AAMT,SAAgB,yBACd,QACA,OACQ;CACR,IAAI,MAAM,OACR,OAAO;CAGT,MAAM,QAAkB,EAAE;CAE1B,MAAM,WAAW,MAAM,UAAU;CACjC,MAAM,cAAc,qBAAqB,UAAU,MAAM;CACzD,MAAM,YAAY,qBAAqB,UAAU,IAAI;CACrD,MAAM,iBAAiB,SAAiB,UAAU,UAAU,KAAK;CAGjE,MAAM,YAAY,6BAA6B,OAAO,OAAO,MAAM,OAAO;EACxE,QAAQ;EACR,QAAQ;EACR;EACA;EACA,QAAQ;EACT,CAAC;CACF,MAAM,KAAK,GAAG,UAAU;CAGxB,IAAI,UAAU,OAAO,EAAE,EAAE;EACvB,MAAM,KAAK,GAAG,cAAc,iBAAiB,OAAO,QAAQ,MAAM,IAAI,GAAG;EACzE,MAAM,KACJ,GAAG,cAAc,UAAU,OAAO,OAAO,OAAO,KAAK,QAAQ,OAAO,OAAO,OAAO,KAAK,QAAQ,OAAO,OAAO,OAAO,OAAO,GAC5H;;CAIH,MAAM,KAAK,GAAG;CAGd,IAAI,OAAO,IACT,MAAM,KAAK,GAAG,YAAY,IAAI,CAAC,GAAG,OAAO,UAAU;MAC9C;EACL,MAAM,WAAW,OAAO,OAAO,KAAK,OAAO,KAAK,KAAK;EACrD,MAAM,KAAK,GAAG,UAAU,IAAI,CAAC,GAAG,OAAO,UAAU,WAAW;;CAG9D,OAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAgB,uBAAuB,QAA4C;CACjF,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE;;;;;AAUxC,SAAgB,iBAAiB,QAA4B,OAA4B;CACvF,IAAI,MAAM,OACR,OAAO;CAGT,MAAM,QAAkB,EAAE;CAE1B,MAAM,WAAW,MAAM,UAAU;CACjC,MAAM,cAAc,qBAAqB,UAAU,MAAM;CACzD,MAAM,iBAAiB,SAAiB,UAAU,UAAU,KAAK;CAEjE,IAAI,OAAO,IAAI;EAEb,MAAM,KAAK,GAAG,YAAY,IAAI,CAAC,kBAAkB;EAGjD,MAAM,eAAe,OAAO,OAAO,UAAU,eAAe;EAC5D,MAAM,cAAc,OAAO,SAAS;EAEpC,MAAM,KAAK,GAAG,cAAc,WAAW,eAAe,GAAG;EACzD,MAAM,KAAK,GAAG,cAAc,WAAW,cAAc,GAAG;EAExD,IAAI,UAAU,OAAO,EAAE,EAAE;GACvB,IAAI,OAAO,SAAS,aAClB,MAAM,KAAK,GAAG,cAAc,kBAAkB,OAAO,SAAS,cAAc,GAAG;GAEjF,IAAI,OAAO,OAAO,UAAU,aAC1B,MAAM,KACJ,GAAG,cAAc,2BAA2B,OAAO,OAAO,SAAS,cAAc,GAClF;GAEH,MAAM,KAAK,GAAG,cAAc,iBAAiB,OAAO,QAAQ,MAAM,IAAI,GAAG;;;CAI7E,OAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAgB,eAAe,QAAoC;CACjE,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE"}
1
+ {"version":3,"file":"verify-D7ypCCe6.mjs","names":[],"sources":["../src/utils/formatters/verify.ts"],"sourcesContent":["import type {\n CoreSchemaView,\n IntrospectSchemaResult,\n SchemaTreeNode,\n SchemaVerificationNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} 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// ============================================================================\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 counts: VerifyDatabaseSchemaResult['schema']['counts'];\n readonly strict: boolean;\n };\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.mode === 'full' && result.schema && isVerbose(flags, 1)) {\n lines.push(\n `${formatDimText(` schema: pass=${result.schema.counts.pass} warn=${result.schema.counts.warn} fail=${result.schema.counts.fail}`)}`,\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 ...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 * Matches the style of renderSchemaVerificationTree for consistency.\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 * Renders a schema verification tree structure from SchemaVerificationNode.\n * Similar to renderSchemaTree but for verification nodes with status-based colors and glyphs.\n */\nfunction renderSchemaVerificationTree(\n node: SchemaVerificationNode,\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 status glyph and color based on status\n let statusGlyph = '';\n let statusColor: (text: string) => string = (text) => text;\n if (useColor) {\n switch (node.status) {\n case 'pass':\n statusGlyph = '✔';\n statusColor = green;\n break;\n case 'warn':\n statusGlyph = '⚠';\n statusColor = (text) => (useColor ? yellow(text) : text);\n break;\n case 'fail':\n statusGlyph = '✖';\n statusColor = red;\n break;\n }\n } else {\n switch (node.status) {\n case 'pass':\n statusGlyph = '✔';\n break;\n case 'warn':\n statusGlyph = '⚠';\n break;\n case 'fail':\n statusGlyph = '✖';\n break;\n }\n }\n\n // Format node label with color based on kind\n // For column nodes, we need to parse the name to color code different parts\n let labelColor: (text: string) => string = (text) => text;\n let formattedLabel: string = node.name;\n\n if (useColor) {\n switch (node.kind) {\n case 'contract':\n case 'schema':\n labelColor = bold;\n formattedLabel = labelColor(node.name);\n break;\n case 'table': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.name.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n formattedLabel = dim(node.name);\n }\n break;\n }\n case 'columns':\n labelColor = dim;\n formattedLabel = labelColor(node.name);\n break;\n case 'column': {\n // Parse column name format: \"columnName: contractType -> nativeType (nullability)\"\n // Color code: column name (cyan), contract type (default), native type (dim), nullability (dim)\n const columnMatch = node.name.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"contractType -> nativeType (nullability)\"\n // Match contract type (can contain /, @, etc.), arrow, native type, then nullability in parentheses\n const typeMatch = rest.match(/^([^\\s→]+)\\s*→\\s*([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2] && typeMatch[3]) {\n const contractType = typeMatch[1];\n const nativeType = typeMatch[2];\n const nullability = typeMatch[3];\n formattedLabel = `${cyan(columnName)}: ${contractType} → ${dim(nativeType)} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match (e.g., no native type or no nullability)\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.name;\n }\n break;\n }\n case 'type':\n case 'nullability':\n labelColor = (text) => text; // Default color\n formattedLabel = labelColor(node.name);\n break;\n case 'primaryKey': {\n // Parse \"primary key: columnName\" format - color \"primary key\" dim, columnName cyan\n const pkMatch = node.name.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n formattedLabel = dim(node.name);\n }\n break;\n }\n case 'foreignKey':\n case 'unique':\n case 'index':\n labelColor = dim;\n formattedLabel = labelColor(node.name);\n break;\n case 'dependency': {\n // Parse specific extension message formats\n // \"database is postgres\" -> dim \"database is\", cyan \"postgres\"\n const dbMatch = node.name.match(/^database is\\s+(.+)$/);\n if (dbMatch?.[1]) {\n const dbName = dbMatch[1];\n formattedLabel = `${dim('database is')} ${cyan(dbName)}`;\n } else {\n // \"vector extension is enabled\" -> dim everything except extension name\n // Match pattern: \"extensionName extension is enabled\"\n const extMatch = node.name.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 name with magenta\n labelColor = magenta;\n formattedLabel = labelColor(node.name);\n }\n }\n break;\n }\n default:\n formattedLabel = node.name;\n break;\n }\n } else {\n formattedLabel = node.name;\n }\n\n const statusGlyphColored = statusColor(statusGlyph);\n\n // Build the label with optional message for failure/warn nodes\n let nodeLabel = formattedLabel;\n if (\n (node.status === 'fail' || node.status === 'warn') &&\n node.message &&\n node.message.length > 0\n ) {\n // Always show message for failure/warn nodes - it provides crucial context\n // For parent nodes, the message summarizes child failures\n // For leaf nodes, the message explains the specific issue\n const messageText = formatDimText(`(${node.message})`);\n nodeLabel = `${formattedLabel} ${messageText}`;\n }\n\n // Root node renders without tree characters or | prefix\n // Root node renders without tree characters or prefix\n if (isRoot) {\n lines.push(`${statusGlyphColored} ${nodeLabel}`);\n } else {\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${formatDimText(treeChar)}─ `;\n lines.push(`${prefix}${treePrefix}${statusGlyphColored} ${nodeLabel}`);\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 = renderSchemaVerificationTree(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 schema verification.\n */\nexport function formatSchemaVerifyOutput(\n result: VerifyDatabaseSchemaResult,\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 formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Render verification tree first\n const treeLines = renderSchemaVerificationTree(result.schema.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n lines.push(...treeLines);\n\n // Add counts and timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n lines.push(\n `${formatDimText(` pass=${result.schema.counts.pass} warn=${result.schema.counts.warn} fail=${result.schema.counts.fail}`)}`,\n );\n }\n\n // Blank line before summary\n lines.push('');\n\n // Summary line at the end: summary 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.\n */\nexport function formatSchemaVerifyJson(result: VerifyDatabaseSchemaResult): string {\n return JSON.stringify(result, 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",
3
- "version": "0.8.0",
3
+ "version": "0.9.0-dev.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -14,14 +14,14 @@
14
14
  "dependencies": {
15
15
  "@clack/prompts": "^1.3.0",
16
16
  "@dagrejs/dagre": "^3.0.0",
17
- "@prisma-next/config": "0.8.0",
18
- "@prisma-next/contract": "0.8.0",
19
- "@prisma-next/emitter": "0.8.0",
20
- "@prisma-next/errors": "0.8.0",
21
- "@prisma-next/framework-components": "0.8.0",
22
- "@prisma-next/migration-tools": "0.8.0",
23
- "@prisma-next/psl-printer": "0.8.0",
24
- "@prisma-next/utils": "0.8.0",
17
+ "@prisma-next/config": "0.9.0-dev.1",
18
+ "@prisma-next/contract": "0.9.0-dev.1",
19
+ "@prisma-next/emitter": "0.9.0-dev.1",
20
+ "@prisma-next/errors": "0.9.0-dev.1",
21
+ "@prisma-next/framework-components": "0.9.0-dev.1",
22
+ "@prisma-next/migration-tools": "0.9.0-dev.1",
23
+ "@prisma-next/psl-printer": "0.9.0-dev.1",
24
+ "@prisma-next/utils": "0.9.0-dev.1",
25
25
  "arktype": "^2.1.29",
26
26
  "c12": "^3.3.4",
27
27
  "clipanion": "4.0.0-rc.4",
@@ -37,7 +37,7 @@
37
37
  "wrap-ansi": "^10.0.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@prisma-next/cli": "0.8.0"
40
+ "@prisma-next/cli": "0.9.0-dev.1"
41
41
  },
42
42
  "publishConfig": {
43
43
  "access": "public"
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli-errors-D3_sMh2K.mjs","names":[],"sources":["../src/utils/cli-errors.ts"],"sourcesContent":["/**\n * Re-export all domain error factories from @prisma-next/errors for convenience.\n * CLI-specific errors (e.g., Commander argument validation in the main CLI, or\n * clipanion parse errors in the migration-file CLI) can be added here if needed.\n */\nexport type { CliErrorConflict, CliErrorEnvelope } from '@prisma-next/errors/control';\n\nimport {\n CliStructuredError,\n errorConfigFileNotFound,\n errorConfigValidation,\n errorContractConfigMissing,\n errorContractMissingExtensionPacks,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFamilyReadMarkerSqlRequired,\n errorFileNotFound,\n errorMigrationCliInvalidConfigArg,\n errorMigrationCliUnknownFlag,\n errorMigrationPlanningFailed,\n errorQueryRunnerFactoryRequired,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '@prisma-next/errors/control';\nimport { errorRuntime } from '@prisma-next/errors/execution';\nimport type { MigrationToolsError } from '@prisma-next/migration-tools/errors';\n\nexport {\n ERROR_CODE_DESTRUCTIVE_CHANGES,\n errorDestructiveChanges,\n errorHashMismatch,\n errorMarkerMissing,\n errorMarkerRequired,\n errorRunnerFailed,\n errorRuntime,\n errorSchemaVerificationFailed,\n errorTargetMismatch,\n} from '@prisma-next/errors/execution';\nexport {\n errorMigrationFileMissing,\n errorMigrationInvalidDefaultExport,\n errorMigrationPlanNotArray,\n errorUnfilledPlaceholder,\n placeholder,\n} from '@prisma-next/errors/migration';\nexport {\n CliStructuredError,\n errorConfigFileNotFound,\n errorConfigValidation,\n errorContractConfigMissing,\n errorContractMissingExtensionPacks,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFamilyReadMarkerSqlRequired,\n errorFileNotFound,\n errorMigrationCliInvalidConfigArg,\n errorMigrationCliUnknownFlag,\n errorMigrationPlanningFailed,\n errorQueryRunnerFactoryRequired,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n};\n\n/**\n * Maps a `MigrationToolsError` raised by the migration-tools loader/graph\n * surface (`readMigrationPackage`, `readMigrationsDir`, `readRefs`,\n * `resolveRef`, `reconstructGraph`, ...) into a CLI `errorRuntime` envelope.\n *\n * The full `error.details` payload is forwarded into `meta` so machine\n * consumers (`--json`) see structural fields like `dir`, `storedHash`,\n * `computedHash` (for `MIGRATION.HASH_MISMATCH`) alongside the stable\n * `code`. The user-visible `summary`/`why`/`fix` text is unchanged.\n *\n * Callers are expected to gate on `MigrationToolsError.is(error)` first\n * (mirroring the original inline pattern); non-`MigrationToolsError`\n * values are caller-classified (rethrow, wrap with command-specific\n * `errorUnexpected`, etc.).\n */\nexport function mapMigrationToolsError(error: MigrationToolsError): CliStructuredError {\n return errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAgFA,SAAgB,uBAAuB,OAAgD;CACrF,OAAO,aAAa,MAAM,SAAS;EACjC,KAAK,MAAM;EACX,KAAK,MAAM;EACX,MAAM;GAAE,MAAM,MAAM;GAAM,GAAI,MAAM,WAAW,EAAE;GAAG;EACrD,CAAC"}