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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/README.md +44 -45
  2. package/dist/cli.mjs +13 -13
  3. package/dist/{client-KuBQftxz.mjs → client-CMusjGV5.mjs} +24 -25
  4. package/dist/client-CMusjGV5.mjs.map +1 -0
  5. package/dist/{command-helpers-Cpq44aVa.mjs → command-helpers-CVn3U9Uz.mjs} +12 -4
  6. package/dist/command-helpers-CVn3U9Uz.mjs.map +1 -0
  7. package/dist/commands/contract-emit.mjs +1 -1
  8. package/dist/commands/contract-infer.mjs +1 -1
  9. package/dist/commands/db-init.d.mts.map +1 -1
  10. package/dist/commands/db-init.mjs +5 -4
  11. package/dist/commands/db-init.mjs.map +1 -1
  12. package/dist/commands/db-schema.mjs +3 -3
  13. package/dist/commands/db-sign.d.mts.map +1 -1
  14. package/dist/commands/db-sign.mjs +9 -11
  15. package/dist/commands/db-sign.mjs.map +1 -1
  16. package/dist/commands/db-update.d.mts.map +1 -1
  17. package/dist/commands/db-update.mjs +11 -13
  18. package/dist/commands/db-update.mjs.map +1 -1
  19. package/dist/commands/db-verify.mjs +1 -1
  20. package/dist/commands/migrate.d.mts +1 -1
  21. package/dist/commands/migrate.d.mts.map +1 -1
  22. package/dist/commands/migrate.mjs +13 -13
  23. package/dist/commands/migrate.mjs.map +1 -1
  24. package/dist/commands/migration-check.d.mts +4 -2
  25. package/dist/commands/migration-check.d.mts.map +1 -1
  26. package/dist/commands/migration-check.mjs +1 -1
  27. package/dist/commands/migration-graph.d.mts +1 -1
  28. package/dist/commands/migration-graph.mjs +4 -4
  29. package/dist/commands/migration-list.d.mts +1 -1
  30. package/dist/commands/migration-list.d.mts.map +1 -1
  31. package/dist/commands/migration-list.mjs +1 -1
  32. package/dist/commands/migration-log.d.mts +1 -1
  33. package/dist/commands/migration-log.mjs +1 -1
  34. package/dist/commands/migration-new.d.mts.map +1 -1
  35. package/dist/commands/migration-new.mjs +16 -40
  36. package/dist/commands/migration-new.mjs.map +1 -1
  37. package/dist/commands/migration-plan.d.mts +3 -4
  38. package/dist/commands/migration-plan.d.mts.map +1 -1
  39. package/dist/commands/migration-plan.mjs +1 -1
  40. package/dist/commands/migration-show.mjs +5 -5
  41. package/dist/commands/migration-show.mjs.map +1 -1
  42. package/dist/commands/migration-status.d.mts +1 -1
  43. package/dist/commands/migration-status.d.mts.map +1 -1
  44. package/dist/commands/migration-status.mjs +1 -1
  45. package/dist/commands/ref.d.mts +1 -1
  46. package/dist/commands/ref.d.mts.map +1 -1
  47. package/dist/commands/ref.mjs +13 -18
  48. package/dist/commands/ref.mjs.map +1 -1
  49. package/dist/commands/telemetry/index.mjs +1 -1
  50. package/dist/contract-at-errors-C-l4-JEY.mjs +36 -0
  51. package/dist/contract-at-errors-C-l4-JEY.mjs.map +1 -0
  52. package/dist/{contract-emit-cJQBlvGb.mjs → contract-emit-CfIbTnsR.mjs} +6 -7
  53. package/dist/{contract-emit-cJQBlvGb.mjs.map → contract-emit-CfIbTnsR.mjs.map} +1 -1
  54. package/dist/{contract-emit-CgnXSANN.mjs → contract-emit-PaY3qRdN.mjs} +3 -3
  55. package/dist/{contract-emit-CgnXSANN.mjs.map → contract-emit-PaY3qRdN.mjs.map} +1 -1
  56. package/dist/{contract-enrichment-gn9sWbPw.mjs → contract-enrichment-JUhLv-BX.mjs} +8 -8
  57. package/dist/{contract-enrichment-gn9sWbPw.mjs.map → contract-enrichment-JUhLv-BX.mjs.map} +1 -1
  58. package/dist/{contract-infer-Cg8evbeg.mjs → contract-infer-DCju2fTk.mjs} +3 -3
  59. package/dist/{contract-infer-Cg8evbeg.mjs.map → contract-infer-DCju2fTk.mjs.map} +1 -1
  60. package/dist/{contract-space-aggregate-loader-D_3VeHVb.mjs → contract-space-aggregate-loader-B6E9LGa6.mjs} +14 -14
  61. package/dist/contract-space-aggregate-loader-B6E9LGa6.mjs.map +1 -0
  62. package/dist/{db-verify-BEclUzki.mjs → db-verify-B_dKu6Yp.mjs} +5 -5
  63. package/dist/db-verify-B_dKu6Yp.mjs.map +1 -0
  64. package/dist/exports/control-api.d.mts +4 -4
  65. package/dist/exports/control-api.d.mts.map +1 -1
  66. package/dist/exports/control-api.mjs +3 -3
  67. package/dist/exports/index.mjs +2 -2
  68. package/dist/exports/init-output.d.mts.map +1 -1
  69. package/dist/exports/init-output.mjs +1 -1
  70. package/dist/{format-DAUAZqPt.mjs → format-cCyDfmRE.mjs} +8 -7
  71. package/dist/format-cCyDfmRE.mjs.map +1 -0
  72. package/dist/{framework-components-CnbUbiJw.mjs → framework-components-DUN-TYDg.mjs} +3 -3
  73. package/dist/framework-components-DUN-TYDg.mjs.map +1 -0
  74. package/dist/{init-C3JhkHg-.mjs → init-C9U3ffHH.mjs} +55 -47
  75. package/dist/init-C9U3ffHH.mjs.map +1 -0
  76. package/dist/{inspect-live-schema-CX7EA5C3.mjs → inspect-live-schema-DHXE7skX.mjs} +4 -4
  77. package/dist/{inspect-live-schema-CX7EA5C3.mjs.map → inspect-live-schema-DHXE7skX.mjs.map} +1 -1
  78. package/dist/{migration-check-MHT3w7_v.mjs → migration-check-W5XEx4d-.mjs} +58 -30
  79. package/dist/migration-check-W5XEx4d-.mjs.map +1 -0
  80. package/dist/{migration-command-scaffold-CRyYrHZ9.mjs → migration-command-scaffold-hI5cnoGe.mjs} +4 -4
  81. package/dist/{migration-command-scaffold-CRyYrHZ9.mjs.map → migration-command-scaffold-hI5cnoGe.mjs.map} +1 -1
  82. package/dist/{migration-graph-command-render-B83xrnNy.mjs → migration-graph-command-render-DgQg5App.mjs} +3 -3
  83. package/dist/migration-graph-command-render-DgQg5App.mjs.map +1 -0
  84. package/dist/{migration-list-BAKujUjh.mjs → migration-list-ClkEaoL8.mjs} +6 -6
  85. package/dist/migration-list-ClkEaoL8.mjs.map +1 -0
  86. package/dist/{migration-log-C_xam2HZ.mjs → migration-log-CjafbZ2Z.mjs} +5 -5
  87. package/dist/{migration-log-C_xam2HZ.mjs.map → migration-log-CjafbZ2Z.mjs.map} +1 -1
  88. package/dist/{migration-path-target-DpPTsRCg.mjs → migration-path-target-C0TQuV5n.mjs} +2 -2
  89. package/dist/{migration-path-target-DpPTsRCg.mjs.map → migration-path-target-C0TQuV5n.mjs.map} +1 -1
  90. package/dist/{migration-plan-CreSVtWZ.mjs → migration-plan-Pc4hCF1H.mjs} +64 -74
  91. package/dist/migration-plan-Pc4hCF1H.mjs.map +1 -0
  92. package/dist/{migration-status-YgEvXf-u.mjs → migration-status-CqAdRzs8.mjs} +13 -12
  93. package/dist/migration-status-CqAdRzs8.mjs.map +1 -0
  94. package/dist/{output-mEQ74_nd.mjs → output-DWNYqZGc.mjs} +5 -6
  95. package/dist/output-DWNYqZGc.mjs.map +1 -0
  96. package/dist/{ref-advancement-BkXlikCA.mjs → ref-advancement-BCz7X7qJ.mjs} +13 -6
  97. package/dist/ref-advancement-BCz7X7qJ.mjs.map +1 -0
  98. package/dist/{telemetry-DVr6RFnq.mjs → telemetry-BEyNMfco.mjs} +2 -2
  99. package/dist/{telemetry-DVr6RFnq.mjs.map → telemetry-BEyNMfco.mjs.map} +1 -1
  100. package/dist/{types-D4r_HI9-.d.mts → types-DgXprE3w.d.mts} +3 -3
  101. package/dist/types-DgXprE3w.d.mts.map +1 -0
  102. package/dist/{verify-CgDVZjhc.mjs → verify-C4RazDE1.mjs} +2 -2
  103. package/dist/{verify-CgDVZjhc.mjs.map → verify-C4RazDE1.mjs.map} +1 -1
  104. package/package.json +21 -21
  105. package/src/commands/db-init.ts +1 -0
  106. package/src/commands/db-sign.ts +7 -5
  107. package/src/commands/db-update.ts +14 -6
  108. package/src/commands/db-verify.ts +1 -1
  109. package/src/commands/format.ts +1 -1
  110. package/src/commands/init/hygiene-gitattributes.ts +37 -21
  111. package/src/commands/init/init.ts +6 -6
  112. package/src/commands/init/output.ts +4 -5
  113. package/src/commands/init/reinit-cleanup.ts +16 -17
  114. package/src/commands/inspect-live-schema.ts +1 -1
  115. package/src/commands/migrate.ts +6 -5
  116. package/src/commands/migration-check.ts +72 -34
  117. package/src/commands/migration-list.ts +1 -5
  118. package/src/commands/migration-log.ts +1 -1
  119. package/src/commands/migration-new.ts +17 -41
  120. package/src/commands/migration-plan.ts +64 -88
  121. package/src/commands/migration-show.ts +2 -2
  122. package/src/commands/migration-status.ts +6 -7
  123. package/src/commands/ref.ts +19 -14
  124. package/src/control-api/client.ts +7 -8
  125. package/src/control-api/contract-enrichment.ts +7 -7
  126. package/src/control-api/operations/contract-emit.ts +2 -3
  127. package/src/control-api/operations/db-init.ts +3 -3
  128. package/src/control-api/operations/db-run.ts +6 -6
  129. package/src/control-api/operations/db-update.ts +2 -2
  130. package/src/control-api/operations/db-verify.ts +4 -4
  131. package/src/control-api/operations/format.ts +5 -4
  132. package/src/control-api/operations/migrate.ts +3 -3
  133. package/src/control-api/types.ts +1 -1
  134. package/src/utils/cli-errors.ts +15 -7
  135. package/src/utils/contract-at-errors.ts +13 -22
  136. package/src/utils/contract-space-aggregate-loader.ts +8 -8
  137. package/src/utils/contract-space-seed-phase.ts +11 -9
  138. package/src/utils/extension-pack-inputs.ts +8 -8
  139. package/src/utils/formatters/migration-graph-labels.ts +1 -2
  140. package/src/utils/formatters/migration-list-data-column.ts +1 -2
  141. package/src/utils/framework-components.ts +9 -9
  142. package/src/utils/integrity-violation-to-check-failure.ts +3 -3
  143. package/src/utils/migration-command-scaffold.ts +1 -1
  144. package/src/utils/plan-resolution.ts +7 -10
  145. package/src/utils/ref-advancement.ts +22 -3
  146. package/dist/client-KuBQftxz.mjs.map +0 -1
  147. package/dist/command-helpers-Cpq44aVa.mjs.map +0 -1
  148. package/dist/contract-at-errors-D9gEjYtg.mjs +0 -42
  149. package/dist/contract-at-errors-D9gEjYtg.mjs.map +0 -1
  150. package/dist/contract-space-aggregate-loader-D_3VeHVb.mjs.map +0 -1
  151. package/dist/db-verify-BEclUzki.mjs.map +0 -1
  152. package/dist/format-DAUAZqPt.mjs.map +0 -1
  153. package/dist/framework-components-CnbUbiJw.mjs.map +0 -1
  154. package/dist/init-C3JhkHg-.mjs.map +0 -1
  155. package/dist/migration-check-MHT3w7_v.mjs.map +0 -1
  156. package/dist/migration-graph-command-render-B83xrnNy.mjs.map +0 -1
  157. package/dist/migration-list-BAKujUjh.mjs.map +0 -1
  158. package/dist/migration-plan-CreSVtWZ.mjs.map +0 -1
  159. package/dist/migration-status-YgEvXf-u.mjs.map +0 -1
  160. package/dist/output-mEQ74_nd.mjs.map +0 -1
  161. package/dist/ref-advancement-BkXlikCA.mjs.map +0 -1
  162. package/dist/types-D4r_HI9-.d.mts.map +0 -1
