@prisma-next/cli 0.10.0 → 0.11.0-dev.2

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 (151) hide show
  1. package/README.md +1 -1
  2. package/dist/{cli-errors-CF60g2cG.mjs → cli-errors-Djtz98Vm.mjs} +3 -3
  3. package/dist/cli-errors-Djtz98Vm.mjs.map +1 -0
  4. package/dist/cli.mjs +400 -13
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/{client-Brv4qlfB.mjs → client-oXO2WCPD.mjs} +6 -5
  7. package/dist/client-oXO2WCPD.mjs.map +1 -0
  8. package/dist/{command-helpers-D3vL5yi8.mjs → command-helpers-DtavI0wJ.mjs} +109 -12
  9. package/dist/command-helpers-DtavI0wJ.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.d.mts.map +1 -1
  13. package/dist/commands/db-init.mjs +19 -20
  14. package/dist/commands/db-init.mjs.map +1 -1
  15. package/dist/commands/db-schema.mjs +6 -10
  16. package/dist/commands/db-schema.mjs.map +1 -1
  17. package/dist/commands/db-sign.mjs +7 -11
  18. package/dist/commands/db-sign.mjs.map +1 -1
  19. package/dist/commands/db-update.d.mts.map +1 -1
  20. package/dist/commands/db-update.mjs +16 -17
  21. package/dist/commands/db-update.mjs.map +1 -1
  22. package/dist/commands/db-verify.mjs +1 -1
  23. package/dist/commands/migrate.d.mts +1 -1
  24. package/dist/commands/migrate.mjs +7 -11
  25. package/dist/commands/migrate.mjs.map +1 -1
  26. package/dist/commands/migration-check.mjs +4 -7
  27. package/dist/commands/migration-check.mjs.map +1 -1
  28. package/dist/commands/migration-graph.d.mts +1 -1
  29. package/dist/commands/migration-graph.mjs +6 -10
  30. package/dist/commands/migration-graph.mjs.map +1 -1
  31. package/dist/commands/migration-list.mjs +5 -9
  32. package/dist/commands/migration-list.mjs.map +1 -1
  33. package/dist/commands/migration-log.d.mts.map +1 -1
  34. package/dist/commands/migration-log.mjs +7 -10
  35. package/dist/commands/migration-log.mjs.map +1 -1
  36. package/dist/commands/migration-new.mjs +6 -10
  37. package/dist/commands/migration-new.mjs.map +1 -1
  38. package/dist/commands/migration-plan.d.mts +1 -1
  39. package/dist/commands/migration-plan.mjs +1 -1
  40. package/dist/commands/migration-show.d.mts +1 -1
  41. package/dist/commands/migration-show.mjs +8 -12
  42. package/dist/commands/migration-show.mjs.map +1 -1
  43. package/dist/commands/migration-status.d.mts +1 -1
  44. package/dist/commands/migration-status.d.mts.map +1 -1
  45. package/dist/commands/migration-status.mjs +36 -14
  46. package/dist/commands/migration-status.mjs.map +1 -1
  47. package/dist/commands/ref.d.mts +1 -1
  48. package/dist/commands/ref.mjs +9 -19
  49. package/dist/commands/ref.mjs.map +1 -1
  50. package/dist/{contract-emit-iynA3BCA.mjs → contract-emit-bcrpT-wD.mjs} +3 -3
  51. package/dist/{contract-emit-iynA3BCA.mjs.map → contract-emit-bcrpT-wD.mjs.map} +1 -1
  52. package/dist/{contract-emit-C3STUIBg.mjs → contract-emit-uwT-Mj8-.mjs} +7 -12
  53. package/dist/contract-emit-uwT-Mj8-.mjs.map +1 -0
  54. package/dist/{contract-infer-Cnj8G1E2.mjs → contract-infer-pKkiCt7C.mjs} +9 -14
  55. package/dist/contract-infer-pKkiCt7C.mjs.map +1 -0
  56. package/dist/{contract-space-aggregate-loader-pAc8CDfY.mjs → contract-space-aggregate-loader-BmNQwlws.mjs} +2 -2
  57. package/dist/{contract-space-aggregate-loader-pAc8CDfY.mjs.map → contract-space-aggregate-loader-BmNQwlws.mjs.map} +1 -1
  58. package/dist/{db-verify-D7cyH_zz.mjs → db-verify-AoIUriL4.mjs} +9 -13
  59. package/dist/db-verify-AoIUriL4.mjs.map +1 -0
  60. package/dist/exports/control-api.d.mts +1 -1
  61. package/dist/exports/control-api.mjs +2 -2
  62. package/dist/exports/index.mjs +2 -2
  63. package/dist/exports/init-output.mjs +1 -1
  64. package/dist/{framework-components-xFLFpZUO.mjs → framework-components-65gOHkHB.mjs} +2 -2
  65. package/dist/{framework-components-xFLFpZUO.mjs.map → framework-components-65gOHkHB.mjs.map} +1 -1
  66. package/dist/{global-flags-DGmw6Kqg.d.mts → global-flags-CdE7M0d9.d.mts} +4 -1
  67. package/dist/global-flags-CdE7M0d9.d.mts.map +1 -0
  68. package/dist/{graph-render-eJDcLWny.mjs → graph-render-DJVv0_uf.mjs} +1 -1
  69. package/dist/{graph-render-eJDcLWny.mjs.map → graph-render-DJVv0_uf.mjs.map} +1 -1
  70. package/dist/{init-eh2z5Tl6.mjs → init-YX6lCJpG.mjs} +528 -627
  71. package/dist/init-YX6lCJpG.mjs.map +1 -0
  72. package/dist/{inspect-live-schema-CWLK_lgs.mjs → inspect-live-schema-LeWvkZVz.mjs} +4 -4
  73. package/dist/{inspect-live-schema-CWLK_lgs.mjs.map → inspect-live-schema-LeWvkZVz.mjs.map} +1 -1
  74. package/dist/{migration-command-scaffold-CmXXC1UZ.mjs → migration-command-scaffold-BtkunvFQ.mjs} +4 -4
  75. package/dist/{migration-command-scaffold-CmXXC1UZ.mjs.map → migration-command-scaffold-BtkunvFQ.mjs.map} +1 -1
  76. package/dist/{migration-plan-CHyUlBV0.mjs → migration-plan-C2jeH1J5.mjs} +8 -12
  77. package/dist/migration-plan-C2jeH1J5.mjs.map +1 -0
  78. package/dist/{migration-types-D2FW63pr.d.mts → migration-types-BXWvz12q.d.mts} +1 -1
  79. package/dist/{migration-types-D2FW63pr.d.mts.map → migration-types-BXWvz12q.d.mts.map} +1 -1
  80. package/dist/{migrations-DyUf5lTt.mjs → migrations-CwZMa1Ck.mjs} +2 -2
  81. package/dist/{migrations-DyUf5lTt.mjs.map → migrations-CwZMa1Ck.mjs.map} +1 -1
  82. package/dist/{output-B60Gw5fu.mjs → output-BlsrGMEF.mjs} +1 -1
  83. package/dist/{output-B60Gw5fu.mjs.map → output-BlsrGMEF.mjs.map} +1 -1
  84. package/dist/quick-reference-mongo.md +1 -1
  85. package/dist/quick-reference-postgres.md +1 -1
  86. package/dist/readme-mongo.md +35 -0
  87. package/dist/readme-postgres.md +34 -0
  88. package/dist/{terminal-ui-XtOQsqe9.mjs → terminal-ui-BiB_8KNo.mjs} +131 -24
  89. package/dist/terminal-ui-BiB_8KNo.mjs.map +1 -0
  90. package/dist/{types-0aS865QN.d.mts → types--CqjMdk0.d.mts} +2 -2
  91. package/dist/{types-0aS865QN.d.mts.map → types--CqjMdk0.d.mts.map} +1 -1
  92. package/dist/{verify-D7ypCCe6.mjs → verify-Bom75OYI.mjs} +2 -2
  93. package/dist/{verify-D7ypCCe6.mjs.map → verify-Bom75OYI.mjs.map} +1 -1
  94. package/package.json +19 -17
  95. package/src/cli.ts +42 -0
  96. package/src/commands/contract-emit.ts +4 -4
  97. package/src/commands/contract-infer.ts +7 -7
  98. package/src/commands/db-init.ts +13 -5
  99. package/src/commands/db-schema.ts +4 -4
  100. package/src/commands/db-sign.ts +4 -4
  101. package/src/commands/db-update.ts +13 -5
  102. package/src/commands/db-verify.ts +5 -5
  103. package/src/commands/init/detect-package-manager.ts +15 -0
  104. package/src/commands/init/errors.ts +33 -2
  105. package/src/commands/init/hygiene-gitattributes.ts +2 -2
  106. package/src/commands/init/index.ts +15 -6
  107. package/src/commands/init/init.ts +61 -32
  108. package/src/commands/init/inputs.ts +82 -5
  109. package/src/commands/init/output.ts +1 -1
  110. package/src/commands/init/{agent-skill-install.ts → skill-install.ts} +42 -31
  111. package/src/commands/init/templates/code-templates.ts +26 -24
  112. package/src/commands/init/templates/env.ts +8 -1
  113. package/src/commands/init/templates/quick-reference-mongo.md +1 -1
  114. package/src/commands/init/templates/quick-reference-postgres.md +1 -1
  115. package/src/commands/init/templates/readme-mongo.md +35 -0
  116. package/src/commands/init/templates/readme-postgres.md +34 -0
  117. package/src/commands/init/templates/readme.ts +62 -0
  118. package/src/commands/migrate.ts +4 -7
  119. package/src/commands/migration-check.ts +4 -4
  120. package/src/commands/migration-graph.ts +4 -4
  121. package/src/commands/migration-list.ts +4 -4
  122. package/src/commands/migration-log.ts +6 -5
  123. package/src/commands/migration-new.ts +4 -4
  124. package/src/commands/migration-plan.ts +4 -4
  125. package/src/commands/migration-show.ts +4 -4
  126. package/src/commands/migration-status.ts +49 -6
  127. package/src/commands/ref.ts +8 -8
  128. package/src/control-api/operations/apply-aggregate.ts +1 -0
  129. package/src/utils/cli-errors.ts +4 -0
  130. package/src/utils/command-helpers.ts +14 -6
  131. package/src/utils/global-flags.ts +105 -16
  132. package/src/utils/is-ci.ts +18 -0
  133. package/src/utils/telemetry.ts +141 -0
  134. package/src/utils/terminal-ui.ts +44 -23
  135. package/dist/cli-errors-CF60g2cG.mjs.map +0 -1
  136. package/dist/client-Brv4qlfB.mjs.map +0 -1
  137. package/dist/command-helpers-D3vL5yi8.mjs.map +0 -1
  138. package/dist/contract-emit-C3STUIBg.mjs.map +0 -1
  139. package/dist/contract-infer-Cnj8G1E2.mjs.map +0 -1
  140. package/dist/db-verify-D7cyH_zz.mjs.map +0 -1
  141. package/dist/errors-Cw6kyTyV.mjs +0 -56
  142. package/dist/errors-Cw6kyTyV.mjs.map +0 -1
  143. package/dist/global-flags-DGmw6Kqg.d.mts.map +0 -1
  144. package/dist/helpers-eqdN8tH6.mjs +0 -25
  145. package/dist/helpers-eqdN8tH6.mjs.map +0 -1
  146. package/dist/init-eh2z5Tl6.mjs.map +0 -1
  147. package/dist/migration-plan-CHyUlBV0.mjs.map +0 -1
  148. package/dist/result-handler-Bm_6dDYg.mjs +0 -25
  149. package/dist/result-handler-Bm_6dDYg.mjs.map +0 -1
  150. package/dist/terminal-ui-XtOQsqe9.mjs.map +0 -1
  151. /package/dist/{cli-errors-DdcjVLJV.d.mts → cli-errors-Czmx92Zy.d.mts} +0 -0
