@prisma-next/cli 0.15.0 → 0.16.0-dev.10

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 (177) hide show
  1. package/README.md +3 -4
  2. package/dist/cli.d.mts +1 -1
  3. package/dist/cli.mjs +13 -13
  4. package/dist/{client-DigVI8zX.mjs → client-2kwLMBSf.mjs} +67 -36
  5. package/dist/client-2kwLMBSf.mjs.map +1 -0
  6. package/dist/{command-helpers-CUoKYTlG.mjs → command-helpers-CVn3U9Uz.mjs} +32 -8
  7. package/dist/command-helpers-CVn3U9Uz.mjs.map +1 -0
  8. package/dist/commands/contract-emit.d.mts +0 -1
  9. package/dist/commands/contract-emit.d.mts.map +1 -1
  10. package/dist/commands/contract-emit.mjs +1 -1
  11. package/dist/commands/contract-infer.d.mts +0 -1
  12. package/dist/commands/contract-infer.d.mts.map +1 -1
  13. package/dist/commands/contract-infer.mjs +1 -1
  14. package/dist/commands/db-init.d.mts +0 -1
  15. package/dist/commands/db-init.d.mts.map +1 -1
  16. package/dist/commands/db-init.mjs +8 -7
  17. package/dist/commands/db-init.mjs.map +1 -1
  18. package/dist/commands/db-schema.d.mts +0 -1
  19. package/dist/commands/db-schema.d.mts.map +1 -1
  20. package/dist/commands/db-schema.mjs +3 -3
  21. package/dist/commands/db-sign.d.mts +0 -1
  22. package/dist/commands/db-sign.d.mts.map +1 -1
  23. package/dist/commands/db-sign.mjs +8 -10
  24. package/dist/commands/db-sign.mjs.map +1 -1
  25. package/dist/commands/db-update.d.mts +0 -1
  26. package/dist/commands/db-update.d.mts.map +1 -1
  27. package/dist/commands/db-update.mjs +12 -14
  28. package/dist/commands/db-update.mjs.map +1 -1
  29. package/dist/commands/db-verify.d.mts +0 -1
  30. package/dist/commands/db-verify.d.mts.map +1 -1
  31. package/dist/commands/db-verify.mjs +1 -1
  32. package/dist/commands/migrate.d.mts +1 -2
  33. package/dist/commands/migrate.d.mts.map +1 -1
  34. package/dist/commands/migrate.mjs +7 -7
  35. package/dist/commands/migrate.mjs.map +1 -1
  36. package/dist/commands/migration-check.d.mts +4 -3
  37. package/dist/commands/migration-check.d.mts.map +1 -1
  38. package/dist/commands/migration-check.mjs +1 -1
  39. package/dist/commands/migration-graph.d.mts +2 -3
  40. package/dist/commands/migration-graph.d.mts.map +1 -1
  41. package/dist/commands/migration-graph.mjs +3 -3
  42. package/dist/commands/migration-list.d.mts +2 -3
  43. package/dist/commands/migration-list.d.mts.map +1 -1
  44. package/dist/commands/migration-list.mjs +1 -1
  45. package/dist/commands/migration-log.d.mts +2 -3
  46. package/dist/commands/migration-log.d.mts.map +1 -1
  47. package/dist/commands/migration-log.mjs +1 -1
  48. package/dist/commands/migration-new.d.mts +0 -1
  49. package/dist/commands/migration-new.d.mts.map +1 -1
  50. package/dist/commands/migration-new.mjs +14 -38
  51. package/dist/commands/migration-new.mjs.map +1 -1
  52. package/dist/commands/migration-plan.d.mts +0 -1
  53. package/dist/commands/migration-plan.d.mts.map +1 -1
  54. package/dist/commands/migration-plan.mjs +1 -1
  55. package/dist/commands/migration-show.d.mts +0 -1
  56. package/dist/commands/migration-show.d.mts.map +1 -1
  57. package/dist/commands/migration-show.mjs +3 -3
  58. package/dist/commands/migration-status.d.mts +2 -3
  59. package/dist/commands/migration-status.d.mts.map +1 -1
  60. package/dist/commands/migration-status.mjs +1 -1
  61. package/dist/commands/ref.d.mts +1 -2
  62. package/dist/commands/ref.d.mts.map +1 -1
  63. package/dist/commands/ref.mjs +13 -18
  64. package/dist/commands/ref.mjs.map +1 -1
  65. package/dist/commands/telemetry/index.d.mts +0 -1
  66. package/dist/commands/telemetry/index.d.mts.map +1 -1
  67. package/dist/commands/telemetry/index.mjs +1 -1
  68. package/dist/contract-at-errors-C-l4-JEY.mjs +36 -0
  69. package/dist/contract-at-errors-C-l4-JEY.mjs.map +1 -0
  70. package/dist/{contract-emit-wgqrOXUI.mjs → contract-emit-DzOkTs11.mjs} +3 -3
  71. package/dist/{contract-emit-wgqrOXUI.mjs.map → contract-emit-DzOkTs11.mjs.map} +1 -1
  72. package/dist/{contract-emit-sYrqzsdN.mjs → contract-emit-iSMJVs26.mjs} +3 -3
  73. package/dist/{contract-emit-sYrqzsdN.mjs.map → contract-emit-iSMJVs26.mjs.map} +1 -1
  74. package/dist/{contract-infer-6SQnnVj7.mjs → contract-infer-BVqworBB.mjs} +3 -3
  75. package/dist/{contract-infer-6SQnnVj7.mjs.map → contract-infer-BVqworBB.mjs.map} +1 -1
  76. package/dist/{contract-space-aggregate-loader-DpB4x97a.mjs → contract-space-aggregate-loader-hPVymNLw.mjs} +14 -15
  77. package/dist/contract-space-aggregate-loader-hPVymNLw.mjs.map +1 -0
  78. package/dist/{db-verify-CEsG5Gek.mjs → db-verify-BpwCMyWJ.mjs} +6 -7
  79. package/dist/db-verify-BpwCMyWJ.mjs.map +1 -0
  80. package/dist/exports/control-api.d.mts +1 -2
  81. package/dist/exports/control-api.d.mts.map +1 -1
  82. package/dist/exports/control-api.mjs +2 -2
  83. package/dist/exports/index.d.mts +0 -1
  84. package/dist/exports/index.d.mts.map +1 -1
  85. package/dist/exports/index.mjs +2 -2
  86. package/dist/exports/init-output.d.mts +1 -0
  87. package/dist/exports/init-output.d.mts.map +1 -1
  88. package/dist/exports/init-output.mjs +1 -1
  89. package/dist/{format-CjongNb1.mjs → format-CFLZv_zU.mjs} +6 -5
  90. package/dist/format-CFLZv_zU.mjs.map +1 -0
  91. package/dist/{framework-components-BbnM1RYm.mjs → framework-components-VMQJbAwl.mjs} +2 -2
  92. package/dist/{framework-components-BbnM1RYm.mjs.map → framework-components-VMQJbAwl.mjs.map} +1 -1
  93. package/dist/global-flags-BpoOYtNZ.d.mts.map +1 -1
  94. package/dist/{init-D8YFfaD6.mjs → init-BSgPxVXA.mjs} +85 -90
  95. package/dist/init-BSgPxVXA.mjs.map +1 -0
  96. package/dist/{inspect-live-schema-CEt_ztBJ.mjs → inspect-live-schema-DxsD_a4d.mjs} +3 -3
  97. package/dist/{inspect-live-schema-CEt_ztBJ.mjs.map → inspect-live-schema-DxsD_a4d.mjs.map} +1 -1
  98. package/dist/{migration-check-ByeQHOhK.mjs → migration-check-DMxPzbHl.mjs} +70 -44
  99. package/dist/migration-check-DMxPzbHl.mjs.map +1 -0
  100. package/dist/migration-cli.d.mts +0 -1
  101. package/dist/migration-cli.d.mts.map +1 -1
  102. package/dist/migration-cli.mjs +3 -3
  103. package/dist/migration-cli.mjs.map +1 -1
  104. package/dist/{migration-command-scaffold-CJO3tjiR.mjs → migration-command-scaffold-DB_i9nBC.mjs} +3 -3
  105. package/dist/{migration-command-scaffold-CJO3tjiR.mjs.map → migration-command-scaffold-DB_i9nBC.mjs.map} +1 -1
  106. package/dist/{migration-list-DTYM8xvm.mjs → migration-list-cnSKilYH.mjs} +5 -5
  107. package/dist/migration-list-cnSKilYH.mjs.map +1 -0
  108. package/dist/{migration-log-qZ8LpQIl.mjs → migration-log-CEqFiez9.mjs} +3 -3
  109. package/dist/{migration-log-qZ8LpQIl.mjs.map → migration-log-CEqFiez9.mjs.map} +1 -1
  110. package/dist/{migration-path-target-DmNwsDgs.mjs → migration-path-target-C0TQuV5n.mjs} +2 -2
  111. package/dist/{migration-path-target-DmNwsDgs.mjs.map → migration-path-target-C0TQuV5n.mjs.map} +1 -1
  112. package/dist/{migration-plan-CfPrB80t.mjs → migration-plan-BJHulFZC.mjs} +54 -62
  113. package/dist/migration-plan-BJHulFZC.mjs.map +1 -0
  114. package/dist/{migration-status-DRuS-rP5.mjs → migration-status-ugWwGk1V.mjs} +5 -5
  115. package/dist/{migration-status-DRuS-rP5.mjs.map → migration-status-ugWwGk1V.mjs.map} +1 -1
  116. package/dist/{output-mEQ74_nd.mjs → output-DWNYqZGc.mjs} +5 -6
  117. package/dist/output-DWNYqZGc.mjs.map +1 -0
  118. package/dist/{ref-advancement-BkXlikCA.mjs → ref-advancement-BCz7X7qJ.mjs} +13 -6
  119. package/dist/ref-advancement-BCz7X7qJ.mjs.map +1 -0
  120. package/dist/schemas-CeGMYFYX.d.mts.map +1 -1
  121. package/dist/{telemetry-DHBBq5wT.mjs → telemetry-BEyNMfco.mjs} +2 -2
  122. package/dist/{telemetry-DHBBq5wT.mjs.map → telemetry-BEyNMfco.mjs.map} +1 -1
  123. package/dist/{terminal-ui-DGRNFWna.d.mts → terminal-ui-BN4QOsm5.d.mts} +1 -2
  124. package/dist/terminal-ui-BN4QOsm5.d.mts.map +1 -0
  125. package/dist/{types-DFoqNIcQ.d.mts → types-D4r_HI9-.d.mts} +8 -4
  126. package/dist/types-D4r_HI9-.d.mts.map +1 -0
  127. package/dist/{verify-DDCb0R2r.mjs → verify-C4RazDE1.mjs} +9 -8
  128. package/dist/verify-C4RazDE1.mjs.map +1 -0
  129. package/package.json +25 -25
  130. package/src/commands/db-init.ts +4 -3
  131. package/src/commands/db-sign.ts +6 -4
  132. package/src/commands/db-update.ts +15 -7
  133. package/src/commands/db-verify.ts +2 -3
  134. package/src/commands/init/errors.ts +62 -58
  135. package/src/commands/init/hygiene-gitattributes.ts +37 -21
  136. package/src/commands/init/init.ts +35 -32
  137. package/src/commands/init/output.ts +4 -5
  138. package/src/commands/init/reinit-cleanup.ts +16 -17
  139. package/src/commands/migrate.ts +1 -0
  140. package/src/commands/migration-check.ts +75 -38
  141. package/src/commands/migration-list.ts +1 -5
  142. package/src/commands/migration-new.ts +15 -39
  143. package/src/commands/migration-plan.ts +56 -78
  144. package/src/commands/ref.ts +19 -14
  145. package/src/control-api/operations/db-run.ts +4 -4
  146. package/src/control-api/operations/db-verify.ts +12 -9
  147. package/src/control-api/operations/format.ts +4 -3
  148. package/src/control-api/operations/migrate.ts +70 -26
  149. package/src/control-api/types.ts +4 -1
  150. package/src/migration-cli.ts +5 -5
  151. package/src/utils/cli-errors.ts +28 -7
  152. package/src/utils/combine-verify-results.ts +1 -1
  153. package/src/utils/contract-at-errors.ts +13 -22
  154. package/src/utils/contract-space-aggregate-loader.ts +12 -13
  155. package/src/utils/contract-space-seed-phase.ts +8 -6
  156. package/src/utils/formatters/errors.ts +24 -3
  157. package/src/utils/formatters/verify.ts +7 -6
  158. package/src/utils/integrity-violation-to-check-failure.ts +14 -14
  159. package/src/utils/plan-resolution.ts +6 -9
  160. package/src/utils/ref-advancement.ts +22 -3
  161. package/src/utils/result-handler.ts +4 -2
  162. package/dist/client-DigVI8zX.mjs.map +0 -1
  163. package/dist/command-helpers-CUoKYTlG.mjs.map +0 -1
  164. package/dist/contract-at-errors-D8CNDD7g.mjs +0 -42
  165. package/dist/contract-at-errors-D8CNDD7g.mjs.map +0 -1
  166. package/dist/contract-space-aggregate-loader-DpB4x97a.mjs.map +0 -1
  167. package/dist/db-verify-CEsG5Gek.mjs.map +0 -1
  168. package/dist/format-CjongNb1.mjs.map +0 -1
  169. package/dist/init-D8YFfaD6.mjs.map +0 -1
  170. package/dist/migration-check-ByeQHOhK.mjs.map +0 -1
  171. package/dist/migration-list-DTYM8xvm.mjs.map +0 -1
  172. package/dist/migration-plan-CfPrB80t.mjs.map +0 -1
  173. package/dist/output-mEQ74_nd.mjs.map +0 -1
  174. package/dist/ref-advancement-BkXlikCA.mjs.map +0 -1
  175. package/dist/terminal-ui-DGRNFWna.d.mts.map +0 -1
  176. package/dist/types-DFoqNIcQ.d.mts.map +0 -1
  177. package/dist/verify-DDCb0R2r.mjs.map +0 -1
