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

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 (173) hide show
  1. package/README.md +44 -45
  2. package/dist/cli.mjs +13 -13
  3. package/dist/{client-KuBQftxz.mjs → client-B1UjQc_x.mjs} +50 -58
  4. package/dist/client-B1UjQc_x.mjs.map +1 -0
  5. package/dist/{command-helpers-Cpq44aVa.mjs → command-helpers-D-jBl0Qt.mjs} +16 -8
  6. package/dist/command-helpers-D-jBl0Qt.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 +8 -6
  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 +11 -12
  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 +14 -15
  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-DvZ_DzJK.mjs +36 -0
  51. package/dist/contract-at-errors-DvZ_DzJK.mjs.map +1 -0
  52. package/dist/{contract-emit-CgnXSANN.mjs → contract-emit-BT46Mu8Q.mjs} +3 -3
  53. package/dist/{contract-emit-CgnXSANN.mjs.map → contract-emit-BT46Mu8Q.mjs.map} +1 -1
  54. package/dist/{contract-emit-cJQBlvGb.mjs → contract-emit-hVdlaF2U.mjs} +6 -7
  55. package/dist/{contract-emit-cJQBlvGb.mjs.map → contract-emit-hVdlaF2U.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-DpqTQECL.mjs} +3 -3
  59. package/dist/{contract-infer-Cg8evbeg.mjs.map → contract-infer-DpqTQECL.mjs.map} +1 -1
  60. package/dist/{contract-space-aggregate-loader-D_3VeHVb.mjs → contract-space-aggregate-loader-CNd-ZB6C.mjs} +14 -14
  61. package/dist/contract-space-aggregate-loader-CNd-ZB6C.mjs.map +1 -0
  62. package/dist/{db-verify-BEclUzki.mjs → db-verify-FEN6k1m7.mjs} +10 -8
  63. package/dist/db-verify-FEN6k1m7.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.d.mts +2 -1
  68. package/dist/exports/index.d.mts.map +1 -1
  69. package/dist/exports/index.mjs +61 -21
  70. package/dist/exports/index.mjs.map +1 -1
  71. package/dist/exports/init-output.d.mts.map +1 -1
  72. package/dist/exports/init-output.mjs +1 -1
  73. package/dist/{format-DAUAZqPt.mjs → format-DI5qVr22.mjs} +8 -7
  74. package/dist/format-DI5qVr22.mjs.map +1 -0
  75. package/dist/{framework-components-CnbUbiJw.mjs → framework-components-C4XACYNB.mjs} +3 -3
  76. package/dist/framework-components-C4XACYNB.mjs.map +1 -0
  77. package/dist/{init-C3JhkHg-.mjs → init-ClrRkbwd.mjs} +77 -67
  78. package/dist/init-ClrRkbwd.mjs.map +1 -0
  79. package/dist/{inspect-live-schema-CX7EA5C3.mjs → inspect-live-schema-C0Rgdtw_.mjs} +4 -4
  80. package/dist/{inspect-live-schema-CX7EA5C3.mjs.map → inspect-live-schema-C0Rgdtw_.mjs.map} +1 -1
  81. package/dist/{migration-check-MHT3w7_v.mjs → migration-check-zEkHpPDT.mjs} +58 -30
  82. package/dist/migration-check-zEkHpPDT.mjs.map +1 -0
  83. package/dist/{migration-command-scaffold-CRyYrHZ9.mjs → migration-command-scaffold-CkNsp9g1.mjs} +4 -4
  84. package/dist/{migration-command-scaffold-CRyYrHZ9.mjs.map → migration-command-scaffold-CkNsp9g1.mjs.map} +1 -1
  85. package/dist/{migration-graph-command-render-B83xrnNy.mjs → migration-graph-command-render-DEwFpx-w.mjs} +5 -4
  86. package/dist/migration-graph-command-render-DEwFpx-w.mjs.map +1 -0
  87. package/dist/{migration-list-BAKujUjh.mjs → migration-list-BkafFVXS.mjs} +6 -6
  88. package/dist/migration-list-BkafFVXS.mjs.map +1 -0
  89. package/dist/{migration-log-C_xam2HZ.mjs → migration-log-BxhAtbhA.mjs} +5 -5
  90. package/dist/{migration-log-C_xam2HZ.mjs.map → migration-log-BxhAtbhA.mjs.map} +1 -1
  91. package/dist/{migration-path-target-DpPTsRCg.mjs → migration-path-target-B5HkjSTO.mjs} +2 -2
  92. package/dist/{migration-path-target-DpPTsRCg.mjs.map → migration-path-target-B5HkjSTO.mjs.map} +1 -1
  93. package/dist/{migration-plan-CreSVtWZ.mjs → migration-plan-Bk2pbPQH.mjs} +64 -74
  94. package/dist/migration-plan-Bk2pbPQH.mjs.map +1 -0
  95. package/dist/{migration-status-YgEvXf-u.mjs → migration-status-BzlARseq.mjs} +13 -12
  96. package/dist/migration-status-BzlARseq.mjs.map +1 -0
  97. package/dist/{output-mEQ74_nd.mjs → output-DWNYqZGc.mjs} +5 -6
  98. package/dist/output-DWNYqZGc.mjs.map +1 -0
  99. package/dist/{ref-advancement-BkXlikCA.mjs → ref-advancement-BCz7X7qJ.mjs} +13 -6
  100. package/dist/ref-advancement-BCz7X7qJ.mjs.map +1 -0
  101. package/dist/{telemetry-DVr6RFnq.mjs → telemetry-BbniBUbP.mjs} +2 -2
  102. package/dist/{telemetry-DVr6RFnq.mjs.map → telemetry-BbniBUbP.mjs.map} +1 -1
  103. package/dist/{types-D4r_HI9-.d.mts → types-DgXprE3w.d.mts} +3 -3
  104. package/dist/types-DgXprE3w.d.mts.map +1 -0
  105. package/dist/{verify-CgDVZjhc.mjs → verify-BSaNeaSL.mjs} +2 -2
  106. package/dist/{verify-CgDVZjhc.mjs.map → verify-BSaNeaSL.mjs.map} +1 -1
  107. package/package.json +21 -21
  108. package/src/commands/db-init.ts +5 -3
  109. package/src/commands/db-sign.ts +9 -7
  110. package/src/commands/db-update.ts +18 -9
  111. package/src/commands/db-verify.ts +4 -4
  112. package/src/commands/format.ts +1 -1
  113. package/src/commands/init/hygiene-gitattributes.ts +37 -21
  114. package/src/commands/init/init.ts +6 -6
  115. package/src/commands/init/output.ts +4 -5
  116. package/src/commands/init/probe-db.ts +9 -2
  117. package/src/commands/init/reinit-cleanup.ts +16 -17
  118. package/src/commands/init/templates/render.ts +2 -1
  119. package/src/commands/inspect-live-schema.ts +1 -1
  120. package/src/commands/migrate.ts +6 -5
  121. package/src/commands/migration-check.ts +72 -34
  122. package/src/commands/migration-list.ts +1 -5
  123. package/src/commands/migration-log.ts +1 -1
  124. package/src/commands/migration-new.ts +17 -41
  125. package/src/commands/migration-plan.ts +64 -88
  126. package/src/commands/migration-show.ts +2 -2
  127. package/src/commands/migration-status.ts +6 -7
  128. package/src/commands/ref.ts +19 -14
  129. package/src/control-api/client.ts +43 -25
  130. package/src/control-api/contract-enrichment.ts +7 -7
  131. package/src/control-api/operations/contract-emit.ts +2 -3
  132. package/src/control-api/operations/db-init.ts +3 -3
  133. package/src/control-api/operations/db-run.ts +8 -7
  134. package/src/control-api/operations/db-update.ts +2 -2
  135. package/src/control-api/operations/db-verify.ts +4 -4
  136. package/src/control-api/operations/format.ts +5 -4
  137. package/src/control-api/operations/migrate.ts +6 -5
  138. package/src/control-api/operations/run-migration.ts +2 -1
  139. package/src/control-api/types.ts +1 -1
  140. package/src/load-ts-contract.ts +81 -16
  141. package/src/utils/cli-errors.ts +15 -7
  142. package/src/utils/combine-verify-results.ts +2 -1
  143. package/src/utils/command-helpers.ts +15 -5
  144. package/src/utils/contract-at-errors.ts +13 -22
  145. package/src/utils/contract-space-aggregate-loader.ts +8 -8
  146. package/src/utils/contract-space-seed-phase.ts +11 -9
  147. package/src/utils/extension-pack-inputs.ts +8 -8
  148. package/src/utils/formatters/migration-graph-grid-layout.ts +2 -1
  149. package/src/utils/formatters/migration-graph-labels.ts +1 -2
  150. package/src/utils/formatters/migration-list-data-column.ts +1 -2
  151. package/src/utils/framework-components.ts +9 -9
  152. package/src/utils/integrity-violation-to-check-failure.ts +3 -3
  153. package/src/utils/migration-command-scaffold.ts +1 -1
  154. package/src/utils/plan-resolution.ts +7 -10
  155. package/src/utils/ref-advancement.ts +22 -3
  156. package/dist/client-KuBQftxz.mjs.map +0 -1
  157. package/dist/command-helpers-Cpq44aVa.mjs.map +0 -1
  158. package/dist/contract-at-errors-D9gEjYtg.mjs +0 -42
  159. package/dist/contract-at-errors-D9gEjYtg.mjs.map +0 -1
  160. package/dist/contract-space-aggregate-loader-D_3VeHVb.mjs.map +0 -1
  161. package/dist/db-verify-BEclUzki.mjs.map +0 -1
  162. package/dist/format-DAUAZqPt.mjs.map +0 -1
  163. package/dist/framework-components-CnbUbiJw.mjs.map +0 -1
  164. package/dist/init-C3JhkHg-.mjs.map +0 -1
  165. package/dist/migration-check-MHT3w7_v.mjs.map +0 -1
  166. package/dist/migration-graph-command-render-B83xrnNy.mjs.map +0 -1
  167. package/dist/migration-list-BAKujUjh.mjs.map +0 -1
  168. package/dist/migration-plan-CreSVtWZ.mjs.map +0 -1
  169. package/dist/migration-status-YgEvXf-u.mjs.map +0 -1
  170. package/dist/output-mEQ74_nd.mjs.map +0 -1
  171. package/dist/ref-advancement-BkXlikCA.mjs.map +0 -1
  172. package/dist/types-D4r_HI9-.d.mts.map +0 -1
  173. package/src/control-api/errors.ts +0 -9