package/README.md CHANGED
@@ -1060,7 +1060,7 @@ run `migration.ts` directly with Node to produce `ops.json` and attest
1060
1060
  node migrations/<dir>/migration.ts
1061
1061
  ```
1062
1062
 
1063
- The scaffolded `migration.ts` calls `MigrationCLI.run(import.meta.url, ...)` from `@prisma-next/cli/migration-cli` when invoked as the entrypoint. (Postgres scaffolds re-export `MigrationCLI` through `@prisma-next/target-postgres/migration` so a Postgres `migration.ts` only needs the single facade import; Mongo scaffolds still pull from `@prisma-next/cli/migration-cli` directly.) The CLI entrypoint loads `prisma-next.config.ts`, assembles a `ControlStack`, instantiates the migration with that stack (so `dataTransform` and other adapter-aware helpers can materialize a real adapter), and serializes operations to `ops.json` while writing the content-addressed `migrationHash` into `migration.json`. If `migration.ts` contains unfilled `placeholder()` slots, the script exits with `PN-MIG-2001` and reports the slot to fill in.
1063
+ The scaffolded `migration.ts` calls `MigrationCLI.run(import.meta.url, ...)` from `@prisma-next/cli/migration-cli` when invoked as the entrypoint. (Postgres and SQLite scaffolds re-export `MigrationCLI` through `@prisma-next/postgres/migration` or `@prisma-next/sqlite/migration` so a `migration.ts` only needs the single facade import; Mongo scaffolds still pull from `@prisma-next/cli/migration-cli` directly.) The CLI entrypoint loads `prisma-next.config.ts`, assembles a `ControlStack`, instantiates the migration with that stack (so `dataTransform` and other adapter-aware helpers can materialize a real adapter), and serializes operations to `ops.json` while writing the content-addressed `migrationHash` into `migration.json`. If `migration.ts` contains unfilled `placeholder()` slots, the script exits with `PN-MIG-2001` and reports the slot to fill in.
1064
1064
 
1065
1065
  `MigrationCLI.run` accepts an optional third argument `{ argv?, stdout?, stderr? }` for in-process testability (default: `process.argv` / `process.stdout` / `process.stderr`) and returns the exit code as a `Promise<number>`. The flag surface is `--help` / `--dry-run` / `--config <path>`, parsed by [`clipanion`](https://github.com/arcanis/clipanion). The main multi-command surface (`prisma-next contract emit`, `db verify`, etc.) uses Commander; the per-migration `MigrationCLI.run` entrypoint uses clipanion to keep authored migration files lightweight and in-process testable.
1066
1066
 
@@ -1,4 +1,4 @@
1
- import { CliStructuredError as CliStructuredError$1, errorConfigValidation as errorConfigValidation$1, errorContractConfigMissing as errorContractConfigMissing$1, errorContractValidationFailed, errorDatabaseConnectionRequired, errorDriverRequired, errorFileNotFound, errorMigrationPlanningFailed, errorTargetMigrationNotSupported, errorUnexpected as errorUnexpected$1 } from "@prisma-next/errors/control";
1
+ import { CliStructuredError as CliStructuredError$1, errorConfigValidation as errorConfigValidation$1, errorContractConfigMissing as errorContractConfigMissing$1, errorContractValidationFailed, errorDatabaseConnectionRequired, errorDriverRequired, errorFileNotFound, errorInvalidOutputFormat, errorMigrationPlanningFailed, errorOutputFormatMutex, errorTargetMigrationNotSupported, errorUnexpected as errorUnexpected$1 } from "@prisma-next/errors/control";
2
2
  import { ERROR_CODE_DESTRUCTIVE_CHANGES, errorDestructiveChanges, errorHashMismatch, errorMarkerMissing, errorRunnerFailed, errorRuntime, errorRuntime as errorRuntime$1, errorTargetMismatch } from "@prisma-next/errors/execution";
3
3
  import "@prisma-next/errors/migration";
4
4
  //#region src/utils/cli-errors.ts
@@ -66,6 +66,6 @@ function mapRefResolutionError(error) {
66
66
  }
67
67
  }
68
68
  //#endregion
69
- export { errorUnexpected$1 as _, errorContractValidationFailed as a, errorDriverRequired as c, errorMarkerMissing as d, errorMigrationPlanningFailed as f, errorTargetMismatch as g, errorTargetMigrationNotSupported as h, errorContractConfigMissing$1 as i, errorFileNotFound as l, errorRuntime$1 as m, ERROR_CODE_DESTRUCTIVE_CHANGES as n, errorDatabaseConnectionRequired as o, errorRunnerFailed as p, errorConfigValidation$1 as r, errorDestructiveChanges as s, CliStructuredError$1 as t, errorHashMismatch as u, mapMigrationToolsError as v, mapRefResolutionError as y };
69
+ export { errorTargetMigrationNotSupported as _, errorContractValidationFailed as a, mapMigrationToolsError as b, errorDriverRequired as c, errorInvalidOutputFormat as d, errorMarkerMissing as f, errorRuntime$1 as g, errorRunnerFailed as h, errorContractConfigMissing$1 as i, errorFileNotFound as l, errorOutputFormatMutex as m, ERROR_CODE_DESTRUCTIVE_CHANGES as n, errorDatabaseConnectionRequired as o, errorMigrationPlanningFailed as p, errorConfigValidation$1 as r, errorDestructiveChanges as s, CliStructuredError$1 as t, errorHashMismatch as u, errorTargetMismatch as v, mapRefResolutionError as x, errorUnexpected$1 as y };
70
70
 
71
- //# sourceMappingURL=cli-errors-CF60g2cG.mjs.map
71
+ //# sourceMappingURL=cli-errors-Djtz98Vm.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-errors-Djtz98Vm.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 errorInvalidOutputFormat,\n errorMigrationCliInvalidConfigArg,\n errorMigrationCliUnknownFlag,\n errorMigrationPlanningFailed,\n errorOutputFormatMutex,\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';\nimport type { RefResolutionError } from '@prisma-next/migration-tools/ref-resolution';\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 errorInvalidOutputFormat,\n errorMigrationCliInvalidConfigArg,\n errorMigrationCliUnknownFlag,\n errorMigrationPlanningFailed,\n errorOutputFormatMutex,\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\n/**\n * Maps a `RefResolutionError` from the contract/migration reference\n * resolver into a CLI structured error envelope.\n */\nexport function mapRefResolutionError(error: RefResolutionError): CliStructuredError {\n switch (error.kind) {\n case 'not-found':\n return errorRuntime(`Not a known ${error.grammar} reference: \"${error.input}\"`, {\n why: `No ${error.grammar} matching \"${error.input}\" exists in the migration graph or refs index.`,\n fix:\n error.grammar === 'contract'\n ? 'Provide a valid contract hash, ref name, or migration directory name.'\n : 'Provide a valid migration directory name or migration hash.',\n meta: { input: error.input, grammar: error.grammar },\n });\n case 'ambiguous':\n return errorRuntime(`Ambiguous ${error.grammar} reference: \"${error.input}\"`, {\n why: `\"${error.input}\" matches multiple ${error.grammar}s: ${error.candidates.join(', ')}`,\n fix: 'Provide a longer prefix or use the full hash to disambiguate.',\n meta: { input: error.input, candidates: error.candidates, grammar: error.grammar },\n });\n case 'wrong-grammar':\n return errorRuntime(error.message, {\n why: error.message,\n fix: error.fix,\n meta: { input: error.input, expectedGrammar: error.expectedGrammar },\n });\n case 'invalid-format':\n return errorRuntime(`Invalid reference format: \"${error.input}\"`, {\n why: error.reason,\n fix: 'Provide a valid contract hash, ref name, or migration directory name.',\n meta: { input: error.input },\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqFA,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;;;;;;AAOJ,SAAgB,sBAAsB,OAA+C;CACnF,QAAQ,MAAM,MAAd;EACE,KAAK,aACH,OAAO,aAAa,eAAe,MAAM,QAAQ,eAAe,MAAM,MAAM,IAAI;GAC9E,KAAK,MAAM,MAAM,QAAQ,aAAa,MAAM,MAAM;GAClD,KACE,MAAM,YAAY,aACd,0EACA;GACN,MAAM;IAAE,OAAO,MAAM;IAAO,SAAS,MAAM;IAAS;GACrD,CAAC;EACJ,KAAK,aACH,OAAO,aAAa,aAAa,MAAM,QAAQ,eAAe,MAAM,MAAM,IAAI;GAC5E,KAAK,IAAI,MAAM,MAAM,qBAAqB,MAAM,QAAQ,KAAK,MAAM,WAAW,KAAK,KAAK;GACxF,KAAK;GACL,MAAM;IAAE,OAAO,MAAM;IAAO,YAAY,MAAM;IAAY,SAAS,MAAM;IAAS;GACnF,CAAC;EACJ,KAAK,iBACH,OAAO,aAAa,MAAM,SAAS;GACjC,KAAK,MAAM;GACX,KAAK,MAAM;GACX,MAAM;IAAE,OAAO,MAAM;IAAO,iBAAiB,MAAM;IAAiB;GACrE,CAAC;EACJ,KAAK,kBACH,OAAO,aAAa,8BAA8B,MAAM,MAAM,IAAI;GAChE,KAAK,MAAM;GACX,KAAK;GACL,MAAM,EAAE,OAAO,MAAM,OAAO;GAC7B,CAAC"}
package/dist/cli.mjs CHANGED
@@ -1,27 +1,397 @@
1
1
  #!/usr/bin/env node