package/README.md CHANGED
@@ -952,15 +952,14 @@ prisma-next migration plan [--config <path>] [--name <slug>] [--from <contract>]
952
952
  2. Reads existing migrations from `config.migrations.dir` (default: `migrations/`)
953
953
  3. Determines the starting point: `--from <contract>` if provided, otherwise the `db` ref (greenfield when absent)
954
954
  4. Diffs the starting contract against the destination using the target's migration planner
955
- 5. Scaffolds a new migration package: `migration.ts` (containing `placeholder(...)` lambdas for any data transforms), `migration.json` (with a content-addressed `migrationHash` over the planned ops, or over `[]` when the planner could not lower any calls because of placeholders), `ops.json` (the planned ops, or `[]` in the placeholder-blocked case), and contract bookends. The package is **always** fully attested — there is no draft state on disk.
955
+ 5. Scaffolds a new migration package: `migration.ts` (containing `placeholder(...)` lambdas for any data transforms), `migration.json` (with a content-addressed `migrationHash` over the planned ops, or over `[]` when the planner could not lower any calls because of placeholders), and `ops.json` (the planned ops, or `[]` in the placeholder-blocked case). The bookend contracts are written write-if-absent into the shared snapshot store at `migrations/snapshots/<hex>/contract.{json,d.ts}`. The package is **always** fully attested — there is no draft state on disk.
956
956
  6. If the plan has unfilled `placeholder(...)` slots, the command returns a successful `pendingPlaceholders` envelope (a warning, not a failure) asking the developer to fill in the slots before re-emitting. The on-disk `ops.json` is `[]` and `migrationHash` is the hash of `(metadata, [])`, so applying the migration as-written will not advance the storage hash to the intended destination — the runner's destination-hash post-check surfaces this as a state mismatch. After filling in the placeholders, run `node migrations/<dir>/migration.ts` to re-emit `ops.json` and the corresponding `migrationHash`. `PN-MIG-2001` is raised only at self-emit time when a slot is still unfilled.
