@prisma-next/cli 0.3.0-dev.163 → 0.3.0-dev.164

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 (93) hide show
  1. package/dist/agent-skill-mongo.md +106 -0
  2. package/dist/agent-skill-postgres.md +106 -0
  3. package/dist/cli.mjs +27 -4
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/{client-yYtotiSX.mjs → client-DiUkJAeN.mjs} +4 -80
  6. package/dist/client-DiUkJAeN.mjs.map +1 -0
  7. package/dist/commands/contract-emit.d.mts.map +1 -1
  8. package/dist/commands/contract-emit.mjs +6 -1
  9. package/dist/commands/contract-infer.mjs +7 -1
  10. package/dist/commands/db-init.mjs +6 -4
  11. package/dist/commands/db-init.mjs.map +1 -1
  12. package/dist/commands/db-schema.mjs +7 -3
  13. package/dist/commands/db-schema.mjs.map +1 -1
  14. package/dist/commands/db-sign.mjs +6 -4
  15. package/dist/commands/db-sign.mjs.map +1 -1
  16. package/dist/commands/db-update.mjs +6 -4
  17. package/dist/commands/db-update.mjs.map +1 -1
  18. package/dist/commands/db-verify.mjs +6 -4
  19. package/dist/commands/db-verify.mjs.map +1 -1
  20. package/dist/commands/migration-apply.mjs +5 -3
  21. package/dist/commands/migration-apply.mjs.map +1 -1
  22. package/dist/commands/migration-new.mjs +2 -1
  23. package/dist/commands/migration-new.mjs.map +1 -1
  24. package/dist/commands/migration-plan.mjs +3 -2
  25. package/dist/commands/migration-plan.mjs.map +1 -1
  26. package/dist/commands/migration-ref.d.mts +1 -1
  27. package/dist/commands/migration-ref.mjs +2 -1
  28. package/dist/commands/migration-ref.mjs.map +1 -1
  29. package/dist/commands/migration-show.d.mts +1 -1
  30. package/dist/commands/migration-show.mjs +4 -3
  31. package/dist/commands/migration-show.mjs.map +1 -1
  32. package/dist/commands/migration-status.mjs +6 -1
  33. package/dist/commands/migration-verify.mjs +3 -2
  34. package/dist/commands/migration-verify.mjs.map +1 -1
  35. package/dist/{contract-emit-Bk_eEDKu.mjs → contract-emit-D2wDXfyo.mjs} +8 -4
  36. package/dist/{contract-emit-Bk_eEDKu.mjs.map → contract-emit-D2wDXfyo.mjs.map} +1 -1
  37. package/dist/contract-emit-Zm_sd1wQ.mjs +112 -0
  38. package/dist/contract-emit-Zm_sd1wQ.mjs.map +1 -0
  39. package/dist/contract-emit-kN-IkKTE.mjs +6 -0
  40. package/dist/contract-enrichment-CGW6mm-E.mjs +79 -0
  41. package/dist/contract-enrichment-CGW6mm-E.mjs.map +1 -0
  42. package/dist/{contract-infer-suMDmFSG.mjs → contract-infer-DozZT511.mjs} +4 -3
  43. package/dist/{contract-infer-suMDmFSG.mjs.map → contract-infer-DozZT511.mjs.map} +1 -1
  44. package/dist/exports/control-api.mjs +7 -108
  45. package/dist/exports/index.mjs +6 -1
  46. package/dist/exports/index.mjs.map +1 -1
  47. package/dist/{extract-operation-statements-BVlb3jxp.mjs → extract-operation-statements-DZUJNmL3.mjs} +2 -2
  48. package/dist/{extract-operation-statements-BVlb3jxp.mjs.map → extract-operation-statements-DZUJNmL3.mjs.map} +1 -1
  49. package/dist/{extract-sql-ddl-6EVSOThm.mjs → extract-sql-ddl-DDMX-9mz.mjs} +1 -1
  50. package/dist/{extract-sql-ddl-6EVSOThm.mjs.map → extract-sql-ddl-DDMX-9mz.mjs.map} +1 -1
  51. package/dist/init-6Pvm_esG.mjs +430 -0
  52. package/dist/init-6Pvm_esG.mjs.map +1 -0
  53. package/dist/{inspect-live-schema-HMutsJYh.mjs → inspect-live-schema-BYnhztxZ.mjs} +4 -4
  54. package/dist/{inspect-live-schema-HMutsJYh.mjs.map → inspect-live-schema-BYnhztxZ.mjs.map} +1 -1
  55. package/dist/{migration-command-scaffold-Dg7CKKCg.mjs → migration-command-scaffold-CntCcntR.mjs} +4 -4
  56. package/dist/{migration-command-scaffold-Dg7CKKCg.mjs.map → migration-command-scaffold-CntCcntR.mjs.map} +1 -1
  57. package/dist/{migration-status-BqfVmC0w.mjs → migration-status-CJANY4yr.mjs} +4 -3
  58. package/dist/{migration-status-BqfVmC0w.mjs.map → migration-status-CJANY4yr.mjs.map} +1 -1
  59. package/dist/{migrations-Bv8oeiY_.mjs → migrations-DTZBYXm1.mjs} +2 -2
  60. package/dist/{migrations-Bv8oeiY_.mjs.map → migrations-DTZBYXm1.mjs.map} +1 -1
  61. package/dist/{progress-adapter-D4x8SbJa.mjs → progress-adapter-B-YvmcDu.mjs} +1 -1
  62. package/dist/{progress-adapter-D4x8SbJa.mjs.map → progress-adapter-B-YvmcDu.mjs.map} +1 -1
  63. package/dist/quick-reference-mongo.md +93 -0
  64. package/dist/quick-reference-postgres.md +91 -0
  65. package/dist/{terminal-ui-N5tR-ob5.mjs → result-handler-oK_vA-Fn.mjs} +3 -273
  66. package/dist/result-handler-oK_vA-Fn.mjs.map +1 -0
  67. package/dist/terminal-ui-C5k88MmW.mjs +274 -0
  68. package/dist/terminal-ui-C5k88MmW.mjs.map +1 -0
  69. package/dist/validate-contract-deps-esa-VQ0h.mjs +37 -0
  70. package/dist/validate-contract-deps-esa-VQ0h.mjs.map +1 -0
  71. package/dist/{verify-WARh5TjK.mjs → verify-DlFQ2FOw.mjs} +2 -2
  72. package/dist/{verify-WARh5TjK.mjs.map → verify-DlFQ2FOw.mjs.map} +1 -1
  73. package/package.json +17 -16
  74. package/src/cli.ts +5 -0
  75. package/src/commands/contract-emit.ts +7 -0
  76. package/src/commands/init/detect-package-manager.ts +47 -0
  77. package/src/commands/init/index.ts +21 -0
  78. package/src/commands/init/init.ts +203 -0
  79. package/src/commands/init/templates/agent-skill-mongo.md +106 -0
  80. package/src/commands/init/templates/agent-skill-postgres.md +106 -0
  81. package/src/commands/init/templates/agent-skill.ts +19 -0
  82. package/src/commands/init/templates/code-templates.ts +168 -0
  83. package/src/commands/init/templates/quick-reference-mongo.md +93 -0
  84. package/src/commands/init/templates/quick-reference-postgres.md +91 -0
  85. package/src/commands/init/templates/quick-reference.ts +19 -0
  86. package/src/commands/init/templates/render.ts +20 -0
  87. package/src/commands/init/templates/tsconfig.ts +35 -0
  88. package/src/control-api/operations/contract-emit.ts +7 -0
  89. package/src/utils/validate-contract-deps.ts +49 -0
  90. package/dist/client-yYtotiSX.mjs.map +0 -1
  91. package/dist/exports/control-api.mjs.map +0 -1
  92. package/dist/terminal-ui-N5tR-ob5.mjs.map +0 -1
  93. /package/dist/{cli-errors-Dzs7Oxz7.d.mts → cli-errors-DStABy9d.d.mts} +0 -0