@@ -4,6 +4,7 @@ import type {
4
4
  LedgerEntryRecord,
5
5
  } from '@prisma-next/contract/types';
6
6
  import { emit as emitContractArtifacts } from '@prisma-next/emitter';
7
+ import { CliStructuredError } from '@prisma-next/errors/control';
7
8
  import type { AuthoringPslBlockDescriptorNamespace } from '@prisma-next/framework-components/authoring';
8
9
  import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
9
10
  import type {
@@ -27,13 +28,13 @@ import {
27
28
  hasSchemaView,
28
29
  } from '@prisma-next/framework-components/control';
29
30
  import type { PslDocumentAst } from '@prisma-next/framework-components/psl-ast';
30
-
31
31
  import { ifDefined } from '@prisma-next/utils/defined';
32
+ import { InternalError } from '@prisma-next/utils/internal-error';
32
33
  import { notOk, ok } from '@prisma-next/utils/result';
34
+ import { structuredError } from '@prisma-next/utils/structured-error';
33
35
 
34
36
  import { assertFrameworkComponentsCompatible } from '../utils/framework-components';
35
37
  import { enrichContract } from './contract-enrichment';
36
- import { ContractValidationError } from './errors';
37
38
  import { executeDbInit } from './operations/db-init';
38
39
  import { executeDbUpdate } from './operations/db-update';
39
40
  import { type ExecuteDbVerifyResult, executeDbVerify } from './operations/db-verify';
@@ -103,7 +104,7 @@ class ControlClientImpl implements ControlClient {
103
104
  target: this.options.target,
104
105
  adapter: this.options.adapter,
105
106
  driver: this.options.driver,
106
- extensionPacks: this.options.extensionPacks,
107
+ extensions: this.options.extensions,
107
108
  });