package/README.md CHANGED
@@ -52,7 +52,7 @@ Commands that enforce wiring validation:
52
52
  - **`db init`**
53
53
  - **`db update`**
54
54
 
55
- If you hit a wiring validation error: add the required descriptors to `config.extensionPacks` (matched by descriptor `id`) and re-run the command.
55
+ If you hit a wiring validation error: add the required descriptors to `config.extensions` (matched by descriptor `id`) and re-run the command.
56
56
 
57
57
  **Note**: Control plane domain actions (database verification, contract emission) are implemented in `@prisma-next/emitter` and `@prisma-next/framework-components/control`. The CLI uses the control plane domain actions programmatically but does not define control plane types itself.
58
58
 
@@ -92,7 +92,7 @@ export default defineConfig({
92
92
  family: sql,
93
93
  target: postgres,
94
94
  adapter: postgresAdapter,
95
- extensionPacks: [],
95
+ extensions: [],
96
96
  contract: typescriptContract(contract, 'src/prisma/contract.json'),
97
97
  });
98
98
  ```
@@ -181,7 +181,7 @@ export default defineConfig({
181
181
  target: postgres,
182
182
  adapter: postgresAdapter,
183
183
  driver: postgresDriver,
184
- extensionPacks: [],
184
+ extensions: [],
185
185
  contract: typescriptContract(contract, 'src/prisma/contract.json'),
186
186
  db: {
187
187
  connection: process.env.DATABASE_URL, // Optional: can also use --db flag
@@ -210,16 +210,16 @@ Success:
210
210
  ```text