2
- import { _ as parseGlobalFlags, d as setCommandDescriptions, f as setCommandExamples, t as addGlobalOptions, v as formatCommandHelp, y as formatRootHelp } from "./command-helpers-D3vL5yi8.mjs";
3
- import { t as createContractEmitCommand } from "./contract-emit-C3STUIBg.mjs";
4
- import { n as installShutdownHandlers } from "./terminal-ui-XtOQsqe9.mjs";
5
- import { t as createContractInferCommand } from "./contract-infer-Cnj8G1E2.mjs";
2
+ import { a as isCI, n as installShutdownHandlers } from "./terminal-ui-BiB_8KNo.mjs";
3
+ import { _ as parseGlobalFlags, b as formatCommandHelp, d as setCommandDescriptions, f as setCommandExamples, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as formatRootHelp } from "./command-helpers-DtavI0wJ.mjs";
4
+ import { t as createContractEmitCommand } from "./contract-emit-uwT-Mj8-.mjs";
5
+ import { t as createContractInferCommand } from "./contract-infer-pKkiCt7C.mjs";
6
6
  import { createDbInitCommand } from "./commands/db-init.mjs";
7
7
  import { createDbSchemaCommand } from "./commands/db-schema.mjs";
8
8
  import { createDbSignCommand } from "./commands/db-sign.mjs";