108
109
 
109
110
  this.familyInstance = this.options.family.create(this.stack);
@@ -112,7 +113,7 @@ class ControlClientImpl implements ControlClient {
112
113
  const rawComponents = [
113
114
  this.options.target,
114
115
  this.options.adapter,
115
- ...(this.options.extensionPacks ?? []),
116
+ ...(this.options.extensions ?? []),
116
117
  ];
117
118
  this.frameworkComponents = assertFrameworkComponentsCompatible(
118
119
  this.options.family.familyId,
@@ -128,20 +129,25 @@ class ControlClientImpl implements ControlClient {
128
129
  this.init();
129
130
 
130
131
  if (this.driver) {
131
- throw new Error('Already connected. Call close() before reconnecting.');
132
+ throw new CliStructuredError(
133
+ 'DRIVER.ALREADY_CONNECTED',
134
+ 'Already connected. Call close() before reconnecting.',
135
+ );
132
136
  }
133
137
 
134
138
  // Resolve connection: argument > default from options
135
139
  const resolvedConnection = connection ?? this.defaultConnection;
136
140
  if (resolvedConnection === undefined) {
137
- throw new Error(
141
+ throw new CliStructuredError(
142
+ 'CONFIG.DB_CONNECTION_REQUIRED',
138
143
  'No connection provided. Pass a connection to connect() or provide a default connection when creating the client.',
139
144
  );
140
145
  }
141
146
 
142
147
  // Check for driver descriptor
143
148
  if (!this.stack?.driver) {
144
- throw new Error(
149
+ throw new CliStructuredError(
150
+ 'CONFIG.DRIVER_REQUIRED',
145
151
  'Driver is not configured. Pass a driver descriptor when creating the control client to enable database operations.',
146
152
  );
147
153
  }
@@ -167,7 +173,8 @@ class ControlClientImpl implements ControlClient {
167
173
  private buildControlAdapter(): ControlAdapterInstance<string, string> {
168
174
  this.init();
169
175
  if (!this.stack?.adapter) {
170
- throw new Error(
176
+ throw new CliStructuredError(
177
+ 'MIGRATION.TARGET_UNSUPPORTED',
171
178
  `Target "${this.options.target.targetId}" requires an adapter for migrations`,
172
179
  );
173
180
  }
@@ -188,7 +195,10 @@ class ControlClientImpl implements ControlClient {
188
195
  }
189
196
 
190
197
  if (!this.driver || !this.familyInstance || !this.frameworkComponents) {
191
- throw new Error('Not connected. Call connect(connection) first.');
198
+ throw new CliStructuredError(
199
+ 'DRIVER.NOT_CONNECTED',
200
+ 'Not connected. Call connect(connection) first.',
201
+ );
192
202
  }
193
203
  return {
194
204
  driver: this.driver,
@@ -229,7 +239,7 @@ class ControlClientImpl implements ControlClient {
229
239
  contract = familyInstance.deserializeContract(options.contract);
230
240
  } catch (error) {
231
241
  const message = error instanceof Error ? error.message : String(error);
232
- throw new ContractValidationError(message, error);
242
+ throw structuredError('CONTRACT.VALIDATION_FAILED', message, { cause: error });
233
243
  }
234
244
 
235
245
  // Emit verify span
@@ -282,7 +292,7 @@ class ControlClientImpl implements ControlClient {
282
292
  contract = familyInstance.deserializeContract(options.contract);
283
293
  } catch (error) {
284
294
  const message = error instanceof Error ? error.message : String(error);
285
- throw new ContractValidationError(message, error);
295
+ throw structuredError('CONTRACT.VALIDATION_FAILED', message, { cause: error });
286
296
  }
287
297
 
288
298
  // Emit schemaVerify span
@@ -336,7 +346,7 @@ class ControlClientImpl implements ControlClient {
336
346
  contract = familyInstance.deserializeContract(options.contract);
337
347
  } catch (error) {
338
348
  const message = error instanceof Error ? error.message : String(error);
339
- throw new ContractValidationError(message, error);
349
+ throw structuredError('CONTRACT.VALIDATION_FAILED', message, { cause: error });
340
350
  }
341
351
 
342
352
  // Emit sign span
@@ -381,7 +391,10 @@ class ControlClientImpl implements ControlClient {
381
391
  const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();
382
392
 
383
393
  if (!hasMigrations(this.options.target)) {
384
- throw new Error(`Target "${this.options.target.targetId}" does not support migrations`);
394
+ throw new CliStructuredError(
395
+ 'MIGRATION.TARGET_UNSUPPORTED',
396
+ `Target "${this.options.target.targetId}" does not support migrations`,
397
+ );
385
398
  }
386
399
 
387
400
  const adapter = this.buildControlAdapter();
@@ -391,7 +404,7 @@ class ControlClientImpl implements ControlClient {
391
404
  contract = familyInstance.deserializeContract(options.contract);
392
405
  } catch (error) {
393
406
  const message = error instanceof Error ? error.message : String(error);
394
- throw new ContractValidationError(message, error);
407
+ throw structuredError('CONTRACT.VALIDATION_FAILED', message, { cause: error });
395
408
  }
396
409
 
397
410
  return executeDbInit({
@@ -404,7 +417,7 @@ class ControlClientImpl implements ControlClient {
404
417
  frameworkComponents,
405
418
  migrationsDir: options.migrationsDir,
406
419
  targetId: this.options.target.targetId,
407
- extensionPacks: this.options.extensionPacks ?? [],
420
+ extensions: this.options.extensions ?? [],
408
421
  ...ifDefined('onProgress', onProgress),
409
422
  });
410
423
  }
@@ -415,7 +428,10 @@ class ControlClientImpl implements ControlClient {
415
428
  const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();
416
429
 
417
430
  if (!hasMigrations(this.options.target)) {
418
- throw new Error(`Target "${this.options.target.targetId}" does not support migrations`);
431
+ throw new CliStructuredError(
432
+ 'MIGRATION.TARGET_UNSUPPORTED',
433
+ `Target "${this.options.target.targetId}" does not support migrations`,
434
+ );
419
435
  }
420
436
 
421
437
  const adapter = this.buildControlAdapter();
@@ -425,7 +441,7 @@ class ControlClientImpl implements ControlClient {
425
441
  contract = familyInstance.deserializeContract(options.contract);
426
442
  } catch (error) {
427
443
  const message = error instanceof Error ? error.message : String(error);
428
- throw new ContractValidationError(message, error);
444
+ throw structuredError('CONTRACT.VALIDATION_FAILED', message, { cause: error });
429
445
  }
430
446
 
431
447
  return executeDbUpdate({
@@ -438,7 +454,7 @@ class ControlClientImpl implements ControlClient {
438
454
  frameworkComponents,
439
455
  migrationsDir: options.migrationsDir,
440
456
  targetId: this.options.target.targetId,
441
- extensionPacks: this.options.extensionPacks ?? [],
457
+ extensions: this.options.extensions ?? [],
442
458
  ...ifDefined('acceptDataLoss', options.acceptDataLoss),
443
459
  ...ifDefined('onProgress', onProgress),
444
460
  });
@@ -455,7 +471,7 @@ class ControlClientImpl implements ControlClient {
455
471
  contract: options.contract,
456
472
  migrationsDir: options.migrationsDir,
457
473
  targetId: this.options.target.targetId,
458
- extensionPacks: this.options.extensionPacks ?? [],
474
+ extensions: this.options.extensions ?? [],
459
475
  frameworkComponents,
460
476
  mode: options.strict ? 'strict' : 'lenient',
461
477
  skipSchema: options.skipSchema,
@@ -490,7 +506,10 @@ class ControlClientImpl implements ControlClient {
490
506
  const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();
491
507
 
492
508
  if (!hasMigrations(this.options.target)) {
493
- throw new Error(`Target "${this.options.target.targetId}" does not support migrations`);
509
+ throw new CliStructuredError(
510
+ 'MIGRATION.TARGET_UNSUPPORTED',
511
+ `Target "${this.options.target.targetId}" does not support migrations`,
512
+ );
494
513
  }
495
514
 
496
515
  let contract: Contract;
@@ -498,7 +517,7 @@ class ControlClientImpl implements ControlClient {
498
517
  contract = familyInstance.deserializeContract(options.contract);
499
518
  } catch (error) {
500
519
  const message = error instanceof Error ? error.message : String(error);
501
- throw new ContractValidationError(message, error);
520
+ throw structuredError('CONTRACT.VALIDATION_FAILED', message, { cause: error });
502
521
  }
503
522
 
504
523
  return executeMigrate({
@@ -508,7 +527,7 @@ class ControlClientImpl implements ControlClient {
508
527
  migrations: this.options.target.migrations,
509
528
  frameworkComponents,
510
529
  migrationsDir: options.migrationsDir,
511
- extensionPacks: this.options.extensionPacks ?? [],
530
+ extensions: this.options.extensions ?? [],
512
531
  targetId: this.options.target.targetId,
513
532
  ...ifDefined('refHash', options.refHash),
514
533
  ...ifDefined('refInvariants', options.refInvariants),
@@ -593,7 +612,7 @@ class ControlClientImpl implements ControlClient {
593
612
  this.init();
594
613
 
595
614
  if (!this.familyInstance) {
596
- throw new Error('Family instance was not initialized. This is a bug.');
615
+ throw new InternalError('Family instance was not initialized. This is a bug.');
597
616
  }
598
617
 
599
618
  let contractRaw: unknown;
@@ -607,9 +626,8 @@ class ControlClientImpl implements ControlClient {
607
626
  try {
608
627
  const stack = this.stack!;
609
628
  const sourceContext = {
610
- composedExtensionPacks: stack.extensionPacks.map((p) => p.id),
629
+ composedExtensions: stack.extensions.map((p) => p.id),
611
630
  composedExtensionContracts: stack.extensionContracts,
612
- scalarTypeDescriptors: stack.scalarTypeDescriptors,
613
631
  authoringContributions: stack.authoringContributions,
614
632
  codecLookup: stack.codecLookup,
615
633
  controlMutationDefaults: stack.controlMutationDefaults,
@@ -65,21 +65,21 @@ export function enrichContract(
65
65
  ): Contract {
66
66
  const mergedCapabilities = mergeCapabilityMatrices(ir.capabilities, components);
67
67
 
68
- const extensionPacksMeta: Record<string, unknown> = {};
68
+ const extensionsMeta: Record<string, unknown> = {};
69
69
  for (const component of components) {
70
70
  if (component.kind === 'extension') {
71
- extensionPacksMeta[component.id] = extractExtensionPackMeta(component);
71
+ extensionsMeta[component.id] = extractExtensionPackMeta(component);
72
72
  }
73
73
  }
74
74
 
75
- const extensionPacks =
76
- Object.keys(extensionPacksMeta).length > 0
77
- ? { ...ir.extensionPacks, ...extensionPacksMeta }
78
- : ir.extensionPacks;
75
+ const extensions =
76
+ Object.keys(extensionsMeta).length > 0
77
+ ? { ...ir.extensions, ...extensionsMeta }
78
+ : ir.extensions;
79
79
 
80
80
  return {
81
81
  ...ir,
82
82
  capabilities: sortDeepTyped(mergedCapabilities),
83
- extensionPacks: sortDeepTyped(extensionPacks),
83
+ extensions: sortDeepTyped(extensions),
84
84
  };
85
85
  }
@@ -195,9 +195,8 @@ export async function executeContractEmit(
195
195
  const stack = createControlStack(config);
196
196
 
197
197
  const sourceContext = {
198
- composedExtensionPacks: stack.extensionPacks.map((p) => p.id),
198
+ composedExtensions: stack.extensions.map((p) => p.id),
199
199
  composedExtensionContracts: stack.extensionContracts,
200
- scalarTypeDescriptors: stack.scalarTypeDescriptors,
201
200
  authoringContributions: stack.authoringContributions,
202
201
  codecLookup: stack.codecLookup,
203
202
  controlMutationDefaults: stack.controlMutationDefaults,
@@ -231,7 +230,7 @@ export async function executeContractEmit(
231
230
  let emitResult: Awaited<ReturnType<typeof emit>>;
232
231
  try {
233
232
  const familyInstance = config.family.create(stack);
234
- const rawComponents = [config.target, config.adapter, ...(config.extensionPacks ?? [])];
233
+ const rawComponents = [config.target, config.adapter, ...(config.extensions ?? [])];
235
234
  const frameworkComponents = assertFrameworkComponentsCompatible(
236
235
  config.family.familyId,
237
236
  config.target.targetId,
@@ -25,7 +25,7 @@ import { executeRun } from './db-run';
25
25
  * 3. The runner's `execute` applies the per-space plans
26
26
  * inside one outer transaction.
27
27
  *
28
- * `extensionPacks` mirrors `Config.extensionPacks` (descriptor list).
28
+ * `extensions` mirrors `Config.extensions` (descriptor list).
29
29
  * The loader (sub-spec § Loader) is the sole descriptor-import boundary.
30
30
  */
31
31
  export interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extends string> {
@@ -55,7 +55,7 @@ export interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extend
55
55
  * routes through the same loader → planner → runner pipeline with no
56
56
  * extension spaces in the aggregate.
57
57
  */
58
- readonly extensionPacks?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
58
+ readonly extensions?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
59
59
  /** Optional progress callback for observing operation progress */
60
60
  readonly onProgress?: OnControlProgress;
61
61
  }
@@ -80,7 +80,7 @@ export async function executeDbInit<TFamilyId extends string, TTargetId extends
80
80
  frameworkComponents: options.frameworkComponents,
81
81
  migrationsDir: options.migrationsDir,
82
82
  targetId: options.targetId,
83
- extensionPacks: options.extensionPacks ?? [],
83
+ extensions: options.extensions ?? [],
84
84
  policy: { allowedOperationClasses: ['additive'] },
85
85
  action: 'dbInit',
86
86
  ...ifDefined('onProgress', options.onProgress),
@@ -24,6 +24,7 @@ import {
24
24
  } from '@prisma-next/migration-tools/aggregate';
25
25
  import { blindCast } from '@prisma-next/utils/casts';
26
26
  import { ifDefined } from '@prisma-next/utils/defined';
27
+ import { InternalError } from '@prisma-next/utils/internal-error';
27
28
  import { notOk, ok } from '@prisma-next/utils/result';
28
29
  import { CliStructuredError } from '../../utils/cli-errors';
29
30
  import {
@@ -80,7 +81,7 @@ export interface ExecuteRunOptions<TFamilyId extends string, TTargetId extends s
80
81
  >;
81
82
  readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
82
83
  readonly migrationsDir: string;
83
- readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
84
+ readonly extensions: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
84
85
  readonly targetId: TTargetId;
85
86
  readonly policy: MigrationOperationPolicy;
86
87
  readonly action: 'dbInit' | 'dbUpdate';
@@ -119,7 +120,7 @@ export async function executeRun<TFamilyId extends string, TTargetId extends str
119
120
  migrations,
120
121
  frameworkComponents,
121
122
  migrationsDir,
122
- extensionPacks,
123
+ extensions,
123
124
  targetId,
124
125
  policy,
125
126
  action,
@@ -131,7 +132,7 @@ export async function executeRun<TFamilyId extends string, TTargetId extends str
131
132
  targetId,
132
133
  migrationsDir,
133
134
  appContract: contract,
134
- extensionPacks,
135
+ extensions,
135
136
  deserializeContract: (json) => familyInstance.deserializeContract(json),
136
137
  };
137
138
  const loaded = await buildContractSpaceAggregate(loadInputs);
@@ -200,7 +201,7 @@ export async function executeRun<TFamilyId extends string, TTargetId extends str
200
201
  // `destination` is the storage hash users see in CLI output.
201
202
  const appResolution = orderedResolutions.find((r) => r.spaceId === aggregate.app.spaceId);
202
203
  if (!appResolution) {
203
- throw new Error(
204
+ throw new InternalError(
204
205
  'Aggregate planner returned no plan for the app space — the planner is supposed to always emit one.',
205
206
  );
206
207
  }
@@ -283,7 +284,7 @@ function aggregatePlannerWarnings(
283
284
  * Compare the live `_prisma_marker` rows against the aggregate's
284
285
  * declared contract spaces. Any marker row whose `space` is not a space of
285
286
  * the aggregate is an "orphan" — typically a marker left behind by
286
- * an extension that was removed from `extensionPacks` without first
287
+ * an extension that was removed from `extensions` without first
287
288
  * cleaning up its on-disk migrations / database tables.
288
289
  *
289
290
  * Returns a {@link CliStructuredError} envelope (code
@@ -319,8 +320,8 @@ function detectOrphanMarkers(
319
320
  .map((s) => `"${s}"`)
320
321
  .join(
321
322
  ', ',
322
- )}) that are not declared in the project's \`extensionPacks\`. The aggregate pipeline refuses to advance markers it cannot account for.`,
323
- 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.',
323
+ )}) that are not declared in the project's \`extensions\`. The aggregate pipeline refuses to advance markers it cannot account for.`,
324
+ 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.',
324
325
  docsUrl: 'https://pris.ly/contract-spaces',
325
326
  meta: {
326
327
  violations: orphans.map((spaceId) => ({ kind: 'orphanMarker', spaceId })),
@@ -40,7 +40,7 @@ export interface ExecuteDbUpdateOptions<TFamilyId extends string, TTargetId exte
40
40
  readonly acceptDataLoss?: boolean;
41
41
  readonly migrationsDir: string;
42
42
  readonly targetId: TTargetId;
43
- readonly extensionPacks?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
43
+ readonly extensions?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
44
44
  readonly onProgress?: OnControlProgress;
45
45
  }
46
46
 
@@ -65,7 +65,7 @@ export async function executeDbUpdate<TFamilyId extends string, TTargetId extend
65
65
  frameworkComponents: options.frameworkComponents,
66
66
  migrationsDir: options.migrationsDir,
67
67
  targetId: options.targetId,
68
- extensionPacks: options.extensionPacks ?? [],
68
+ extensions: options.extensions ?? [],
69
69
  policy: DB_UPDATE_POLICY,
70
70
  action: 'dbUpdate' as const,
71
71
  ...ifDefined('onProgress', options.onProgress),
@@ -50,7 +50,7 @@ export interface ExecuteDbVerifyOptions<TFamilyId extends string, TTargetId exte
50
50
  readonly contract: Contract;
51
51
  readonly migrationsDir: string;
52
52
  readonly targetId: TTargetId;
53
- readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
53
+ readonly extensions: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
54
54
  readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
55
55
  readonly mode: 'strict' | 'lenient';
56
56
  readonly skipSchema: boolean;
@@ -149,7 +149,7 @@ function buildLoadInputs<TFamilyId extends string, TTargetId extends string>(
149
149
  targetId: options.targetId,
150
150
  migrationsDir: options.migrationsDir,
151
151
  appContract: options.contract,
152
- extensionPacks: options.extensionPacks,
152
+ extensions: options.extensions,
153
153
  deserializeContract: (json) => options.familyInstance.deserializeContract(json),
154
154
  };
155
155
  }
@@ -349,7 +349,7 @@ function mapMarkerCheckFailures(
349
349
  violations.push({
350
350
  kind: 'orphanMarker',
351
351
  spaceId: orphan.spaceId,
352
- remediation: `Add the corresponding extension to \`extensionPacks\` in \`prisma-next.config.ts\`, or delete the orphan marker row for "${orphan.spaceId}".`,
352
+ remediation: `Add the corresponding extension to \`extensions\` in \`prisma-next.config.ts\`, or delete the orphan marker row for "${orphan.spaceId}".`,
353
353
  });
354
354
  }
355
355
  if (violations.length === 0) return null;
@@ -359,7 +359,7 @@ function mapMarkerCheckFailures(
359
359
  ? 'Contract-space verifier found a violation'
360
360
  : `Contract-space verifier found violations (${violations.length})`;
361
361
  return new CliStructuredError('MIGRATION.CONTRACT_SPACE_VIOLATION', summary, {
362
- why: `The on-disk \`migrations/\` directory, the \`extensionPacks\` declaration, and the live database marker rows are not in agreement.\n${lines.join('\n')}`,
362
+ why: `The on-disk \`migrations/\` directory, the \`extensions\` declaration, and the live database marker rows are not in agreement.\n${lines.join('\n')}`,
363
363
  fix: violations[0]?.remediation ?? 'Review and reconcile the violations listed above.',
364
364
  docsUrl: 'https://pris.ly/contract-spaces',
365
365
  meta: { violations },
@@ -1,8 +1,9 @@
1
1
  import { readFile, writeFile } from 'node:fs/promises';
2
2
  import { EOL } from 'node:os';
3
3
  import { loadConfig } from '@prisma-next/config-loader';
4
- import { type FormatOptions, format, PslFormatError } from '@prisma-next/psl-parser/format';
4
+ import { type FormatOptions, format } from '@prisma-next/psl-parser/format';
5
5
  import { notOk, ok, type Result } from '@prisma-next/utils/result';
6
+ import { isStructuredError } from '@prisma-next/utils/structured-error';
6
7
  import { CliStructuredError, errorRuntime, errorUnexpected } from '../../utils/cli-errors';
7
8
 
8
9
  export interface FormatOperationOptions {
@@ -41,7 +42,7 @@ export async function executeFormat(
41
42
  }
42
43
 
43
44
  const source = config.contract?.source;
44
- if (source?.sourceFormat !== 'psl') {
45
+ if (source?.format !== 'psl') {
45
46
  return ok({ formatted: false });
46
47
  }
47
48
 
@@ -71,12 +72,12 @@ export async function executeFormat(
71
72
  try {
72
73
  formatted = format(contents, formatOptions);
73
74
  } catch (error) {
74
- if (error instanceof PslFormatError) {
75
+ if (isStructuredError(error) && error.code === 'PSL.PARSE_FAILED') {
75
76
  return notOk(
76
77
  errorRuntime('Cannot format PSL with parse errors', {
77
78
  why: error.message,
78
79
  fix: 'Fix the parse errors in your schema and try again.',
79
- meta: { diagnostics: error.diagnostics },
80
+ meta: { diagnostics: error.meta?.['diagnostics'] },
80
81
  }),
81
82
  );
82
83
  }
@@ -24,6 +24,7 @@ import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';
24
24
  import { errorNoInvariantPath } from '@prisma-next/migration-tools/errors';
25
25
  import { findPathWithDecision } from '@prisma-next/migration-tools/migration-graph';
26
26
  import { ifDefined } from '@prisma-next/utils/defined';
27
+ import { InternalError } from '@prisma-next/utils/internal-error';
27
28
  import { notOk, ok } from '@prisma-next/utils/result';
28
29
  import {
29
30
  type BuildAggregateInputs,
@@ -60,7 +61,7 @@ export interface ExecuteMigrateOptions<TFamilyId extends string, TTargetId exten
60
61
  >;
61
62
  readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
62
63
  readonly migrationsDir: string;
63
- readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
64
+ readonly extensions: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
64
65
  readonly targetId: TTargetId;
65
66
  /**
66
67
  * Optional app-space ref override. When provided, the app space's
@@ -122,7 +123,7 @@ export async function executeMigrate<TFamilyId extends string, TTargetId extends
122
123
  migrations,
123
124
  frameworkComponents,
124
125
  migrationsDir,
125
- extensionPacks,
126
+ extensions,
126
127
  targetId,
127
128
  refHash,
128
129
  refInvariants,
@@ -134,7 +135,7 @@ export async function executeMigrate<TFamilyId extends string, TTargetId extends
134
135
  targetId,
135
136
  migrationsDir,
136
137
  appContract: contract,
137
- extensionPacks,
138
+ extensions,
138
139
  deserializeContract: (json) => familyInstance.deserializeContract(json),
139
140
  };
140
141
  const loaded = await buildContractSpaceAggregate(loadInputs);
@@ -247,7 +248,7 @@ export async function executeMigrate<TFamilyId extends string, TTargetId extends
247
248
  .map((spaceId) => {
248
249
  const entry = perSpacePlans.get(spaceId) ?? atHeadResolutions.get(spaceId);
249
250
  if (entry === undefined) {
250
- throw new Error(`Unreachable: missing per-space plan for "${spaceId}"`);
251
+ throw new InternalError(`Unreachable: missing per-space plan for "${spaceId}"`);
251
252
  }
252
253
  return { spaceId, entry };
253
254
  });
@@ -306,7 +307,7 @@ export async function executeMigrate<TFamilyId extends string, TTargetId extends
306
307
  }
307
308
  const entry = atHeadResolutions.get(spaceId);
308
309
  if (entry === undefined) {
309
- throw new Error(`Unreachable: missing per-space plan for "${spaceId}"`);
310
+ throw new InternalError(`Unreachable: missing per-space plan for "${spaceId}"`);
310
311
  }
311
312
  return { spaceId, entry };
312
313
  });
@@ -12,6 +12,7 @@ import type {
12
12
  } from '@prisma-next/framework-components/control';
13
13
  import type { ContractSpaceAggregate, PerSpacePlan } from '@prisma-next/migration-tools/aggregate';
14
14
  import { ifDefined } from '@prisma-next/utils/defined';
15
+ import { InternalError } from '@prisma-next/utils/internal-error';
15
16
  import { notOk, ok, type Result } from '@prisma-next/utils/result';
16
17
  import type { OnControlProgress, PerSpaceExecutionEntry } from '../types';
17
18
 
@@ -243,7 +244,7 @@ export function collectOrdered(
243
244
  return applyOrder.map((spaceId) => {
244
245
  const entry = perSpace.get(spaceId);
245
246
  if (!entry) {
246
- throw new Error(`planner output missing per-space plan for "${spaceId}"`);
247
+ throw new InternalError(`planner output missing per-space plan for "${spaceId}"`);
247
248
  }
248
249
  return { spaceId, entry };
249
250
  });
@@ -52,7 +52,7 @@ export interface ControlClientOptions {
52
52
  // biome-ignore lint/suspicious/noExplicitAny: required for contravariance in driver.create()
53
53
  readonly driver?: ControlDriverDescriptor<any, any, any, any>;
54
54
  // biome-ignore lint/suspicious/noExplicitAny: required for contravariance in extension.create()
55
- readonly extensionPacks?: ReadonlyArray<ControlExtensionDescriptor<any, any, any>>;
55
+ readonly extensions?: ReadonlyArray<ControlExtensionDescriptor<any, any, any>>;
56
56
  /**
57
57
  * Optional default connection for auto-connect.
58
58
  * When provided, operations will auto-connect if not already connected.