211
211
  ✔ Database marker and schema match contract
212
212
  verification: marker + schema
213
- storageHash: sha256:abc123...
214
- profileHash: sha256:def456...
213
+ storageHash: abc123...
214
+ profileHash: def456...
215
215
  ```
216
216
 
217
217
  Marker-only success:
218
218
  ```text
219
219
  ✔ Database marker matches contract
220
220
  verification: marker only (--marker-only)
221
- storageHash: sha256:abc123...
222
- profileHash: sha256:def456...
221
+ storageHash: abc123...
222
+ profileHash: def456...
223
223
 
224
224
  ⚠ Schema verification skipped because --marker-only was provided
225
225
  ```
@@ -242,12 +242,12 @@ Schema drift failure:
242
242
  "summary": "Database marker and schema match contract",
243
243
  "mode": "full",
244
244
  "contract": {
245
- "storageHash": "sha256:abc123...",
246
- "profileHash": "sha256:def456..."
245
+ "storageHash": "abc123...",
246
+ "profileHash": "def456..."
247
247
  },
248
248
  "marker": {
249
- "storageHash": "sha256:abc123...",
250
- "profileHash": "sha256:def456..."
249
+ "storageHash": "abc123...",
250
+ "profileHash": "def456..."
251
251
  },
252
252
  "target": {
253
253
  "expected": "postgres"
@@ -297,7 +297,7 @@ interface ControlStack<TFamilyId, TTargetId> {
297
297
  readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
298
298
  readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
299
299
  readonly driver: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;
300
- readonly extensionPacks: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
300
+ readonly extensions: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
301
301
  }
302
302
 
303
303
  interface ControlFamilyInstance {
@@ -311,7 +311,7 @@ interface ControlFamilyInstance {
311
311
  }
312
312
  ```