9
9
  import { createDbUpdateCommand } from "./commands/db-update.mjs";
10
- import { t as createDbVerifyCommand } from "./db-verify-D7cyH_zz.mjs";
10
+ import { t as createDbVerifyCommand } from "./db-verify-AoIUriL4.mjs";
11
11
  import { createMigrateCommand } from "./commands/migrate.mjs";
12
12
  import { createMigrationCheckCommand } from "./commands/migration-check.mjs";
13
13
  import { createMigrationGraphCommand } from "./commands/migration-graph.mjs";
14
14
  import { createMigrationListCommand } from "./commands/migration-list.mjs";
15
15
  import { createMigrationLogCommand } from "./commands/migration-log.mjs";
16
16
  import { createMigrationNewCommand } from "./commands/migration-new.mjs";
17
- import { t as createMigrationPlanCommand } from "./migration-plan-CHyUlBV0.mjs";
17
+ import { t as createMigrationPlanCommand } from "./migration-plan-C2jeH1J5.mjs";
18
18
  import { createMigrationShowCommand } from "./commands/migration-show.mjs";
19
19
  import { createMigrationStatusCommand } from "./commands/migration-status.mjs";
20
20
  import { createRefCommand } from "./commands/ref.mjs";
21
21
  import { Command } from "commander";