@@ -1,4 +1,4 @@
1
- import { C as isVerbose, S as formatDim, x as createColorFormatter } from "./terminal-ui-N5tR-ob5.mjs";
1
+ import { b as formatDim, x as isVerbose, y as createColorFormatter } from "./result-handler-oK_vA-Fn.mjs";
2
2
  import { green, yellow } from "colorette";
3
3
 
4
4
  //#region src/utils/formatters/migrations.ts
@@ -170,4 +170,4 @@ function formatMigrationJson(result) {
170
170
 
171
171
  //#endregion
172
172
  export { formatMigrationShowOutput as a, formatMigrationPlanOutput as i, formatMigrationApplyOutput as n, formatMigrationVerifyCommandOutput as o, formatMigrationJson as r, formatMigrationApplyCommandOutput as t };
173
- //# sourceMappingURL=migrations-Bv8oeiY_.mjs.map
173
+ //# sourceMappingURL=migrations-DTZBYXm1.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrations-Bv8oeiY_.mjs","names":["lines: string[]"],"sources":["../src/utils/formatters/migrations.ts"],"sourcesContent":["import { green, yellow } from 'colorette';\n\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim, isVerbose } from './helpers';\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 readonly sql?: readonly string[];\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 readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\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 lines.push(`${formatGreen('✔')} Planned ${operationCount} operation(s)`);\n\n // Show operations tree\n if (result.plan?.operations && result.plan.operations.length > 0) {\n const formatYellow = createColorFormatter(useColor, yellow);\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 opClassLabel =\n op.operationClass === 'destructive'\n ? formatYellow(`[${op.operationClass}]`)\n : formatDimText(`[${op.operationClass}]`);\n lines.push(`${formatDimText(treeChar)}─ ${op.label} ${opClassLabel}`);\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 // SQL DDL preview (SQL family only)\n const planSql = result.plan?.sql;\n if (planSql) {\n lines.push('');\n lines.push(`${formatDimText('DDL preview')}`);\n if (planSql.length === 0) {\n lines.push(`${formatDimText('No DDL operations.')}`);\n } else {\n lines.push('');\n for (const statement of planSql) {\n const trimmed = statement.trim();\n if (!trimmed) continue;\n const line = trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n lines.push(`${line}`);\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 dirName: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly timings?: {\n readonly total: number;\n };\n}\n\nexport interface MigrationVerifyCommandOutputResult {\n readonly status: 'verified' | 'attested';\n readonly migrationId?: string;\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 if (result.migrationsApplied === 0) {\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n lines.push(formatDimText(` marker: ${result.markerHash}`));\n return lines.join('\\n');\n }\n\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n lines.push('');\n\n for (let i = 0; i < result.applied.length; i++) {\n const migration = result.applied[i]!;\n const isLast = i === result.applied.length - 1;\n const treeChar = isLast ? '└' : '├';\n lines.push(\n `${formatDimText(treeChar)}─ ${migration.dirName} ${formatDimText(`[${migration.operationsExecuted} op(s)]`)}`,\n );\n }\n\n lines.push('');\n lines.push(formatDimText(`marker: ${result.markerHash}`));\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\nexport function formatMigrationVerifyCommandOutput(\n result: MigrationVerifyCommandOutputResult,\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 formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n switch (result.status) {\n case 'verified':\n lines.push(`${formatGreen('✔')} Migration verified`);\n if (result.migrationId) {\n lines.push(formatDimText(` migrationId: ${result.migrationId}`));\n }\n break;\n case 'attested':\n lines.push(`${formatYellow('◉')} Draft migration attested`);\n if (result.migrationId) {\n lines.push(formatDimText(` migrationId: ${result.migrationId}`));\n }\n break;\n }\n\n return lines.join('\\n');\n}\n\ninterface MigrationShowResult {\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string | null;\n readonly kind: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly sql: readonly string[];\n readonly summary: string;\n}\n\nexport function formatMigrationShowOutput(result: MigrationShowResult, 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 formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n lines.push(`${formatGreen('✔')} ${result.dirName}`);\n lines.push(`${formatDimText(` kind: ${result.kind}`)}`);\n lines.push(`${formatDimText(` from: ${result.from}`)}`);\n lines.push(`${formatDimText(` to: ${result.to}`)}`);\n if (result.migrationId) {\n lines.push(`${formatDimText(` migrationId: ${result.migrationId}`)}`);\n } else {\n lines.push(`${formatYellow(' migrationId: (draft — not yet attested)')}`);\n }\n lines.push(`${formatDimText(` created: ${result.createdAt}`)}`);\n\n lines.push('');\n lines.push(`${result.operations.length} operation(s)`);\n\n if (result.operations.length > 0) {\n lines.push(`${formatDimText('│')}`);\n for (let i = 0; i < result.operations.length; i++) {\n const op = result.operations[i]!;\n const isLast = i === result.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const opClassLabel =\n op.operationClass === 'destructive'\n ? formatYellow(`[${op.operationClass}]`)\n : formatDimText(`[${op.operationClass}]`);\n lines.push(`${formatDimText(treeChar)}─ ${op.label} ${opClassLabel}`);\n }\n\n const hasDestructive = result.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 (result.sql.length > 0) {\n lines.push('');\n lines.push(`${formatDimText('DDL preview')}`);\n lines.push('');\n for (const statement of result.sql) {\n const trimmed = statement.trim();\n if (!trimmed) continue;\n const line = trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n lines.push(`${line}`);\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 if (executed === 0) {\n lines.push(`${formatGreen('✔')} Database already matches contract`);\n } else {\n lines.push(`${formatGreen('✔')} Applied ${executed} operation(s)`);\n }\n\n // Marker info\n if (result.marker) {\n lines.push(`${formatDimText(` Signature: ${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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"}
1
+ {"version":3,"file":"migrations-DTZBYXm1.mjs","names":["lines: string[]"],"sources":["../src/utils/formatters/migrations.ts"],"sourcesContent":["import { green, yellow } from 'colorette';\n\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim, isVerbose } from './helpers';\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 readonly sql?: readonly string[];\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 readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\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 lines.push(`${formatGreen('✔')} Planned ${operationCount} operation(s)`);\n\n // Show operations tree\n if (result.plan?.operations && result.plan.operations.length > 0) {\n const formatYellow = createColorFormatter(useColor, yellow);\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 opClassLabel =\n op.operationClass === 'destructive'\n ? formatYellow(`[${op.operationClass}]`)\n : formatDimText(`[${op.operationClass}]`);\n lines.push(`${formatDimText(treeChar)}─ ${op.label} ${opClassLabel}`);\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 // SQL DDL preview (SQL family only)\n const planSql = result.plan?.sql;\n if (planSql) {\n lines.push('');\n lines.push(`${formatDimText('DDL preview')}`);\n if (planSql.length === 0) {\n lines.push(`${formatDimText('No DDL operations.')}`);\n } else {\n lines.push('');\n for (const statement of planSql) {\n const trimmed = statement.trim();\n if (!trimmed) continue;\n const line = trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n lines.push(`${line}`);\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 dirName: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly timings?: {\n readonly total: number;\n };\n}\n\nexport interface MigrationVerifyCommandOutputResult {\n readonly status: 'verified' | 'attested';\n readonly migrationId?: string;\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 if (result.migrationsApplied === 0) {\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n lines.push(formatDimText(` marker: ${result.markerHash}`));\n return lines.join('\\n');\n }\n\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n lines.push('');\n\n for (let i = 0; i < result.applied.length; i++) {\n const migration = result.applied[i]!;\n const isLast = i === result.applied.length - 1;\n const treeChar = isLast ? '└' : '├';\n lines.push(\n `${formatDimText(treeChar)}─ ${migration.dirName} ${formatDimText(`[${migration.operationsExecuted} op(s)]`)}`,\n );\n }\n\n lines.push('');\n lines.push(formatDimText(`marker: ${result.markerHash}`));\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\nexport function formatMigrationVerifyCommandOutput(\n result: MigrationVerifyCommandOutputResult,\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 formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n switch (result.status) {\n case 'verified':\n lines.push(`${formatGreen('✔')} Migration verified`);\n if (result.migrationId) {\n lines.push(formatDimText(` migrationId: ${result.migrationId}`));\n }\n break;\n case 'attested':\n lines.push(`${formatYellow('◉')} Draft migration attested`);\n if (result.migrationId) {\n lines.push(formatDimText(` migrationId: ${result.migrationId}`));\n }\n break;\n }\n\n return lines.join('\\n');\n}\n\ninterface MigrationShowResult {\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string | null;\n readonly kind: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n readonly sql: readonly string[];\n readonly summary: string;\n}\n\nexport function formatMigrationShowOutput(result: MigrationShowResult, 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 formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n lines.push(`${formatGreen('✔')} ${result.dirName}`);\n lines.push(`${formatDimText(` kind: ${result.kind}`)}`);\n lines.push(`${formatDimText(` from: ${result.from}`)}`);\n lines.push(`${formatDimText(` to: ${result.to}`)}`);\n if (result.migrationId) {\n lines.push(`${formatDimText(` migrationId: ${result.migrationId}`)}`);\n } else {\n lines.push(`${formatYellow(' migrationId: (draft — not yet attested)')}`);\n }\n lines.push(`${formatDimText(` created: ${result.createdAt}`)}`);\n\n lines.push('');\n lines.push(`${result.operations.length} operation(s)`);\n\n if (result.operations.length > 0) {\n lines.push(`${formatDimText('│')}`);\n for (let i = 0; i < result.operations.length; i++) {\n const op = result.operations[i]!;\n const isLast = i === result.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const opClassLabel =\n op.operationClass === 'destructive'\n ? formatYellow(`[${op.operationClass}]`)\n : formatDimText(`[${op.operationClass}]`);\n lines.push(`${formatDimText(treeChar)}─ ${op.label} ${opClassLabel}`);\n }\n\n const hasDestructive = result.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 (result.sql.length > 0) {\n lines.push('');\n lines.push(`${formatDimText('DDL preview')}`);\n lines.push('');\n for (const statement of result.sql) {\n const trimmed = statement.trim();\n if (!trimmed) continue;\n const line = trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n lines.push(`${line}`);\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 if (executed === 0) {\n lines.push(`${formatGreen('✔')} Database already matches contract`);\n } else {\n lines.push(`${formatGreen('✔')} Applied ${executed} operation(s)`);\n }\n\n // Marker info\n if (result.marker) {\n lines.push(`${formatDimText(` Signature: ${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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"}
@@ -40,4 +40,4 @@ function createProgressAdapter(options) {
40
40
 
41
41
  //#endregion
42
42
  export { createProgressAdapter as t };
43
- //# sourceMappingURL=progress-adapter-D4x8SbJa.mjs.map
43
+ //# sourceMappingURL=progress-adapter-B-YvmcDu.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress-adapter-D4x8SbJa.mjs","names":[],"sources":["../src/utils/progress-adapter.ts"],"sourcesContent":["import type { SpinnerResult } from '@clack/prompts';\nimport type { ControlProgressEvent, OnControlProgress } from '../control-api/types';\nimport type { GlobalFlags } from './global-flags';\nimport type { TerminalUI } from './terminal-ui';\n\n/**\n * Options for creating a progress adapter.\n */\ninterface ProgressAdapterOptions {\n readonly ui: TerminalUI;\n readonly flags: GlobalFlags;\n}\n\n/**\n * State for tracking active spans in the progress adapter.\n */\ninterface SpanState {\n readonly spinner: SpinnerResult;\n readonly startTime: number;\n readonly label: string;\n}\n\n/**\n * Creates a progress adapter that converts control-api progress events\n * into CLI spinner/progress output on stderr.\n *\n * The adapter:\n * - Starts/succeeds spinners for top-level span boundaries\n * - Prints per-operation lines for nested spans (e.g., migration operations under 'apply')\n * - Respects quiet/json/non-TTY flags (no-op in those cases)\n */\nexport function createProgressAdapter(options: ProgressAdapterOptions): OnControlProgress {\n const { ui, flags } = options;\n\n // Skip progress if quiet, JSON output, or non-interactive\n if (flags.quiet || flags.json || !ui.isInteractive) {\n return () => {};\n }\n\n // Track active spans by spanId\n const activeSpans = new Map<string, SpanState>();\n\n return (event: ControlProgressEvent) => {\n if (event.kind === 'spanStart') {\n // Nested spans (with parentSpanId) are printed as step lines\n if (event.parentSpanId) {\n ui.step(`${event.label}...`);\n return;\n }\n\n // Top-level spans get a spinner\n const spinner = ui.spinner();\n spinner.start(event.label);\n\n activeSpans.set(event.spanId, {\n spinner,\n startTime: Date.now(),\n label: event.label,\n });\n } else if (event.kind === 'spanEnd') {\n const spanState = activeSpans.get(event.spanId);\n if (spanState) {\n const elapsed = Date.now() - spanState.startTime;\n if (event.outcome === 'error') {\n spanState.spinner.error(`${spanState.label} (failed)`);\n } else if (event.outcome === 'skipped') {\n spanState.spinner.stop(`${spanState.label} (skipped)`);\n } else {\n spanState.spinner.stop(`${spanState.label} (${elapsed}ms)`);\n }\n activeSpans.delete(event.spanId);\n }\n }\n };\n}\n"],"mappings":";;;;;;;;;;AA+BA,SAAgB,sBAAsB,SAAoD;CACxF,MAAM,EAAE,IAAI,UAAU;AAGtB,KAAI,MAAM,SAAS,MAAM,QAAQ,CAAC,GAAG,cACnC,cAAa;CAIf,MAAM,8BAAc,IAAI,KAAwB;AAEhD,SAAQ,UAAgC;AACtC,MAAI,MAAM,SAAS,aAAa;AAE9B,OAAI,MAAM,cAAc;AACtB,OAAG,KAAK,GAAG,MAAM,MAAM,KAAK;AAC5B;;GAIF,MAAM,UAAU,GAAG,SAAS;AAC5B,WAAQ,MAAM,MAAM,MAAM;AAE1B,eAAY,IAAI,MAAM,QAAQ;IAC5B;IACA,WAAW,KAAK,KAAK;IACrB,OAAO,MAAM;IACd,CAAC;aACO,MAAM,SAAS,WAAW;GACnC,MAAM,YAAY,YAAY,IAAI,MAAM,OAAO;AAC/C,OAAI,WAAW;IACb,MAAM,UAAU,KAAK,KAAK,GAAG,UAAU;AACvC,QAAI,MAAM,YAAY,QACpB,WAAU,QAAQ,MAAM,GAAG,UAAU,MAAM,WAAW;aAC7C,MAAM,YAAY,UAC3B,WAAU,QAAQ,KAAK,GAAG,UAAU,MAAM,YAAY;QAEtD,WAAU,QAAQ,KAAK,GAAG,UAAU,MAAM,IAAI,QAAQ,KAAK;AAE7D,gBAAY,OAAO,MAAM,OAAO"}
1
+ {"version":3,"file":"progress-adapter-B-YvmcDu.mjs","names":[],"sources":["../src/utils/progress-adapter.ts"],"sourcesContent":["import type { SpinnerResult } from '@clack/prompts';\nimport type { ControlProgressEvent, OnControlProgress } from '../control-api/types';\nimport type { GlobalFlags } from './global-flags';\nimport type { TerminalUI } from './terminal-ui';\n\n/**\n * Options for creating a progress adapter.\n */\ninterface ProgressAdapterOptions {\n readonly ui: TerminalUI;\n readonly flags: GlobalFlags;\n}\n\n/**\n * State for tracking active spans in the progress adapter.\n */\ninterface SpanState {\n readonly spinner: SpinnerResult;\n readonly startTime: number;\n readonly label: string;\n}\n\n/**\n * Creates a progress adapter that converts control-api progress events\n * into CLI spinner/progress output on stderr.\n *\n * The adapter:\n * - Starts/succeeds spinners for top-level span boundaries\n * - Prints per-operation lines for nested spans (e.g., migration operations under 'apply')\n * - Respects quiet/json/non-TTY flags (no-op in those cases)\n */\nexport function createProgressAdapter(options: ProgressAdapterOptions): OnControlProgress {\n const { ui, flags } = options;\n\n // Skip progress if quiet, JSON output, or non-interactive\n if (flags.quiet || flags.json || !ui.isInteractive) {\n return () => {};\n }\n\n // Track active spans by spanId\n const activeSpans = new Map<string, SpanState>();\n\n return (event: ControlProgressEvent) => {\n if (event.kind === 'spanStart') {\n // Nested spans (with parentSpanId) are printed as step lines\n if (event.parentSpanId) {\n ui.step(`${event.label}...`);\n return;\n }\n\n // Top-level spans get a spinner\n const spinner = ui.spinner();\n spinner.start(event.label);\n\n activeSpans.set(event.spanId, {\n spinner,\n startTime: Date.now(),\n label: event.label,\n });\n } else if (event.kind === 'spanEnd') {\n const spanState = activeSpans.get(event.spanId);\n if (spanState) {\n const elapsed = Date.now() - spanState.startTime;\n if (event.outcome === 'error') {\n spanState.spinner.error(`${spanState.label} (failed)`);\n } else if (event.outcome === 'skipped') {\n spanState.spinner.stop(`${spanState.label} (skipped)`);\n } else {\n spanState.spinner.stop(`${spanState.label} (${elapsed}ms)`);\n }\n activeSpans.delete(event.spanId);\n }\n }\n };\n}\n"],"mappings":";;;;;;;;;;AA+BA,SAAgB,sBAAsB,SAAoD;CACxF,MAAM,EAAE,IAAI,UAAU;AAGtB,KAAI,MAAM,SAAS,MAAM,QAAQ,CAAC,GAAG,cACnC,cAAa;CAIf,MAAM,8BAAc,IAAI,KAAwB;AAEhD,SAAQ,UAAgC;AACtC,MAAI,MAAM,SAAS,aAAa;AAE9B,OAAI,MAAM,cAAc;AACtB,OAAG,KAAK,GAAG,MAAM,MAAM,KAAK;AAC5B;;GAIF,MAAM,UAAU,GAAG,SAAS;AAC5B,WAAQ,MAAM,MAAM,MAAM;AAE1B,eAAY,IAAI,MAAM,QAAQ;IAC5B;IACA,WAAW,KAAK,KAAK;IACrB,OAAO,MAAM;IACd,CAAC;aACO,MAAM,SAAS,WAAW;GACnC,MAAM,YAAY,YAAY,IAAI,MAAM,OAAO;AAC/C,OAAI,WAAW;IACb,MAAM,UAAU,KAAK,KAAK,GAAG,UAAU;AACvC,QAAI,MAAM,YAAY,QACpB,WAAU,QAAQ,MAAM,GAAG,UAAU,MAAM,WAAW;aAC7C,MAAM,YAAY,UAC3B,WAAU,QAAQ,KAAK,GAAG,UAAU,MAAM,YAAY;QAEtD,WAAU,QAAQ,KAAK,GAAG,UAAU,MAAM,IAAI,QAAQ,KAAK;AAE7D,gBAAY,OAAO,MAAM,OAAO"}
@@ -0,0 +1,93 @@
1
+ # Welcome to Prisma Next!
2
+
3
+ Prisma Next lets you query your database in simple, easy-to-read TypeScript. Define what your data looks like, and Prisma Next gives you a fully typed client — with autocomplete for every collection, field, and relation.
4
+
5
+ This project is set up for MongoDB. Prisma Next also supports other databases.
6
+
7
+ ## Your data contract
8
+
9
+ Your data contract is the heart of your application. It lives at [`{{schemaPath}}`]({{schemaPath}}) and describes your models:
10
+
11
+ ```prisma
12
+ model User {
13
+ id ObjectId @id @map("_id")
14
+ email String @unique
15
+ name String?
16
+ posts Post[]
17
+ @@map("users")
18
+ }
19
+ ```
20
+
21
+ Every model you define in your contract can be queried from your app. Your editor will autocomplete the query methods and show you what type each field is:
22
+
23
+ ```typescript
24
+ import { db } from '{{dbImportPath}}';
25
+
26
+ const client = await db.connect(process.env['DATABASE_URL']!, 'mydb');
27
+
28
+ const user = await client.orm.User
29
+ .where({ email: 'alice@example.com' })
30
+ .first();
31
+
32
+ // Your editor will show the type of user as
33
+ // { id: ObjectId; email: string; name: string | null; posts: Post[] } | null
34
+ ```
35
+
36
+ Your contract has two companion files in the same directory:
37
+
38
+ - **`contract.json`** — this tells your application what models exist, just like `package-lock.json` tells your package manager what dependencies your project has
39
+ - **`contract.d.ts`** — this powers autocomplete and type checking in your editor
40
+
41
+ Commit both files to git. When you change your contract, run `{{pkgRun}} contract emit` to update them.
42
+
43
+ If you use a framework like Next.js or Vite, the Prisma Next plugin will do this for you automatically.
44
+
45
+ ## Configuration
46
+
47
+ [`prisma-next.config.ts`](prisma-next.config.ts) tells the CLI where your contract lives and how to connect to your database. It loads environment variables from `.env` automatically:
48
+
49
+ ```typescript
50
+ import 'dotenv/config';
51
+ import { defineConfig } from '@prisma-next/mongo/config';
52
+
53
+ export default defineConfig({
54
+ contract: './{{schemaPath}}',
55
+ db: {
56
+ connection: process.env['DATABASE_URL']!,
57
+ },
58
+ });
59
+ ```
60
+
61
+ Notice the `DATABASE_URL` above? It's defined in your [`.env`](./.env) file:
62
+
63
+ ```env
64
+ DATABASE_URL="mongodb://localhost:27017/mydb"
65
+ ```
66
+
67
+ You can customize how your environment variables are loaded by changing or removing the `import 'dotenv/config'` line.
68
+
69
+ ## Quick reference
70
+
71
+ ### Commands
72
+
73
+ ```bash
74
+ {{pkgRun}} contract emit # Update contract.json and contract.d.ts
75
+ {{pkgRun}} db init # Create collections in the database
76
+ {{pkgRun}} migration status # Show migration status
77
+ ```
78
+
79
+ ### Files
80
+
81
+ | File | Purpose |
82
+ |---|---|
83
+ | [`{{schemaPath}}`]({{schemaPath}}) | Your data contract — define your models here |
84
+ | [`prisma-next.config.ts`](prisma-next.config.ts) | CLI configuration |
85
+ | [`{{schemaDir}}/db.ts`]({{schemaDir}}/db.ts) | Database client — `import { db } from '{{dbImportPath}}'` |
86
+ | `{{schemaDir}}/contract.json` | Compiled contract (generated) |
87
+ | `{{schemaDir}}/contract.d.ts` | Contract types (generated) |
88
+
89
+ ### Workflow
90
+
91
+ 1. Edit [`{{schemaPath}}`]({{schemaPath}}) to add or change models.
92
+ 2. Run `{{pkgRun}} contract emit` to regenerate the contract.
93
+ 3. Query your models — your IDE will autocomplete everything.
@@ -0,0 +1,91 @@
1
+ # Welcome to Prisma Next!
2
+
3
+ Prisma Next lets you query your database in simple, easy-to-read TypeScript. Define what your data looks like, and Prisma Next gives you a fully typed client — with autocomplete for every table, column, and relation.
4
+
5
+ This project is set up for PostgreSQL. Prisma Next also supports other databases.
6
+
7
+ ## Your data contract
8
+
9
+ Your data contract is the heart of your application. It lives at [`{{schemaPath}}`]({{schemaPath}}) and describes your models:
10
+
11
+ ```prisma
12
+ model User {
13
+ id Int @id @default(autoincrement())
14
+ email String @unique
15
+ name String?
16
+ posts Post[]
17
+ createdAt DateTime @default(now())
18
+ }
19
+ ```
20
+
21
+ Every model you define in your contract can be queried from your app. Your editor will autocomplete the query methods and show you what type each model field is:
22
+
23
+ ```typescript
24
+ import { db } from '{{dbImportPath}}';
25
+
26
+ const user = await db.orm.User
27
+ .where({ email: 'alice@example.com' })
28
+ .first();
29
+
30
+ // Your editor will show the type of user as
31
+ // { id: number; email: string; createdAt: Date, name: string, posts: Post[] } | null
32
+ ```
33
+
34
+ Your contract has two companion files in the same directory:
35
+
36
+ - **`contract.json`** — this tells your application what models exist, just like `package-lock.json` tells your package manager what dependencies your project has
37
+ - **`contract.d.ts`** — this powers autocomplete and type checking in your editor
38
+
39
+ Commit both files to git. When you change your contract, run `{{pkgRun}} contract emit` to update them.
40
+
41
+ If you use a framework like Next.js or Vite, the Prisma Next plugin will do this for you automatically.
42
+
43
+ ## Configuration
44
+
45
+ [`prisma-next.config.ts`](prisma-next.config.ts) tells the CLI where your contract lives and how to connect to your database. It loads environment variables from `.env` automatically:
46
+
47
+ ```typescript
48
+ import 'dotenv/config';
49
+ import { defineConfig } from '@prisma-next/postgres/config';
50
+
51
+ export default defineConfig({
52
+ contract: './{{schemaPath}}',
53
+ db: {
54
+ connection: process.env['DATABASE_URL']!,
55
+ },
56
+ });
57
+ ```
58
+
59
+ Notice the `DATABASE_URL` above? It's defined in your [`.env`](./.env) file:
60
+
61
+ ```env
62
+ DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
63
+ ```
64
+
65
+ You can customize how your environment variables are loaded by changing or removing the `import 'dotenv/config'` line.
66
+
67
+ ## Quick reference
68
+
69
+ ### Commands
70
+
71
+ ```bash
72
+ {{pkgRun}} contract emit # Update contract.json and contract.d.ts
73
+ {{pkgRun}} db init # Create tables in the database
74
+ {{pkgRun}} migration status # Show migration status
75
+ ```
76
+
77
+ ### Files
78
+
79
+ | File | Purpose |
80
+ |---|---|
81
+ | [`{{schemaPath}}`]({{schemaPath}}) | Your data contract — define your models here |
82
+ | [`prisma-next.config.ts`](prisma-next.config.ts) | CLI configuration |
83
+ | [`{{schemaDir}}/db.ts`]({{schemaDir}}/db.ts) | Database client — `import { db } from '{{dbImportPath}}'` |
84
+ | `{{schemaDir}}/contract.json` | Compiled contract (generated) |
85
+ | `{{schemaDir}}/contract.d.ts` | Contract types (generated) |
86
+
87
+ ### Workflow
88
+
89
+ 1. Edit [`{{schemaPath}}`]({{schemaPath}}) to add or change models.
90
+ 2. Run `{{pkgRun}} contract emit` to regenerate the contract.
91
+ 3. Query your models — your IDE will autocomplete everything.
@@ -5,11 +5,10 @@ import { readFile } from "node:fs/promises";
5
5
  import { reconstructGraph } from "@prisma-next/migration-tools/dag";
6
6
  import { readMigrationsDir } from "@prisma-next/migration-tools/io";
7
7
  import { isAttested, isDraft } from "@prisma-next/migration-tools/types";
8
- import { blue, bold, cyan, dim, green, magenta, red, yellow } from "colorette";
8
+ import { blue, bold, cyan, dim, green, magenta, red } from "colorette";
9
9
  import wrapAnsi from "wrap-ansi";
10
10
  import stringWidth from "string-width";
11
11
  import stripAnsi from "strip-ansi";
12
- import * as clack from "@clack/prompts";
13
12
 
14
13
  //#region src/utils/formatters/helpers.ts
15
14
  /**
@@ -694,274 +693,5 @@ function handleResult(result, flags, ui, onSuccess) {
694
693
  }
695
694
 
696
695
  //#endregion
697
- //#region src/utils/shutdown.ts
698
- function createShutdownHandler(options) {
699
- const exit = options?.exit ?? ((code) => process.exit(code));
700
- const gracePeriodMs = options?.gracePeriodMs ?? 3e3;
701
- const controller = new AbortController();
702
- let shuttingDown = false;
703
- let graceTimer;
704
- const onSignal = () => {
705
- if (shuttingDown) {
706
- exit(130);
707
- return;
708
- }
709
- shuttingDown = true;
710
- controller.abort();
711
- graceTimer = setTimeout(() => exit(130), gracePeriodMs);
712
- graceTimer.unref();
713
- };
714
- return {
715
- signal: controller.signal,
716
- isShuttingDown: () => shuttingDown,
717
- onSignal,
718
- clearGraceTimer: () => {
719
- if (graceTimer !== void 0) {
720
- clearTimeout(graceTimer);
721
- graceTimer = void 0;
722
- }
723
- }
724
- };
725
- }
726
- const globalHandler = createShutdownHandler();
727
- /**
728
- * The global AbortSignal. Pass this to any async operation that should
729
- * be cancellable on Ctrl+C (e.g., DB queries, long-running emit).
730
- */
731
- const shutdownSignal = globalHandler.signal;
732
- /**
733
- * Installs SIGINT and SIGTERM handlers. Call once at CLI startup.
734
- *
735
- * - First signal: aborts the controller, starts a 3s grace timer.
736
- * - Second signal: force-exits immediately.
737
- */
738
- let installed = false;
739
- function installShutdownHandlers() {
740
- if (installed) return;
741
- installed = true;
742
- process.on("SIGINT", globalHandler.onSignal);
743
- process.on("SIGTERM", globalHandler.onSignal);
744
- }
745
-
746
- //#endregion
747
- //#region src/utils/terminal-ui.ts
748
- /**
749
- * Composable CLI output abstraction.
750
- *
751
- * Follows the Unix convention of separating data from decoration:
752
- * - **stdout** — data output only (`ui.output()`). This is what scripts and pipes capture.
753
- * - **stderr** — all decoration (spinners, logs, notes, intro/outro). Visible in terminal, invisible in pipes.
754
- *
755
- * Rules:
756
- * 1. All methods except `output()` and `error()` write to stderr only in interactive mode.
757
- * 2. `output(data)` always writes to stdout — if a command calls it, there is data to emit.
758
- * 3. `error()` always writes to stderr — errors matter even when piped.
759
- * 4. All other decoration is suppressed when piped — `isInteractive` gates every other decoration method.
760
- * 5. Never write data to stderr — decoration methods are for human context only.
761
- * 6. Never write decoration to stdout — it breaks pipes, `$(...)` captures, and `> file` redirects.
762
- */
763
- var TerminalUI = class TerminalUI {
764
- /**
765
- * True when stdout is a TTY (interactive terminal).
766
- * False when piped (e.g., `prisma-next db verify | jq`).
767
- */
768
- isInteractive;
769
- /**
770
- * Whether color output is enabled.
771
- */
772
- useColor;
773
- static stderrOpts = { output: process.stderr };
774
- constructor(options) {
775
- this.isInteractive = options?.interactive ?? !!process.stdout.isTTY;
776
- this.useColor = options?.color ?? this.isInteractive;
777
- }
778
- /**
779
- * Log a message line to stderr. No-op when piped.
780
- */
781
- log(message) {
782
- if (!this.isInteractive) return;
783
- clack.log.message(message, TerminalUI.stderrOpts);
784
- }
785
- /**
786
- * Log a success message to stderr. No-op when piped.
787
- */
788
- success(message) {
789
- if (!this.isInteractive) return;
790
- clack.log.success(message, TerminalUI.stderrOpts);
791
- }
792
- /**
793
- * Log a warning message to stderr. No-op when piped.
794
- */
795
- warn(message) {
796
- if (!this.isInteractive) return;
797
- clack.log.warn(message, TerminalUI.stderrOpts);
798
- }
799
- /**
800
- * Log an error message to stderr. Always writes (errors matter even in pipes).
801
- */
802
- error(message) {
803
- clack.log.error(message, TerminalUI.stderrOpts);
804
- }
805
- /**
806
- * Log an info message to stderr. No-op when piped.
807
- */
808
- info(message) {
809
- if (!this.isInteractive) return;
810
- clack.log.info(message, TerminalUI.stderrOpts);
811
- }
812
- /**
813
- * Log a step message to stderr. No-op when piped.
814
- */
815
- step(message) {
816
- if (!this.isInteractive) return;
817
- clack.log.step(message, TerminalUI.stderrOpts);
818
- }
819
- /**
820
- * Display a note box on stderr. No-op when piped.
821
- */
822
- note(message, title) {
823
- if (!this.isInteractive) return;
824
- clack.note(message, title, TerminalUI.stderrOpts);
825
- }
826
- /**
827
- * Display intro banner on stderr. No-op when piped.
828
- */
829
- intro(title) {
830
- if (!this.isInteractive) return;
831
- clack.intro(title, TerminalUI.stderrOpts);
832
- }
833
- /**
834
- * Display outro banner on stderr. No-op when piped.
835
- */
836
- outro(message) {
837
- if (!this.isInteractive) return;
838
- clack.outro(message, TerminalUI.stderrOpts);
839
- }
840
- /**
841
- * Create a Clack spinner on stderr with a 100ms delay threshold.
842
- * The spinner only appears if the operation takes longer than the threshold,
843
- * avoiding flicker for fast operations. Returns a no-op spinner when not interactive.
844
- */
845
- spinner(delayMs = 100) {
846
- const noop = {
847
- start: () => {},
848
- stop: () => {},
849
- cancel: () => {},
850
- error: () => {},
851
- message: () => {},
852
- clear: () => {},
853
- get isCancelled() {
854
- return false;
855
- }
856
- };
857
- if (!this.isInteractive) return noop;
858
- let inner;
859
- let timer;
860
- let pendingMsg;
861
- let settled = false;
862
- const ensureCleared = () => {
863
- if (timer !== void 0) {
864
- clearTimeout(timer);
865
- timer = void 0;
866
- }
867
- };
868
- const onAbort = () => {
869
- if (!settled) {
870
- settled = true;
871
- ensureCleared();
872
- if (inner) inner.cancel("Interrupted");
873
- }
874
- };
875
- if (!shutdownSignal.aborted) shutdownSignal.addEventListener("abort", onAbort, { once: true });
876
- return {
877
- start(msg) {
878
- pendingMsg = msg;
879
- timer = setTimeout(() => {
880
- if (!settled) {
881
- inner = clack.spinner(TerminalUI.stderrOpts);
882
- inner.start(pendingMsg);
883
- }
884
- }, delayMs);
885
- },
886
- stop(msg) {
887
- settled = true;
888
- ensureCleared();
889
- if (inner) inner.stop(msg);
890
- },
891
- cancel(msg) {
892
- settled = true;
893
- ensureCleared();
894
- if (inner) inner.cancel(msg);
895
- },
896
- error(msg) {
897
- settled = true;
898
- ensureCleared();
899
- if (inner) inner.error(msg);
900
- },
901
- message(msg) {
902
- pendingMsg = msg;
903
- if (inner) inner.message(msg);
904
- },
905
- clear() {
906
- settled = true;
907
- ensureCleared();
908
- if (inner) inner.clear();
909
- },
910
- get isCancelled() {
911
- return inner?.isCancelled ?? false;
912
- }
913
- };
914
- }
915
- /**
916
- * Prompt for yes/no confirmation on stderr. Returns true if confirmed.
917
- * In non-interactive mode or when cancelled (Ctrl-C), returns false.
918
- */
919
- async confirm(message) {
920
- if (!this.isInteractive) return false;
921
- const result = await clack.confirm({
922
- message,
923
- ...TerminalUI.stderrOpts
924
- });
925
- if (clack.isCancel(result)) return false;
926
- return result;
927
- }
928
- /**
929
- * Write a raw line to stderr. No-op when piped.
930
- * Use for decoration that doesn't fit Clack's log format (e.g. styled headers).
931
- */
932
- stderr(message) {
933
- if (!this.isInteractive) return;
934
- process.stderr.write(`${message}\n`);
935
- }
936
- /**
937
- * Write machine-readable data to stdout.
938
- * Always writes — if a command calls output(), there is data to emit.
939
- *
940
- * This is what scripts and pipes capture: `prisma-next db verify --json | jq .ok`
941
- */
942
- output(data) {
943
- process.stdout.write(`${data}\n`);
944
- }
945
- green(text) {
946
- return this.useColor ? green(text) : text;
947
- }
948
- red(text) {
949
- return this.useColor ? red(text) : text;
950
- }
951
- cyan(text) {
952
- return this.useColor ? cyan(text) : text;
953
- }
954
- dim(text) {
955
- return this.useColor ? dim(text) : text;
956
- }
957
- bold(text) {
958
- return this.useColor ? bold(text) : text;
959
- }
960
- yellow(text) {
961
- return this.useColor ? yellow(text) : text;
962
- }
963
- };
964
-
965
- //#endregion
966
- export { isVerbose as C, formatDim as S, formatCommandHelp as _, getTargetMigrations as a, formatSuccessMessage as b, readContractEnvelope as c, sanitizeErrorMessage as d, setCommandDescriptions as f, parseGlobalFlags as g, toPathDecisionResult as h, addGlobalOptions as i, resolveContractPath as l, targetSupportsMigrations as m, installShutdownHandlers as n, loadAllBundles as o, setCommandExamples as p, handleResult as r, maskConnectionUrl as s, TerminalUI as t, resolveMigrationPaths as u, formatRootHelp as v, createColorFormatter as x, formatStyledHeader as y };
967
- //# sourceMappingURL=terminal-ui-N5tR-ob5.mjs.map
696
+ export { formatStyledHeader as _, maskConnectionUrl as a, formatDim as b, resolveMigrationPaths as c, setCommandExamples as d, targetSupportsMigrations as f, formatRootHelp as g, formatCommandHelp as h, loadAllBundles as i, sanitizeErrorMessage as l, parseGlobalFlags as m, addGlobalOptions as n, readContractEnvelope as o, toPathDecisionResult as p, getTargetMigrations as r, resolveContractPath as s, handleResult as t, setCommandDescriptions as u, formatSuccessMessage as v, isVerbose as x, createColorFormatter as y };
697
+ //# sourceMappingURL=result-handler-oK_vA-Fn.mjs.map