313
313
 
314
- Use `createControlStack()` from `@prisma-next/framework-components/control` to create the stack with sensible defaults (`driver` defaults to `undefined`, `extensionPacks` defaults to `[]`).
314
+ Use `createControlStack()` from `@prisma-next/framework-components/control` to create the stack with sensible defaults (`driver` defaults to `undefined`, `extensions` defaults to `[]`).
315
315
 
316
316
  The SQL family provides this via `@prisma-next/family-sql/control`. The `verify()` method handles marker checks, full `db verify` follows it with `schemaVerify()`, `--marker-only` skips that schema step, and `--schema-only` runs `schemaVerify()` without marker checks.
317
317
 
@@ -404,7 +404,7 @@ export default defineConfig({
404
404
  target: postgres,
405
405
  adapter: postgresAdapter,
406
406
  driver: postgresDriver,
407
- extensionPacks: [],
407
+ extensions: [],
408
408
  db: {
409
409
  connection: process.env.DATABASE_URL, // Optional: can also use --db flag
410
410
  },
@@ -555,7 +555,7 @@ export default defineConfig({
555
555
  target: postgres,
556
556
  adapter: postgresAdapter,
557
557
  driver: postgresDriver,
558
- extensionPacks: [],
558
+ extensions: [],
559
559
  contract: typescriptContract(contract, 'src/prisma/contract.json'),
560
560
  db: {
561
561
  connection: process.env.DATABASE_URL, // Optional: can also use --db flag
@@ -584,25 +584,25 @@ export default defineConfig({
584
584
  Success (new marker):
585
585
  ```
586
586
  ✔ Database signed (marker created)
587
- storageHash: sha256:abc123...
588
- profileHash: sha256:def456...
587
+ storageHash: abc123...
588
+ profileHash: def456...
589
589
  Total time: 42ms
590
590
  ```
591
591
 
592
592
  Success (updated marker):
593
593
  ```
594
- ✔ Database signed (marker updated from sha256:old-hash)
595
- storageHash: sha256:abc123...
596
- profileHash: sha256:def456...
597
- previous storageHash: sha256:old-hash
594
+ ✔ Database signed (marker updated from old-hash)
595
+ storageHash: abc123...
596
+ profileHash: def456...
597
+ previous storageHash: old-hash
598
598
  Total time: 42ms
599
599
  ```
600
600
 
601
601
  Success (already up-to-date):
602
602
  ```
603
603
  ✔ Database already signed with this contract
604
- storageHash: sha256:abc123...
605
- profileHash: sha256:def456...
604
+ storageHash: abc123...
605
+ profileHash: def456...
606
606
  Total time: 42ms
607
607
  ```
608
608
 
@@ -619,8 +619,8 @@ Failure (schema mismatch):
619
619
  "ok": true,
620
620
  "summary": "Database signed (marker created)",
621
621
  "contract": {
622
- "storageHash": "sha256:abc123...",
623
- "profileHash": "sha256:def456..."
622
+ "storageHash": "abc123...",
623
+ "profileHash": "def456..."
624
624
  },
625
625
  "target": {
626
626
  "expected": "postgres",
@@ -644,10 +644,10 @@ For updated markers:
644
644
  ```json
645
645
  {
646
646
  "ok": true,
647
- "summary": "Database signed (marker updated from sha256:old-hash)",
647
+ "summary": "Database signed (marker updated from old-hash)",
648
648
  "contract": {
649
- "storageHash": "sha256:abc123...",
650
- "profileHash": "sha256:def456..."
649
+ "storageHash": "abc123...",
650
+ "profileHash": "def456..."
651
651
  },
652
652
  "target": {
653
653
  "expected": "postgres",
@@ -657,8 +657,8 @@ For updated markers:
657
657
  "created": false,
658
658
  "updated": true,
659
659
  "previous": {
660
- "storageHash": "sha256:old-hash",
661
- "profileHash": "sha256:old-profile-hash"
660
+ "storageHash": "old-hash",
661
+ "profileHash": "old-profile-hash"
662
662
  }
663
663
  },
664
664
  "meta": {
@@ -761,7 +761,7 @@ export default defineConfig({
761
761
  target: postgres,
762
762
  adapter: postgresAdapter,
763
763
  driver: postgresDriver,
764
- extensionPacks: [],
764
+ extensions: [],
765
765
  contract: typescriptContract(contract, 'src/prisma/contract.json'),
766
766
  db: {
767
767
  connection: process.env.DATABASE_URL, // Optional: can also use --db flag
@@ -778,7 +778,7 @@ export default defineConfig({
778
778
  5. **Validate wiring**: Ensures the contract is compatible with the CLI config:
779
779
  - `contract.targetFamily` matches `config.family.familyId`
780
780
  - `contract.target` matches `config.target.targetId`
781
- - `contract.extensionPacks` (if present) are provided by `config.extensionPacks` (matched by descriptor `id`)
781
+ - `contract.extensions` (if present) are provided by `config.extensions` (matched by descriptor `id`)
782
782
  6. **Create Planner/Runner**: Uses `config.target.migrations.createPlanner()` and `config.target.migrations.createRunner()`
783
783
  7. **Plan Migration**: Calls `planner.plan()` with the contract, schema IR, additive-only policy, and `frameworkComponents` (the active target/adapter/extension descriptors)
784
784
  - On conflict: Returns a structured failure with conflict list
@@ -803,7 +803,7 @@ prisma-next db init ➜ Bootstrap a database to match the current contract
803
803
  ├─ Create index user_email_idx on user [additive]
804
804
  └─ Add foreign key post_userId_fkey on post [additive]
805
805
 
806
- Destination hash: sha256:abc123...
806
+ Destination hash: abc123...
807
807
 
808
808
  This is a dry run. No changes were applied.
809
809
  Run without --dry-run to apply changes.
@@ -822,7 +822,7 @@ Applying migration plan and verifying schema...
822
822
  → Create index user_email_idx on user...
823
823
  → Add foreign key post_userId_fkey on post...
824
824
  ✔ Applied 4 operation(s)
825
- Marker written: sha256:abc123...
825
+ Marker written: abc123...
826
826
  ```
827
827
 
828
828
  **Output Format (JSON):**
@@ -834,7 +834,7 @@ Applying migration plan and verifying schema...
834
834
  "plan": {
835
835
  "targetId": "postgres",
836
836
  "destination": {
837
- "storageHash": "sha256:abc123..."
837
+ "storageHash": "abc123..."
838
838
  },
839
839
  "operations": [
840
840
  {
@@ -849,7 +849,7 @@ Applying migration plan and verifying schema...
849
849
  "operationsExecuted": 4
850
850
  },
851
851
  "marker": {
852
- "storageHash": "sha256:abc123..."
852
+ "storageHash": "abc123..."
853
853
  }
854
854
  }
855
855
  ```
@@ -891,7 +891,7 @@ prisma-next db update [--db <url>] [--config <path>] [--dry-run] [-y|--yes] [--i
891
891
 
892
892
  **Config File (`prisma-next.config.ts`):**
893
893
 
894
- The CLI uses a config file to specify the target family, target, adapter, extensionPacks, and contract.
894
+ The CLI uses a config file to specify the target family, target, adapter, extensions, and contract.
895
895
 
896
896
  **Config Discovery:**
897
897
  - `--config <path>`: Explicit path (relative or absolute)
@@ -912,7 +912,7 @@ export default defineConfig({
912
912
  family: sql,
913
913
  target: postgres,
914
914
  adapter: postgresAdapter,
915
- extensionPacks: [],
915
+ extensions: [],
916
916
  contract: typescriptContract(contract, 'src/prisma/contract.json'),
917
917
  });
918
918
  ```
@@ -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
@@ -1085,7 +1084,7 @@ prisma-next ref delete <name> # Delete a ref
1085
1084
 
1086
1085
  **Ref naming rules:** Lowercase alphanumeric with hyphens or forward slashes (e.g., `staging`, `prod/us-east`). No `.` or `..` segments.
1087
1086
 
1088
- **Ref values:** Must be valid contract hashes (`sha256:<64 hex chars>` or `sha256:empty`).
1087
+ **Ref values:** Must be valid contract hashes (64 lowercase hex chars, or the `empty` sentinel).
1089
1088
 
1090
1089
  **Atomic writes:** `refs.json` is written atomically via temp file + rename to prevent corruption from concurrent writes.
1091
1090
 
@@ -1295,7 +1294,7 @@ import exampleExtension from '@prisma-next/extension-example/control';
1295
1294
 
1296
1295
  export default defineConfig({
1297
1296
  // family/target/adapter/driver omitted for brevity
1298
- extensionPacks: [exampleExtension],
1297
+ extensions: [exampleExtension],
1299
1298
  });
1300
1299
  ```
1301
1300
 
@@ -1390,7 +1389,7 @@ const client = createControlClient({
1390
1389
  target: postgres,
1391
1390
  adapter: postgresAdapter,
1392
1391
  driver: postgresDriver,
1393
- extensionPacks: [],
1392
+ extensions: [],
1394
1393
  });
1395
1394
 
1396
1395
  try {
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-Cpq44aVa.mjs";
3
- import { t as createContractEmitCommand } from "./contract-emit-CgnXSANN.mjs";
4
- import { t as createContractInferCommand } from "./contract-infer-Cg8evbeg.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-PaY3qRdN.mjs";
4
+ import { t as createContractInferCommand } from "./contract-infer-DCju2fTk.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-BEclUzki.mjs";
10
- import { t as createFormatCommand } from "./format-DAUAZqPt.mjs";
11
- import { t as createMigrationListCommand } from "./migration-list-BAKujUjh.mjs";
9
+ import { t as createDbVerifyCommand } from "./db-verify-B_dKu6Yp.mjs";
10
+ import { t as createFormatCommand } from "./format-cCyDfmRE.mjs";
11
+ import { t as createMigrationListCommand } from "./migration-list-ClkEaoL8.mjs";
12
12
  import { createMigrateCommand } from "./commands/migrate.mjs";
13
- import { t as createMigrationCheckCommand } from "./migration-check-MHT3w7_v.mjs";
13
+ import { t as createMigrationCheckCommand } from "./migration-check-W5XEx4d-.mjs";
14
14
  import { createMigrationGraphCommand } from "./commands/migration-graph.mjs";
15
- import { t as createMigrationLogCommand } from "./migration-log-C_xam2HZ.mjs";
15
+ import { t as createMigrationLogCommand } from "./migration-log-CjafbZ2Z.mjs";
16
16
  import { createMigrationNewCommand } from "./commands/migration-new.mjs";
17
- import { t as createMigrationPlanCommand } from "./migration-plan-CreSVtWZ.mjs";
17
+ import { t as createMigrationPlanCommand } from "./migration-plan-Pc4hCF1H.mjs";
18
18
  import { createMigrationShowCommand } from "./commands/migration-show.mjs";
19
- import { r as createMigrationStatusCommand } from "./migration-status-YgEvXf-u.mjs";
19
+ import { r as createMigrationStatusCommand } from "./migration-status-CqAdRzs8.mjs";
20
20
  import { createRefCommand } from "./commands/ref.mjs";
21
- import { t as createTelemetryCommand } from "./telemetry-DVr6RFnq.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.16.0-dev.3";
28
+ var version = "0.16.0-dev.30";
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-C3JhkHg-.mjs");
297
+ const { runInit } = await import("./init-C9U3ffHH.mjs");
298
298
  const flags = parseGlobalFlagsOrExit(options);
299
299
  const canPrompt = deriveCanPrompt({
300
300
  flagsInteractive: flags.interactive,
@@ -1,7 +1,7 @@
1
- import { F as CliStructuredError } from "./command-helpers-Cpq44aVa.mjs";
2
- import { t as assertFrameworkComponentsCompatible } from "./framework-components-CnbUbiJw.mjs";
3
- import { t as enrichContract } from "./contract-enrichment-gn9sWbPw.mjs";
4
- import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-D_3VeHVb.mjs";
1
+ import { F as CliStructuredError } from "./command-helpers-CVn3U9Uz.mjs";
2
+ import { t as assertFrameworkComponentsCompatible } from "./framework-components-DUN-TYDg.mjs";
3
+ import { t as enrichContract } from "./contract-enrichment-JUhLv-BX.mjs";
4
+ import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-B6E9LGa6.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";
@@ -206,12 +206,12 @@ const SPAN_IDS$1 = {
206
206
  * every space's writes.
207
207
  */
208
208
  async function executeRun(options) {
209
- const { driver, adapter, familyInstance, contract, mode, migrations, frameworkComponents, migrationsDir, extensionPacks, targetId, policy, action, onProgress } = options;
209
+ const { driver, adapter, familyInstance, contract, mode, migrations, frameworkComponents, migrationsDir, extensions, targetId, policy, action, onProgress } = options;
210
210
  const loaded = await buildContractSpaceAggregate({
211
211
  targetId,
212
212
  migrationsDir,
213
213
  appContract: contract,
214
- extensionPacks,
214
+ extensions,
215
215
  deserializeContract: (json) => familyInstance.deserializeContract(json)
216
216
  });
217
217
  if (!loaded.ok) throw loaded.failure;
@@ -327,7 +327,7 @@ function aggregatePlannerWarnings(orderedResolutions) {
327
327
  * Compare the live `_prisma_marker` rows against the aggregate's
328
328
  * declared contract spaces. Any marker row whose `space` is not a space of
329
329
  * the aggregate is an "orphan" — typically a marker left behind by
330
- * an extension that was removed from `extensionPacks` without first
330
+ * an extension that was removed from `extensions` without first
331
331
  * cleaning up its on-disk migrations / database tables.
332
332
  *
333
333
  * Returns a {@link CliStructuredError} envelope (code
@@ -345,8 +345,8 @@ function detectOrphanMarkers(aggregate, markerRows) {
345
345
  if (orphans.length === 0) return null;
346
346
  orphans.sort((a, b) => a.localeCompare(b));
347
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
- 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
- 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.",
348
+ why: `The database has \`_prisma_marker\` rows for spaces (${orphans.map((s) => `"${s}"`).join(", ")}) that are not declared in the project's \`extensions\`. The aggregate pipeline refuses to advance markers it cannot account for.`,
349
+ fix: "Either re-declare the missing extension(s) in `extensions` (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",
351
351
  meta: { violations: orphans.map((spaceId) => ({
352
352
  kind: "orphanMarker",
@@ -451,7 +451,7 @@ async function executeDbInit(options) {
451
451
  frameworkComponents: options.frameworkComponents,
452
452
  migrationsDir: options.migrationsDir,
453
453
  targetId: options.targetId,
454
- extensionPacks: options.extensionPacks ?? [],
454
+ extensions: options.extensions ?? [],
455
455
  policy: { allowedOperationClasses: ["additive"] },
456
456
  action: "dbInit",
457
457
  ...ifDefined("onProgress", options.onProgress)
@@ -483,7 +483,7 @@ async function executeDbUpdate(options) {
483
483
  frameworkComponents: options.frameworkComponents,
484
484
  migrationsDir: options.migrationsDir,
485
485
  targetId: options.targetId,
486
- extensionPacks: options.extensionPacks ?? [],
486
+ extensions: options.extensions ?? [],
487
487
  policy: DB_UPDATE_POLICY,
488
488
  action: "dbUpdate",
489
489
  ...ifDefined("onProgress", options.onProgress)
@@ -585,7 +585,7 @@ function buildLoadInputs(options) {
585
585
  targetId: options.targetId,
586
586
  migrationsDir: options.migrationsDir,
587
587
  appContract: options.contract,
588
- extensionPacks: options.extensionPacks,
588
+ extensions: options.extensions,
589
589
  deserializeContract: (json) => options.familyInstance.deserializeContract(json)
590
590
  };
591
591
  }
@@ -725,12 +725,12 @@ function mapMarkerCheckFailures(appSpaceId, section) {
725
725
  for (const orphan of section.orphanMarkers) violations.push({
726
726
  kind: "orphanMarker",
727
727
  spaceId: orphan.spaceId,
728
- remediation: `Add the corresponding extension to \`extensionPacks\` in \`prisma-next.config.ts\`, or delete the orphan marker row for "${orphan.spaceId}".`
728
+ remediation: `Add the corresponding extension to \`extensions\` in \`prisma-next.config.ts\`, or delete the orphan marker row for "${orphan.spaceId}".`
729
729
  });
730
730
  if (violations.length === 0) return null;
731
731
  const lines = violations.map((v) => `- [${v.kind}] ${v.spaceId}: ${v.remediation}`);
732
732
  return new CliStructuredError("MIGRATION.CONTRACT_SPACE_VIOLATION", violations.length === 1 ? "Contract-space verifier found a violation" : `Contract-space verifier found violations (${violations.length})`, {
733
- why: `The on-disk \`migrations/\` directory, the \`extensionPacks\` declaration, and the live database marker rows are not in agreement.\n${lines.join("\n")}`,
733
+ why: `The on-disk \`migrations/\` directory, the \`extensions\` declaration, and the live database marker rows are not in agreement.\n${lines.join("\n")}`,
734
734
  fix: violations[0]?.remediation ?? "Review and reconcile the violations listed above.",
735
735
  docsUrl: "https://pris.ly/contract-spaces",
736
736
  meta: { violations }
@@ -764,12 +764,12 @@ function mapMarkerCheckFailures(appSpaceId, section) {
764
764
  * authored migration graph on disk before this operation can advance it.
765
765
  */
766
766
  async function executeMigrate(options) {
767
- const { driver, familyInstance, contract, migrations, frameworkComponents, migrationsDir, extensionPacks, targetId, refHash, refInvariants, refName, onProgress } = options;
767
+ const { driver, familyInstance, contract, migrations, frameworkComponents, migrationsDir, extensions, targetId, refHash, refInvariants, refName, onProgress } = options;
768
768
  const loaded = await buildContractSpaceAggregate({
769
769
  targetId,
770
770
  migrationsDir,
771
771
  appContract: contract,
772
- extensionPacks,
772
+ extensions,
773
773
  deserializeContract: (json) => familyInstance.deserializeContract(json)
774
774
  });
775
775
  if (!loaded.ok) throw loaded.failure;
@@ -1139,13 +1139,13 @@ var ControlClientImpl = class {
1139
1139
  target: this.options.target,
1140
1140
  adapter: this.options.adapter,
1141
1141
  driver: this.options.driver,
1142
- extensionPacks: this.options.extensionPacks
1142
+ extensions: this.options.extensions
1143
1143
  });
1144
1144
  this.familyInstance = this.options.family.create(this.stack);
1145
1145
  const rawComponents = [
1146
1146
  this.options.target,
1147
1147
  this.options.adapter,
1148
- ...this.options.extensionPacks ?? []
1148
+ ...this.options.extensions ?? []
1149
1149
  ];
1150
1150
  this.frameworkComponents = assertFrameworkComponentsCompatible(this.options.family.familyId, this.options.target.targetId, rawComponents);
1151
1151
  this.initialized = true;
@@ -1358,7 +1358,7 @@ var ControlClientImpl = class {
1358
1358
  frameworkComponents,
1359
1359
  migrationsDir: options.migrationsDir,
1360
1360
  targetId: this.options.target.targetId,
1361
- extensionPacks: this.options.extensionPacks ?? [],
1361
+ extensions: this.options.extensions ?? [],
1362
1362
  ...ifDefined("onProgress", onProgress)
1363
1363
  });
1364
1364
  }
@@ -1384,7 +1384,7 @@ var ControlClientImpl = class {
1384
1384
  frameworkComponents,
1385
1385
  migrationsDir: options.migrationsDir,
1386
1386
  targetId: this.options.target.targetId,
1387
- extensionPacks: this.options.extensionPacks ?? [],
1387
+ extensions: this.options.extensions ?? [],
1388
1388
  ...ifDefined("acceptDataLoss", options.acceptDataLoss),
1389
1389
  ...ifDefined("onProgress", onProgress)
1390
1390
  });
@@ -1399,7 +1399,7 @@ var ControlClientImpl = class {
1399
1399
  contract: options.contract,
1400
1400
  migrationsDir: options.migrationsDir,
1401
1401
  targetId: this.options.target.targetId,
1402
- extensionPacks: this.options.extensionPacks ?? [],
1402
+ extensions: this.options.extensions ?? [],
1403
1403
  frameworkComponents,
1404
1404
  mode: options.strict ? "strict" : "lenient",
1405
1405
  skipSchema: options.skipSchema,
@@ -1444,7 +1444,7 @@ var ControlClientImpl = class {
1444
1444
  migrations: this.options.target.migrations,
1445
1445
  frameworkComponents,
1446
1446
  migrationsDir: options.migrationsDir,
1447
- extensionPacks: this.options.extensionPacks ?? [],
1447
+ extensions: this.options.extensions ?? [],
1448
1448
  targetId: this.options.target.targetId,
1449
1449
  ...ifDefined("refHash", options.refHash),
1450
1450
  ...ifDefined("refInvariants", options.refInvariants),
@@ -1512,9 +1512,8 @@ var ControlClientImpl = class {
1512
1512
  try {
1513
1513
  const stack = this.stack;
1514
1514
  const sourceContext = {
1515
- composedExtensionPacks: stack.extensionPacks.map((p) => p.id),
1515
+ composedExtensions: stack.extensions.map((p) => p.id),
1516
1516
  composedExtensionContracts: stack.extensionContracts,
1517
- scalarTypeDescriptors: stack.scalarTypeDescriptors,
1518
1517
  authoringContributions: stack.authoringContributions,
1519
1518
  codecLookup: stack.codecLookup,
1520
1519
  controlMutationDefaults: stack.controlMutationDefaults,
@@ -1625,4 +1624,4 @@ var ControlClientImpl = class {
1625
1624
  //#endregion
1626
1625
  export { executeDbInit as a, executeDbUpdate as i, planSpacePath as n, ContractValidationError as o, executeDbVerify as r, createControlClient as t };
1627
1626
 
1628
- //# sourceMappingURL=client-KuBQftxz.mjs.map
1627
+ //# sourceMappingURL=client-CMusjGV5.mjs.map