22
+ import { ifDefined } from "@prisma-next/utils/defined";
23
+ import { DEFAULT_CONTRACT_SOURCE_DIR } from "@prisma-next/config/config-types";
24
+ import { fileURLToPath } from "node:url";
25
+ import { readUserConfig, resolveGating, runTelemetry } from "@prisma-next/cli-telemetry";
22
26
  import { distance } from "closest-match";
23
27
  //#region package.json
24
- var version = "0.10.0";
28
+ var version = "0.11.0-dev.2";
29
+ //#endregion
30
+ //#region src/utils/telemetry.ts
31
+ /**
32
+ * Resolve the commander command path from a leaf `Command`, walking up
33
+ * the parent chain. Result is rooted at the program name and ends at
34
+ * the leaf — `['prisma-next', 'migration', 'new']` for
35
+ * `prisma-next migration new …`.
36
+ */
37
+ function commandPathFor(actionCommand) {
38
+ const path = [];
39
+ let cursor = actionCommand;
40
+ while (cursor !== null) {
41
+ path.unshift(cursor.name());
42
+ cursor = cursor.parent;
43
+ }
44
+ return path;
45
+ }
46
+ function commanderOptionSnapshots(actionCommand) {
47
+ return actionCommand.options.map((option) => {
48
+ const attributeName = option.attributeName();
49
+ return {
50
+ attributeName,
51
+ longName: option.long ?? null,
52
+ source: actionCommand.getOptionValueSource(attributeName) ?? null
53
+ };
54
+ });
55
+ }
56
+ /**
57
+ * Project commander's leaf `Command` into the wire-shape snapshot the
58
+ * telemetry sanitiser consumes. Pure projection — no env, no I/O.
59
+ */
60
+ function commanderSnapshotForTelemetry(actionCommand) {
61
+ return {
62
+ commandPath: commandPathFor(actionCommand),
63
+ positionalArgs: actionCommand.args,
64
+ options: commanderOptionSnapshots(actionCommand)
65
+ };
66
+ }
67
+ function resolveTelemetryGate() {
68
+ if (isCI()) return {
69
+ enabled: false,
70
+ outcome: {
71
+ spawned: false,
72
+ reason: "ci"
73
+ }
74
+ };
75
+ const userConfig = readUserConfig();
76
+ if (!resolveGating({
77
+ env: process.env,
78
+ config: userConfig
79
+ }).enabled) return {
80
+ enabled: false,
81
+ outcome: {
82
+ spawned: false,
83
+ reason: "gated-off"
84
+ }
85
+ };
86
+ return {
87
+ enabled: true,
88
+ userConfig
89
+ };
90
+ }
91
+ /**
92
+ * Path to the compiled sender script inside `@prisma-next/cli-telemetry`'s
93
+ * `dist/`. Resolved off this module's `import.meta.url` via the package
94
+ * specifier `@prisma-next/cli-telemetry/sender`, so the consumer pays
95
+ * no attention to internal package layout.
96
+ */
97
+ function senderPath() {
98
+ return fileURLToPath(new URL(import.meta.resolve("@prisma-next/cli-telemetry/sender")));
99
+ }
100
+ function fireTelemetry(actionCommand, userConfig, overrides = {}) {
101
+ return runTelemetry({
102
+ command: commanderSnapshotForTelemetry(actionCommand),
103
+ version,
104
+ projectRoot: process.cwd(),
105
+ senderPath: senderPath(),
106
+ isCI: isCI(),
107
+ env: process.env,
108
+ userConfig,
109
+ ...ifDefined("databaseTarget", overrides.databaseTarget)
110
+ });
111
+ }
112
+ /**
113
+ * preAction-stage entry point. Synchronous by construction: resolve
114
+ * env/CI/user-consent gates (cheap, all in-memory and a single tiny
115
+ * user-config read), then — only when enabled — `fork()` the detached
116
+ * sender script. The forked child loads `prisma-next.config.*` via
117
+ * c12 on its own (see `loadProjectConfig` in cli-telemetry); the
118
+ * parent does no project-config I/O on the command's hot path.
119
+ *
120
+ * Privacy invariant: gate resolution always happens before any project
121
+ * config touches disk. The child loading user TS code is acceptable
122
+ * only because it's gated behind the same resolved-enabled signal.
123
+ */
124
+ function fireTelemetryFromPreAction(actionCommand) {
125
+ const gate = resolveTelemetryGate();
126
+ if (!gate.enabled) return gate.outcome;
127
+ return fireTelemetry(actionCommand, gate.userConfig);
128
+ }
129
+ /**
130
+ * Manual one-shot telemetry path for the first `init` run where the user
131
+ * explicitly answers Yes to the consent prompt. The preAction hook for
132
+ * that same run has already resolved before consent existed, so it is
133
+ * default-off. After consent is persisted, `runInit` calls this helper
134
+ * exactly for that first affirmative answer; subsequent init runs skip
135
+ * it because the prompt is not shown again.
136
+ *
137
+ * The child's c12 load would return `databaseTarget: null` for this
138
+ * specific invocation because `prisma-next.config.*` is not yet on
139
+ * disk (init writes it later in the same run). To preserve the
140
+ * prompt-chosen target in the first-init telemetry event, this
141
+ * helper forwards the value as a parent-side IPC override on
142
+ * `ParentToSenderPayload.databaseTarget` — the child consults the
143
+ * override first and falls back to its c12 result when absent.
144
+ */
145
+ function fireTelemetryAfterInitConsent(actionCommand, inputs) {
146
+ return fireTelemetry(actionCommand, readUserConfig(), { databaseTarget: inputs.databaseTarget });
147
+ }
148
+ //#endregion
149
+ //#region src/commands/init/templates/code-templates.ts
150
+ function targetPackageName(target) {
151
+ return target === "postgres" ? "@prisma-next/postgres" : "@prisma-next/mongo";
152
+ }
153
+ function targetLabel(target) {
154
+ return target === "postgres" ? "PostgreSQL" : "MongoDB";
155
+ }
156
+ function defaultSchemaPath(authoring) {
157
+ if (authoring === "typescript") return `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.ts`;
158
+ return `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.prisma`;
159
+ }
160
+ function starterSchema(target, authoring) {
161
+ if (authoring === "typescript") return target === "mongo" ? starterSchemaTsMongo() : starterSchemaTsPostgres();
162
+ return target === "mongo" ? starterSchemaPslMongo() : starterSchemaPslPostgres();
163
+ }
164
+ /**
165
+ * Renders a short authoring-appropriate schema sample (FR5.1) for embedding
166
+ * in `prisma-next.md`. Returns a complete fenced markdown code block.
167
+ *
168
+ * The sample intentionally shows just one model: it's illustrative, not
169
+ * a substitute for the full scaffolded contract file. The TS samples use
170
+ * the same outer shape as `starterSchemaTs*` (FR5.3) so a user reading
171
+ * the doc and the file side-by-side sees the same structure.
172
+ */
173
+ function schemaSample(target, authoring) {
174
+ if (authoring === "typescript") return target === "mongo" ? schemaSampleTsMongo() : schemaSampleTsPostgres();
175
+ return target === "mongo" ? schemaSamplePslMongo() : schemaSamplePslPostgres();
176
+ }
177
+ function schemaSamplePslPostgres() {
178
+ return `\`\`\`prisma
179
+ model User {
180
+ id Int @id @default(autoincrement())
181
+ email String @unique
182
+ username String?
183
+ name String?
184
+ }
185
+ \`\`\``;
186
+ }
187
+ function schemaSamplePslMongo() {
188
+ return `\`\`\`prisma
189
+ model User {
190
+ id ObjectId @id @map("_id")
191
+ email String @unique
192
+ username String?
193
+ name String?
194
+ @@map("users")
195
+ }
196
+ \`\`\``;
197
+ }
198
+ function schemaSampleTsPostgres() {
199
+ return `\`\`\`typescript
200
+ import { defineContract } from '@prisma-next/postgres/contract-builder';
201
+
202
+ export const contract = defineContract(
203
+ {},
204
+ ({ field, model }) => ({
205
+ models: {
206
+ User: model('User', {
207
+ fields: {
208
+ id: field.id.uuidv7(),
209
+ email: field.text().unique(),
210
+ username: field.text().optional(),
211
+ name: field.text().optional(),
212
+ },
213
+ }),
214
+ },
215
+ }),
216
+ );
217
+ \`\`\``;
218
+ }
219
+ function schemaSampleTsMongo() {
220
+ return `\`\`\`typescript
221
+ import { defineContract } from '@prisma-next/mongo/contract-builder';
222
+
223
+ export const contract = defineContract(
224
+ {},
225
+ ({ field, model }) => ({
226
+ models: {
227
+ User: model('User', {
228
+ collection: 'users',
229
+ fields: {
230
+ _id: field.objectId(),
231
+ email: field.string(),
232
+ username: field.string().optional(),
233
+ name: field.string().optional(),
234
+ },
235
+ }),
236
+ },
237
+ }),
238
+ );
239
+ \`\`\``;
240
+ }
241
+ function starterSchemaPslPostgres() {
242
+ return `// use prisma-next
243
+
244
+ model User {
245
+ id Int @id @default(autoincrement())
246
+ email String @unique
247
+ username String?
248
+ name String?
249
+ posts Post[]
250
+ createdAt DateTime @default(now())
251
+ updatedAt temporal.updatedAt()
252
+ }
253
+
254
+ model Post {
255
+ id Int @id @default(autoincrement())
256
+ title String
257
+ content String?
258
+ author User @relation(fields: [authorId], references: [id])
259
+ authorId Int
260
+ createdAt DateTime @default(now())
261
+ updatedAt temporal.updatedAt()
262
+ }
263
+ `;
264
+ }
265
+ function starterSchemaPslMongo() {
266
+ return `// use prisma-next
267
+
268
+ model User {
269
+ id ObjectId @id @map("_id")
270
+ email String @unique
271
+ username String?
272
+ name String?
273
+ posts Post[]
274
+ @@map("users")
275
+ }
276
+
277
+ model Post {
278
+ id ObjectId @id @map("_id")
279
+ title String
280
+ content String?
281
+ author User @relation(fields: [authorId], references: [id])
282
+ authorId ObjectId
283
+ @@map("posts")
284
+ }
285
+ `;
286
+ }
287
+ function starterSchemaTsPostgres() {
288
+ return `import { defineContract } from '@prisma-next/postgres/contract-builder';
289
+
290
+ export const contract = defineContract(
291
+ {},
292
+ ({ field, model, rel }) => ({
293
+ models: {
294
+ User: model('User', {
295
+ fields: {
296
+ id: field.id.uuidv7(),
297
+ email: field.text().unique(),
298
+ username: field.text().optional(),
299
+ name: field.text().optional(),
300
+ createdAt: field.temporal.createdAt(),
301
+ updatedAt: field.temporal.updatedAt(),
302
+ },
303
+ relations: {
304
+ posts: rel.hasMany('Post', { by: 'authorId' }),
305
+ },
306
+ }),
307
+
308
+ Post: model('Post', {
309
+ fields: {
310
+ id: field.id.uuidv7(),
311
+ title: field.text(),
312
+ content: field.text().optional(),
313
+ authorId: field.uuid(),
314
+ createdAt: field.temporal.createdAt(),
315
+ updatedAt: field.temporal.updatedAt(),
316
+ },
317
+ relations: {
318
+ author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),
319
+ },
320
+ }),
321
+ },
322
+ }),
323
+ );
324
+ `;
325
+ }
326
+ function starterSchemaTsMongo() {
327
+ return `import { defineContract } from '@prisma-next/mongo/contract-builder';
328
+
329
+ export const contract = defineContract(
330
+ {},
331
+ ({ field, model, rel }) => ({
332
+ models: {
333
+ User: model('User', {
334
+ collection: 'users',
335
+ fields: {
336
+ _id: field.objectId(),
337
+ email: field.string(),
338
+ username: field.string().optional(),
339
+ name: field.string().optional(),
340
+ },
341
+ relations: {
342
+ posts: rel.hasMany('Post', { from: '_id', to: 'authorId' }),
343
+ },
344
+ }),
345
+
346
+ Post: model('Post', {
347
+ collection: 'posts',
348
+ fields: {
349
+ _id: field.objectId(),
350
+ title: field.string(),
351
+ content: field.string().optional(),
352
+ authorId: field.objectId(),
353
+ },
354
+ relations: {
355
+ author: rel.belongsTo('User', { from: 'authorId', to: '_id' }),
356
+ },
357
+ }),
358
+ },
359
+ }),
360
+ );
361
+ `;
362
+ }
363
+ function configFile(target, contractPath) {
364
+ return `import 'dotenv/config';
365
+ import { defineConfig } from '${targetPackageName(target)}/config';
366
+
367
+ export default defineConfig({
368
+ contract: ${JSON.stringify(contractPath)},
369
+ db: {
370
+ connection: process.env['DATABASE_URL']!,
371
+ },
372
+ });
373
+ `;
374
+ }
375
+ function dbFile(target) {
376
+ if (target === "postgres") return `import postgres from '@prisma-next/postgres/runtime';
377
+ import type { Contract } from './contract.d';
378
+ import contractJson from './contract.json' with { type: 'json' };
379
+
380
+ export const db = postgres<Contract>({
381
+ contractJson,
382
+ url: process.env['DATABASE_URL']!,
383
+ });
384
+ `;
385
+ return `import mongo from '@prisma-next/mongo/runtime';
386
+ import type { Contract } from './contract.d';
387
+ import contractJson from './contract.json' with { type: 'json' };
388
+
389
+ export const db = mongo<Contract>({
390
+ contractJson,
391
+ url: process.env['DATABASE_URL']!,
392
+ });
393
+ `;
394
+ }
25
395
  //#endregion