957
957
 
958
958
  **Outputs:**
959
959
  - `migrations/<dir>/migration.ts` — editable migration source (with `placeholder(...)` slots when the planner inserted them)
960
960
  - `migrations/<dir>/migration.json` — fully attested metadata (`migrationHash: string`, never null)
961
961
  - `migrations/<dir>/ops.json` — planned operations (empty list `[]` if placeholders blocked the planner)
962
- - `migrations/<dir>/start-contract.{json,d.ts}` — bookend from the "from" side (when applicable)
963
- - `migrations/<dir>/end-contract.{json,d.ts}` — bookend from the "to" side
962
+ - `migrations/snapshots/<hex>/contract.{json,d.ts}` — bookend contracts, written write-if-absent, keyed by each contract's storage hash (one entry for `from` when applicable, one for `to`)
964
963
 
965
964
  **Branching with `--from` and `--to`:** Use `--from` to create a migration edge from a specific contract hash instead of the default starting point. Use `--to` to plan toward any resolved contract — including a rollback via `<migration-dir>^` — instead of the emitted contract. This enables branched migration graphs and arbitrary-target (including reverse) edges without editing contract source.
966
965
 
@@ -1028,7 +1027,7 @@ prisma-next migrate [--db <url>] [--to <contract>] [--config <path>] [--json] [-
1028
1027
 
1029
1028
  **Options:**
1030
1029
  - `--db <url>`: Database connection string (optional; defaults to `config.db.connection`)
1031
- - `--to <contract>`: Target contract reference (hash, prefix, ref name, migration directory, `<dir>^`, or filesystem path). When omitted, applies toward the emitted `contract.json`. When `--to` resolves to an on-disk graph node, verification and apply use that bundle's `end-contract.json` — so a planned rollback or other arbitrary-target edge applies without editing contract source.
1030
+ - `--to <contract>`: Target contract reference (hash, prefix, ref name, migration directory, `<dir>^`, or filesystem path). When omitted, applies toward the emitted `contract.json`. When `--to` resolves to an on-disk graph node, verification and apply use the snapshot store entry for that node's hash — so a planned rollback or other arbitrary-target edge applies without editing contract source.
1032
1031
  - `--ref <name>`: Target a named ref from `migrations/refs.json` instead of the current contract hash
1033
1032
  - `--config <path>`: Path to `prisma-next.config.ts`
1034
1033
  - `--json`: Output as JSON object
package/dist/cli.d.mts CHANGED
@@ -1 +1 @@
1
- export { };
1
+ export {}
package/dist/cli.mjs CHANGED
@@ -1,31 +1,31 @@
1
1
  #!/usr/bin/env node
2
- import { D as isCI, O as formatCommandHelp, g as parseGlobalFlagsOrExit, h as parseGlobalFlags, k as formatRootHelp, l as setCommandDescriptions, m as deriveCanPrompt, t as addGlobalOptions, u as setCommandExamples, v as installShutdownHandlers } from "./command-helpers-CUoKYTlG.mjs";
3
- import { t as createContractEmitCommand } from "./contract-emit-wgqrOXUI.mjs";
4
- import { t as createContractInferCommand } from "./contract-infer-6SQnnVj7.mjs";
2
+ import { D as isCI, O as formatCommandHelp, g as parseGlobalFlagsOrExit, h as parseGlobalFlags, k as formatRootHelp, l as setCommandDescriptions, m as deriveCanPrompt, t as addGlobalOptions, u as setCommandExamples, v as installShutdownHandlers } from "./command-helpers-CVn3U9Uz.mjs";
3
+ import { t as createContractEmitCommand } from "./contract-emit-DzOkTs11.mjs";
4
+ import { t as createContractInferCommand } from "./contract-infer-BVqworBB.mjs";
5
5
  import { createDbInitCommand } from "./commands/db-init.mjs";
6
6
  import { createDbSchemaCommand } from "./commands/db-schema.mjs";
7
7
  import { createDbSignCommand } from "./commands/db-sign.mjs";
8
8
  import { createDbUpdateCommand } from "./commands/db-update.mjs";
9
- import { t as createDbVerifyCommand } from "./db-verify-CEsG5Gek.mjs";
10
- import { t as createFormatCommand } from "./format-CjongNb1.mjs";
11
- import { t as createMigrationListCommand } from "./migration-list-DTYM8xvm.mjs";
9
+ import { t as createDbVerifyCommand } from "./db-verify-BpwCMyWJ.mjs";
10
+ import { t as createFormatCommand } from "./format-CFLZv_zU.mjs";
11
+ import { t as createMigrationListCommand } from "./migration-list-cnSKilYH.mjs";
12
12
  import { createMigrateCommand } from "./commands/migrate.mjs";
13
- import { t as createMigrationCheckCommand } from "./migration-check-ByeQHOhK.mjs";
13
+ import { t as createMigrationCheckCommand } from "./migration-check-DMxPzbHl.mjs";
14
14
  import { createMigrationGraphCommand } from "./commands/migration-graph.mjs";
15
- import { t as createMigrationLogCommand } from "./migration-log-qZ8LpQIl.mjs";
15
+ import { t as createMigrationLogCommand } from "./migration-log-CEqFiez9.mjs";
16
16
  import { createMigrationNewCommand } from "./commands/migration-new.mjs";
17
- import { t as createMigrationPlanCommand } from "./migration-plan-CfPrB80t.mjs";
17
+ import { t as createMigrationPlanCommand } from "./migration-plan-BJHulFZC.mjs";
18
18
  import { createMigrationShowCommand } from "./commands/migration-show.mjs";
19
- import { r as createMigrationStatusCommand } from "./migration-status-DRuS-rP5.mjs";
19
+ import { r as createMigrationStatusCommand } from "./migration-status-ugWwGk1V.mjs";
20
20
  import { createRefCommand } from "./commands/ref.mjs";
21
- import { t as createTelemetryCommand } from "./telemetry-DHBBq5wT.mjs";
21
+ import { t as createTelemetryCommand } from "./telemetry-BEyNMfco.mjs";
22
22
  import { Command } from "commander";
23
23
  import { DEFAULT_CONTRACT_SOURCE_DIR } from "@prisma-next/config/config-types";
24
24
  import { ensureInstallationId, readUserConfig, resolveGating, runTelemetry, userConfigPath } from "@prisma-next/cli-telemetry";
25
25
  import { distance } from "closest-match";
26
26
  import { fileURLToPath } from "node:url";
27
27
  //#region package.json
28
- var version = "0.15.0";
28
+ var version = "0.16.0-dev.10";
29
29
  //#endregion
30
30
  //#region src/commands/init/templates/code-templates.ts
31
31
  function targetPackageName(target) {
@@ -294,7 +294,7 @@ Exit codes (see CLI Style Guide § Exit Codes):
294
294
  "prisma-next init --no-skill # skip the skills install (air-gapped / restricted env)"
295
295
  ]);