26
396
  //#region src/commands/init/index.ts
27
397
  function createInitCommand() {
@@ -40,11 +410,11 @@ Exit codes (see CLI Style Guide § Exit Codes):
40
410
  "prisma-next init --yes --target mongodb --authoring typescript --json",
41
411
  "prisma-next init --yes --force --target postgres --authoring psl # overwrite an existing scaffold",
42
412
  "prisma-next init --no-install # skip pnpm/npm install + emit",
43
- "prisma-next init --no-skill # skip the agent-skill install (air-gapped / restricted env)"
413
+ "prisma-next init --no-skill # skip the skills install (air-gapped / restricted env)"
44
414
  ]);
45
- return addGlobalOptions(command).option("--target <db>", "Database target: postgres or mongodb").option("--authoring <style>", "Schema authoring style: psl or typescript").option("--schema-path <path>", "Where to write the starter schema (default: prisma/contract.prisma)").option("--force", "Overwrite an existing scaffold without prompting").option("--write-env", "Write a .env file from .env.example (gitignored; default: only .env.example)").option("--probe-db", "Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)").option("--strict-probe", "Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)").option("--no-install", "Skip dependency installation and contract emission").option("--no-skill", "Skip Prisma Next skills install (air-gapped CI, restricted registries, etc.)").action(async (options) => {
46
- const { runInit } = await import("./init-eh2z5Tl6.mjs");
47
- const flags = parseGlobalFlags(options);
415
+ return addGlobalOptions(command).option("--target <db>", "Database target: postgres or mongodb").option("--authoring <style>", "Schema authoring style: psl or typescript").option("--schema-path <path>", `Where to write the starter schema (default: ${defaultSchemaPath("psl")})`).option("--force", "Overwrite an existing scaffold without prompting").option("--write-env", "Write a .env file from .env.example (gitignored; default: only .env.example)").option("--probe-db", "Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)").option("--strict-probe", "Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)").option("--no-install", "Skip dependency installation and contract emission").option("--no-skill", "Skip Prisma Next skills install (air-gapped CI, restricted registries, etc.)").action(async (options, actionCommand) => {
416
+ const { runInit } = await import("./init-YX6lCJpG.mjs");
417
+ const flags = parseGlobalFlagsOrExit(options);
48
418
  const canPrompt = deriveCanPrompt({
49
419
  flagsInteractive: flags.interactive,
50
420
  optionInteractive: options.interactive,
@@ -53,7 +423,10 @@ Exit codes (see CLI Style Guide § Exit Codes):
53
423
  const exitCode = await runInit(process.cwd(), {
54
424
  options,
55
425
  flags,
56
- canPrompt
426
+ canPrompt,
427
+ afterFirstTelemetryConsent: (inputs) => {
428
+ fireTelemetryAfterInitConsent(actionCommand, { databaseTarget: inputs.target });
429
+ }
57
430
  });
58
431
  process.exit(exitCode);
59
432
  });
@@ -137,6 +510,11 @@ function formatSuggestion(input, candidates) {
137
510
  }
138
511
  const program = new Command();
139
512
  program.name("prisma-next").description("Prisma Next CLI").version(version);
513
+ program.hook("preAction", (_thisCommand, actionCommand) => {
514
+ try {
515
+ fireTelemetryFromPreAction(actionCommand);
516
+ } catch {}
517
+ });
140
518
  const versionOption = program.options.find((opt) => opt.flags.includes("--version"));
141
519
  if (versionOption) versionOption.description = "Output the version number";
142
520
  program.configureOutput({
@@ -272,6 +650,15 @@ program.addCommand(contractCommand);
272
650
  program.addCommand(dbCommand);
273
651
  program.addCommand(migrationCommand);
274
652
  program.addCommand(refCommand);
653
+ const TELEMETRY_CRASH_TEST_SLEEP_MS = 200;
654
+ if (process.env["PRISMA_NEXT_ENABLE_TEST_COMMANDS"] === "1") {
655
+ const telemetryCrashTestCommand = new Command("__telemetry-crash-test").description("Internal: deliberately throw for the telemetry e2e suite.").action(async () => {
656
+ await new Promise((settle) => setTimeout(settle, TELEMETRY_CRASH_TEST_SLEEP_MS));
657
+ throw new Error("__telemetry-crash-test: intentional crash for e2e coverage");
658
+ });
659
+ telemetryCrashTestCommand.configureHelp({ visibleCommands: () => [] });
660
+ program.addCommand(telemetryCrashTestCommand, { hidden: true });
661
+ }
275
662
  const helpCommand = new Command("help").description("Show usage instructions").configureHelp({ formatHelp: (cmd) => {
276
663
  return formatCommandHelp({
277
664
  command: cmd,
@@ -342,6 +729,6 @@ if (args.length > 0) {
342
729
  }
343
730
  program.parse();
344
731
  //#endregion
345
- export { version as t };
732
+ export { starterSchema as a, version as c, schemaSample as i, dbFile as n, targetLabel as o, defaultSchemaPath as r, targetPackageName as s, configFile as t };
346
733
 
347
734
  //# sourceMappingURL=cli.mjs.map