296
296
  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) => {
297
- const { runInit } = await import("./init-D8YFfaD6.mjs");
297
+ const { runInit } = await import("./init-BSgPxVXA.mjs");
298
298
  const flags = parseGlobalFlagsOrExit(options);
299
299
  const canPrompt = deriveCanPrompt({
300
300
  flagsInteractive: flags.interactive,
@@ -1,13 +1,13 @@
1
- import { F as CliStructuredError } from "./command-helpers-CUoKYTlG.mjs";
2
- import { t as assertFrameworkComponentsCompatible } from "./framework-components-BbnM1RYm.mjs";
1
+ import { F as CliStructuredError } from "./command-helpers-CVn3U9Uz.mjs";
2
+ import { t as assertFrameworkComponentsCompatible } from "./framework-components-VMQJbAwl.mjs";
3
3
  import { t as enrichContract } from "./contract-enrichment-gn9sWbPw.mjs";
4
- import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-DpB4x97a.mjs";
4
+ import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-hPVymNLw.mjs";
5
5
  import { emit } from "@prisma-next/emitter";
6
6
  import { ifDefined } from "@prisma-next/utils/defined";
7
7
  import { notOk, ok } from "@prisma-next/utils/result";
8
8
  import { APP_SPACE_ID, createControlStack, hasMigrations, hasOperationPreview, hasPslContractInfer, hasSchemaSubjectClassifier, hasSchemaView } from "@prisma-next/framework-components/control";
9
9
  import { blindCast, castAs } from "@prisma-next/utils/casts";
10
- import { buildFabricatedMigrationEdge, collectAggregateNamespaces, planMigration, requireHeadRef, resolveRecordedPath, verifyMigration } from "@prisma-next/migration-tools/aggregate";
10
+ import { allStorageElementsExternal, buildFabricatedMigrationEdge, collectAggregateNamespaces, planMigration, requireHeadRef, resolveRecordedPath, verifyMigration } from "@prisma-next/migration-tools/aggregate";
11
11
  import { EMPTY_CONTRACT_HASH } from "@prisma-next/migration-tools/constants";
12
12
  import { errorNoInvariantPath } from "@prisma-next/migration-tools/errors";
13
13
  import { findPathWithDecision } from "@prisma-next/migration-tools/migration-graph";
@@ -330,8 +330,9 @@ function aggregatePlannerWarnings(orderedResolutions) {
330
330
  * an extension that was removed from `extensionPacks` without first
331
331
  * cleaning up its on-disk migrations / database tables.
332
332
  *
333
- * Returns a {@link CliStructuredError} envelope (code `5002`,
334
- * `kind: 'orphanMarker'`) for the first orphan it finds, or `null`
333
+ * Returns a {@link CliStructuredError} envelope (code
334
+ * `MIGRATION.CONTRACT_SPACE_VIOLATION`, `kind: 'orphanMarker'`) for the
335
+ * first orphan it finds, or `null`
335
336
  * when every marker row maps to a declared contract space. Mirrors the M2
336
337
  * `runContractSpaceVerifierMarkerCheck` envelope so downstream
337
338
  * tooling (integration tests, JSON consumers) keeps asserting on the
@@ -343,8 +344,7 @@ function detectOrphanMarkers(aggregate, markerRows) {
343
344
  for (const [spaceId, row] of markerRows) if (row !== null && row !== void 0 && !aggregateSpaceIds.has(spaceId)) orphans.push(spaceId);
344
345
  if (orphans.length === 0) return null;
345
346
  orphans.sort((a, b) => a.localeCompare(b));
346
- return new CliStructuredError("5002", orphans.length === 1 ? `Orphan contract-space marker detected for "${orphans[0]}"` : `Orphan contract-space markers detected for ${orphans.length} spaces`, {
347
- domain: "MIG",
347
+ return new CliStructuredError("MIGRATION.CONTRACT_SPACE_VIOLATION", orphans.length === 1 ? `Orphan contract-space marker detected for "${orphans[0]}"` : `Orphan contract-space markers detected for ${orphans.length} spaces`, {
348
348
  why: `The database has \`_prisma_marker\` rows for spaces (${orphans.map((s) => `"${s}"`).join(", ")}) that are not declared in the project's \`extensionPacks\`. The aggregate pipeline refuses to advance markers it cannot account for.`,
349
349
  fix: "Either re-declare the missing extension(s) in `extensionPacks` (so the aggregate owns them again), or remove the orphan marker row(s) from `_prisma_marker` once you have confirmed the corresponding tables can be safely retired.",
350
350
  docsUrl: "https://pris.ly/contract-spaces",
@@ -663,8 +663,7 @@ function finaliseVerifyResult(args) {
663
663
  const { verifyResult, aggregate, skipMarker, onProgress } = args;
664
664
  if (!verifyResult.ok) {
665
665
  emitVerifySpan(onProgress, "spanEndError");
666
- return notOk(new CliStructuredError("5002", "Aggregate verifier introspection failed", {
667
- domain: "MIG",
666
+ return notOk(new CliStructuredError("MIGRATION.CONTRACT_SPACE_VIOLATION", "Aggregate verifier introspection failed", {
668
667
  why: verifyResult.failure.detail,
669
668
  fix: "Check database connectivity and the introspection tooling.",
670
669
  docsUrl: "https://pris.ly/contract-spaces"
@@ -702,7 +701,8 @@ function buildSkippedSchemaResult(space) {
702
701
  /**
703
702
  * Translate per-space marker check failures and orphan markers into a
704
703
  * single CLI structured error envelope. Preserves the legacy code
705
- * `5002` (was emitted by `runContractSpaceVerifierMarkerCheck`).
704
+ * `MIGRATION.CONTRACT_SPACE_VIOLATION` (was emitted by
705
+ * `runContractSpaceVerifierMarkerCheck`).
706
706
  */
707
707
  function mapMarkerCheckFailures(appSpaceId, section) {
708
708
  const violations = [];
@@ -729,8 +729,7 @@ function mapMarkerCheckFailures(appSpaceId, section) {
729
729
  });
730
730
  if (violations.length === 0) return null;
731
731
  const lines = violations.map((v) => `- [${v.kind}] ${v.spaceId}: ${v.remediation}`);
732
- return new CliStructuredError("5002", violations.length === 1 ? "Contract-space verifier found a violation" : `Contract-space verifier found violations (${violations.length})`, {
733
- domain: "MIG",
732
+ return new CliStructuredError("MIGRATION.CONTRACT_SPACE_VIOLATION", violations.length === 1 ? "Contract-space verifier found a violation" : `Contract-space verifier found violations (${violations.length})`, {
734
733
  why: `The on-disk \`migrations/\` directory, the \`extensionPacks\` declaration, and the live database marker rows are not in agreement.\n${lines.join("\n")}`,
735
734
  fix: violations[0]?.remediation ?? "Review and reconcile the violations listed above.",
736
735
  docsUrl: "https://pris.ly/contract-spaces",
@@ -751,13 +750,17 @@ function mapMarkerCheckFailures(appSpaceId, section) {
751
750
  * 2. Read live marker rows per space (`familyInstance.readAllMarkers`).
752
751
  * 3. Per space: `resolveRecordedPath` plots the path from the live
753
752
  * marker to `space.headRef.hash` (or `refHash` for the app
754
- * space when provided). Empty-graph spaces fail loudly a
755
- * "never planned" space is a user-error condition for replay.
753
+ * space when provided). An empty-graph space whose elements are ALL
754
+ * externally managed resolves declaratively (marker to head, zero
755
+ * ops), mirroring the db-init aggregate planner: such a space ships
756
+ * no DDL and has nothing to author. Every other empty-graph space
757
+ * fails loudly — "never planned" is a user-error condition for
758
+ * replay.
756
759
  * 4. Hand off to {@link runMigration} (the runner-driving tail
757
760
  * shared with `db init` / `db update`). Marker advancement is
758
761
  * inside the per-space transaction.
759
762
  *
760
- * Encodes the replay-only contract: every contract space must have an
763
+ * Encodes the replay-only contract: the app contract space must have an
761
764
  * authored migration graph on disk before this operation can advance it.
762
765
  */
763
766
  async function executeMigrate(options) {
@@ -813,7 +816,10 @@ async function executeMigrate(options) {
813
816
  }
814
817
  const canonicalOrder = [...aggregate.extensions.map((m) => m.spaceId), aggregate.app.spaceId];
815
818
  const applyOrder = canonicalOrder.filter((spaceId) => perSpacePlans.has(spaceId));
816
- if (sumPlannedOps(applyOrder, perSpacePlans) === 0) {
819
+ if (!applyOrder.some((spaceId) => {
820
+ const entry = perSpacePlans.get(spaceId);
821
+ return entry !== void 0 && planRequiresExecution(entry);
822
+ })) {
817
823
  const ordered = canonicalOrder.filter((spaceId) => perSpacePlans.has(spaceId) || atHeadResolutions.has(spaceId)).map((spaceId) => {
818
824
  const entry = perSpacePlans.get(spaceId) ?? atHeadResolutions.get(spaceId);
819
825
  if (entry === void 0) throw new Error(`Unreachable: missing per-space plan for "${spaceId}"`);
@@ -906,6 +912,27 @@ function planSpacePath({ space, aggregate, targetHash, refInvariants, liveMarker
906
912
  liveMarker
907
913
  })
908
914
  };
915
+ if (!isAppSpace && allStorageElementsExternal(space.contract())) {
916
+ if (headRef.invariants.length > 0) return {
917
+ kind: "unsatisfiable",
918
+ spaceId: space.spaceId,
919
+ isAppSpace,
920
+ missing: [...headRef.invariants].sort(),
921
+ targetInvariants: headRef.invariants,
922
+ targetSpace: space,
923
+ liveHash: liveHash ?? EMPTY_CONTRACT_HASH,
924
+ refName: void 0
925
+ };
926
+ return {
927
+ kind: "ok",
928
+ plan: buildAtHeadResolution({
929
+ aggregateTargetId: aggregate.targetId,
930
+ space,
931
+ targetHash,
932
+ liveMarker
933
+ })
934
+ };
935
+ }
909
936
  return {
910
937
  kind: "never-planned",
911
938
  spaceId: space.spaceId,
@@ -951,11 +978,13 @@ function planSpacePath({ space, aggregate, targetHash, refInvariants, liveMarker
951
978
  };
952
979
  }
953
980
  /**
954
- * Build a zero-op {@link PerSpacePlan} for an empty-graph
955
- * space whose live marker already matches the target. Lets the apply
956
- * pipeline thread the space through `perSpacePlans` -> `applyOrder`
957
- * -> the success envelope's `perSpace[]` block so the result reflects
958
- * every loaded space, even when there is nothing to execute.
981
+ * Build a zero-op {@link PerSpacePlan} for an empty-graph space —
982
+ * either one whose live marker already matches the target (at-head), or
983
+ * an all-external extension space whose marker must advance to the head
984
+ * ref with no DDL (declared-state). Lets the apply pipeline thread the
985
+ * space through `perSpacePlans` -> `applyOrder` -> the success
986
+ * envelope's `perSpace[]` block so the result reflects every loaded
987
+ * space, even when there is nothing to execute.
959
988
  */
960
989
  function buildAtHeadResolution(args) {
961
990
  const { aggregateTargetId, space, targetHash, liveMarker } = args;
@@ -978,14 +1007,14 @@ function buildAtHeadResolution(args) {
978
1007
  })]
979
1008
  };
980
1009
  }
981
- function sumPlannedOps(applyOrder, perSpacePlans) {
982
- let total = 0;
983
- for (const spaceId of applyOrder) {
984
- const entry = perSpacePlans.get(spaceId);
985
- if (!entry) continue;
986
- total += entry.plan.operations.length;
987
- }
988
- return total;
1010
+ /**
1011
+ * A plan needs the runner when it executes operations or advances the
1012
+ * space's marker (a declared-state resolution has zero operations but a
1013
+ * destination hash the live marker doesn't carry yet).
1014
+ */
1015
+ function planRequiresExecution(entry) {
1016
+ if (entry.plan.operations.length > 0) return true;
1017
+ return entry.plan.origin?.storageHash !== entry.plan.destination.storageHash;
989
1018
  }
990
1019
  function buildSuccess(args) {
991
1020
  const appResolution = args.orderedResolutions.find((r) => r.spaceId === args.aggregate.app.spaceId);
@@ -1027,10 +1056,12 @@ function buildSuccess(args) {
1027
1056
  };
1028
1057
  }
1029
1058
  /**
1030
- * Build the `neverPlanned` failure raised when a contract space has no on-disk
1031
- * migration graph but migrate was asked to reach a target hash. The `why`
1032
- * states only the condition; the recovery sequence is composed by
1033
- * `errorPathUnreachable`'s `fix`.
1059
+ * Build the `neverPlanned` failure raised when a contract space that
1060
+ * declares managed storage elements has no on-disk migration graph but
1061
+ * migrate was asked to reach a target hash. All-external spaces never reach
1062
+ * this: they resolve declaratively (marker advances to the head ref with
1063
+ * zero operations). The `why` states only the condition; the recovery
1064
+ * sequence is composed by `errorPathUnreachable`'s `fix`.
1034
1065
  *
1035
1066
  * @internal Exported for testing only.
1036
1067
  */
@@ -1038,7 +1069,7 @@ function buildNeverPlannedFailure(spaceId, targetHash) {
1038
1069
  return {
1039
1070
  code: "MIGRATION_PATH_NOT_FOUND",
1040
1071
  summary: `No on-disk migrations for contract space "${spaceId}"`,
1041
- why: `migrate is replay-only: every contract space must have an authored migration graph on disk. Space "${spaceId}" has no migrations under \`migrations/${spaceId}/\` but its head ref targets "${targetHash}".`,
1072
+ why: `migrate is replay-only: a contract space that declares managed storage elements must have an authored migration graph on disk. Space "${spaceId}" has no migrations under \`migrations/${spaceId}/\` but its head ref targets "${targetHash}".`,
1042
1073
  meta: {
1043
1074
  spaceId,
1044
1075
  target: targetHash,
@@ -1594,4 +1625,4 @@ var ControlClientImpl = class {
1594
1625
  //#endregion
1595
1626
  export { executeDbInit as a, executeDbUpdate as i, planSpacePath as n, ContractValidationError as o, executeDbVerify as r, createControlClient as t };
1596
1627
 
1597
- //# sourceMappingURL=client-DigVI8zX.mjs.map
1628
+ //# sourceMappingURL=client-2kwLMBSf.mjs.map