@prisma-next/core-control-plane 0.3.0-dev.8 → 0.3.0-dev.81

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 (97) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +31 -99
  3. package/dist/constants.d.mts +9 -0
  4. package/dist/constants.d.mts.map +1 -0
  5. package/dist/constants.mjs +10 -0
  6. package/dist/constants.mjs.map +1 -0
  7. package/dist/emission.d.mts +58 -0
  8. package/dist/emission.d.mts.map +1 -0
  9. package/dist/emission.mjs +315 -0
  10. package/dist/emission.mjs.map +1 -0
  11. package/dist/errors.d.mts +231 -0
  12. package/dist/errors.d.mts.map +1 -0
  13. package/dist/errors.mjs +330 -0
  14. package/dist/errors.mjs.map +1 -0
  15. package/dist/{schema-view.d.ts → schema-view-DObwT8x9.d.mts} +17 -14
  16. package/dist/schema-view-DObwT8x9.d.mts.map +1 -0
  17. package/dist/schema-view.d.mts +2 -0
  18. package/dist/schema-view.mjs +1 -0
  19. package/dist/stack.d.mts +30 -0
  20. package/dist/stack.d.mts.map +1 -0
  21. package/dist/stack.mjs +30 -0
  22. package/dist/stack.mjs.map +1 -0
  23. package/dist/types-BArIWumw.d.mts +615 -0
  24. package/dist/types-BArIWumw.d.mts.map +1 -0
  25. package/dist/types.d.mts +2 -0
  26. package/dist/types.mjs +1 -0
  27. package/package.json +31 -43
  28. package/src/constants.ts +5 -0
  29. package/src/emission/canonicalization.ts +68 -21
  30. package/src/emission/emit.ts +82 -21
  31. package/src/emission/hashing.ts +29 -27
  32. package/src/emission/types.ts +13 -2
  33. package/src/errors.ts +116 -12
  34. package/src/exports/constants.ts +1 -0
  35. package/src/exports/emission.ts +1 -1
  36. package/src/exports/errors.ts +6 -1
  37. package/src/exports/types.ts +0 -1
  38. package/src/migrations.ts +27 -1
  39. package/src/schema-view.ts +5 -5
  40. package/src/types.ts +24 -12
  41. package/dist/chunk-473ODD3P.js +0 -14
  42. package/dist/chunk-473ODD3P.js.map +0 -1
  43. package/dist/chunk-U5RYT6PT.js +0 -229
  44. package/dist/chunk-U5RYT6PT.js.map +0 -1
  45. package/dist/config-types.d.ts +0 -68
  46. package/dist/config-types.d.ts.map +0 -1
  47. package/dist/config-validation.d.ts +0 -10
  48. package/dist/config-validation.d.ts.map +0 -1
  49. package/dist/emission/canonicalization.d.ts +0 -6
  50. package/dist/emission/canonicalization.d.ts.map +0 -1
  51. package/dist/emission/emit.d.ts +0 -5
  52. package/dist/emission/emit.d.ts.map +0 -1
  53. package/dist/emission/hashing.d.ts +0 -17
  54. package/dist/emission/hashing.d.ts.map +0 -1
  55. package/dist/emission/types.d.ts +0 -16
  56. package/dist/emission/types.d.ts.map +0 -1
  57. package/dist/errors.d.ts +0 -183
  58. package/dist/errors.d.ts.map +0 -1
  59. package/dist/exports/config-types.d.ts +0 -3
  60. package/dist/exports/config-types.d.ts.map +0 -1
  61. package/dist/exports/config-types.js +0 -53
  62. package/dist/exports/config-types.js.map +0 -1
  63. package/dist/exports/config-validation.d.ts +0 -2
  64. package/dist/exports/config-validation.d.ts.map +0 -1
  65. package/dist/exports/config-validation.js +0 -252
  66. package/dist/exports/config-validation.js.map +0 -1
  67. package/dist/exports/emission.d.ts +0 -5
  68. package/dist/exports/emission.d.ts.map +0 -1
  69. package/dist/exports/emission.js +0 -310
  70. package/dist/exports/emission.js.map +0 -1
  71. package/dist/exports/errors.d.ts +0 -3
  72. package/dist/exports/errors.d.ts.map +0 -1
  73. package/dist/exports/errors.js +0 -43
  74. package/dist/exports/errors.js.map +0 -1
  75. package/dist/exports/schema-view.d.ts +0 -2
  76. package/dist/exports/schema-view.d.ts.map +0 -1
  77. package/dist/exports/schema-view.js +0 -1
  78. package/dist/exports/schema-view.js.map +0 -1
  79. package/dist/exports/stack.d.ts +0 -2
  80. package/dist/exports/stack.d.ts.map +0 -1
  81. package/dist/exports/stack.js +0 -7
  82. package/dist/exports/stack.js.map +0 -1
  83. package/dist/exports/types.d.ts +0 -3
  84. package/dist/exports/types.d.ts.map +0 -1
  85. package/dist/exports/types.js +0 -7
  86. package/dist/exports/types.js.map +0 -1
  87. package/dist/migrations.d.ts +0 -190
  88. package/dist/migrations.d.ts.map +0 -1
  89. package/dist/schema-view.d.ts.map +0 -1
  90. package/dist/stack.d.ts +0 -25
  91. package/dist/stack.d.ts.map +0 -1
  92. package/dist/types.d.ts +0 -411
  93. package/dist/types.d.ts.map +0 -1
  94. package/src/config-types.ts +0 -157
  95. package/src/config-validation.ts +0 -270
  96. package/src/exports/config-types.ts +0 -5
  97. package/src/exports/config-validation.ts +0 -1
package/src/errors.ts CHANGED
@@ -1,8 +1,12 @@
1
+ import { ifDefined } from '@prisma-next/utils/defined';
2
+ import type { SchemaIssue, VerifyDatabaseSchemaResult } from './types';
3
+
1
4
  /**
2
5
  * CLI error envelope for output formatting.
3
6
  * This is the serialized form of a CliStructuredError.
4
7
  */
5
8
  export interface CliErrorEnvelope {
9
+ readonly ok: false;
6
10
  readonly code: string;
7
11
  readonly domain: string;
8
12
  readonly severity: 'error' | 'warn' | 'info';
@@ -66,7 +70,7 @@ export class CliStructuredError extends Error {
66
70
  this.domain = options?.domain ?? 'CLI';
67
71
  this.severity = options?.severity ?? 'error';
68
72
  this.why = options?.why;
69
- this.fix = options?.fix;
73
+ this.fix = options?.fix === options?.why ? undefined : options?.fix;
70
74
  this.where = options?.where
71
75
  ? {
72
76
  path: options.where.path,
@@ -83,6 +87,7 @@ export class CliStructuredError extends Error {
83
87
  toEnvelope(): CliErrorEnvelope {
84
88
  const codePrefix = this.domain === 'CLI' ? 'PN-CLI-' : 'PN-RTM-';
85
89
  return {
90
+ ok: false as const,
86
91
  code: `${codePrefix}${this.code}`,
87
92
  domain: this.domain,
88
93
  severity: this.severity,
@@ -94,6 +99,23 @@ export class CliStructuredError extends Error {
94
99
  docsUrl: this.docsUrl,
95
100
  };
96
101
  }
102
+
103
+ /**
104
+ * Type guard to check if an error is a CliStructuredError.
105
+ * Uses duck-typing to work across module boundaries where instanceof may fail.
106
+ */
107
+ static is(error: unknown): error is CliStructuredError {
108
+ if (!(error instanceof Error)) {
109
+ return false;
110
+ }
111
+ const candidate = error as CliStructuredError;
112
+ return (
113
+ candidate.name === 'CliStructuredError' &&
114
+ typeof candidate.code === 'string' &&
115
+ (candidate.domain === 'CLI' || candidate.domain === 'RTM') &&
116
+ typeof candidate.toEnvelope === 'function'
117
+ );
118
+ }
97
119
  }
98
120
 
99
121
  // ============================================================================
@@ -171,13 +193,19 @@ export function errorFileNotFound(
171
193
  }
172
194
 
173
195
  /**
174
- * Database URL is required but not provided.
196
+ * Database connection is required but not provided.
175
197
  */
176
- export function errorDatabaseUrlRequired(options?: { readonly why?: string }): CliStructuredError {
177
- return new CliStructuredError('4005', 'Database URL is required', {
198
+ export function errorDatabaseConnectionRequired(options?: {
199
+ readonly why?: string;
200
+ readonly commandName?: string;
201
+ }): CliStructuredError {
202
+ const runHint = options?.commandName
203
+ ? `Run \`prisma-next ${options.commandName} --db <url>\``
204
+ : 'Provide `--db <url>`';
205
+ return new CliStructuredError('4005', 'Database connection is required', {
178
206
  domain: 'CLI',
179
- why: options?.why ?? 'Database URL is required for this command',
180
- fix: 'Provide `--db <url>` or set `db: { url: "postgres://…" }` in prisma-next.config.ts',
207
+ why: options?.why ?? 'Database connection is required for this command',
208
+ fix: `${runHint}, or set \`db: { connection: "postgres://…" }\` in prisma-next.config.ts`,
181
209
  });
182
210
  }
183
211
 
@@ -316,16 +344,16 @@ export function errorConfigValidation(
316
344
  readonly why?: string;
317
345
  },
318
346
  ): CliStructuredError {
319
- return new CliStructuredError('4001', 'Config file not found', {
347
+ return new CliStructuredError('4009', 'Config validation error', {
320
348
  domain: 'CLI',
321
349
  why: options?.why ?? `Config must have a "${field}" field`,
322
- fix: "Run 'prisma-next init' to create a config file",
350
+ fix: 'Check your prisma-next.config.ts and ensure all required fields are provided',
323
351
  docsUrl: 'https://prisma-next.dev/docs/cli/config',
324
352
  });
325
353
  }
326
354
 
327
355
  // ============================================================================
328
- // Runtime Errors (PN-RTM-3000-3003)
356
+ // Runtime Errors (PN-RTM-3000-3030)
329
357
  // ============================================================================
330
358
 
331
359
  /**
@@ -335,10 +363,10 @@ export function errorMarkerMissing(options?: {
335
363
  readonly why?: string;
336
364
  readonly dbUrl?: string;
337
365
  }): CliStructuredError {
338
- return new CliStructuredError('3001', 'Marker missing', {
366
+ return new CliStructuredError('3001', 'Database not signed', {
339
367
  domain: 'RTM',
340
- why: options?.why ?? 'Contract marker not found in database',
341
- fix: 'Run `prisma-next db sign --db <url>` to create marker',
368
+ why: options?.why ?? 'No database signature (marker) found',
369
+ fix: 'Run `prisma-next db sign --db <url>` to sign the database',
342
370
  });
343
371
  }
344
372
 
@@ -385,6 +413,82 @@ export function errorTargetMismatch(
385
413
  });
386
414
  }
387
415
 
416
+ /**
417
+ * Database marker is required but not found.
418
+ * Used by commands that require a pre-existing marker as a precondition.
419
+ */
420
+ export function errorMarkerRequired(options?: {
421
+ readonly why?: string;
422
+ readonly fix?: string;
423
+ }): CliStructuredError {
424
+ return new CliStructuredError('3010', 'Database must be signed first', {
425
+ domain: 'RTM',
426
+ why: options?.why ?? 'No database signature (marker) found',
427
+ fix: options?.fix ?? 'Run `prisma-next db init` first to sign the database',
428
+ });
429
+ }
430
+
431
+ /**
432
+ * Schema verification found mismatches between the database and the contract.
433
+ * The full verification tree is preserved in `meta.verificationResult`.
434
+ */
435
+ export function errorSchemaVerificationFailed(options: {
436
+ readonly summary: string;
437
+ readonly verificationResult: VerifyDatabaseSchemaResult;
438
+ readonly issues?: readonly SchemaIssue[];
439
+ }): CliStructuredError {
440
+ return new CliStructuredError('3004', options.summary, {
441
+ domain: 'RTM',
442
+ why: 'Database schema does not satisfy the contract',
443
+ fix: 'Run `prisma-next db update` to reconcile, or adjust your contract to match the database',
444
+ meta: {
445
+ verificationResult: options.verificationResult,
446
+ ...ifDefined('issues', options.issues),
447
+ },
448
+ });
449
+ }
450
+
451
+ /**
452
+ * Migration runner failed during execution.
453
+ */
454
+ export function errorRunnerFailed(
455
+ summary: string,
456
+ options?: {
457
+ readonly why?: string;
458
+ readonly fix?: string;
459
+ readonly meta?: Record<string, unknown>;
460
+ },
461
+ ): CliStructuredError {
462
+ return new CliStructuredError('3020', summary, {
463
+ domain: 'RTM',
464
+ why: options?.why ?? 'Migration runner failed',
465
+ fix: options?.fix ?? 'Inspect the reported conflict and reconcile schema drift',
466
+ ...(options?.meta ? { meta: options.meta } : {}),
467
+ });
468
+ }
469
+
470
+ /** Error code for destructive changes that require explicit confirmation. */
471
+ export const ERROR_CODE_DESTRUCTIVE_CHANGES = '3030';
472
+
473
+ /**
474
+ * Destructive operations require explicit confirmation via -y/--yes.
475
+ */
476
+ export function errorDestructiveChanges(
477
+ summary: string,
478
+ options?: {
479
+ readonly why?: string;
480
+ readonly fix?: string;
481
+ readonly meta?: Record<string, unknown>;
482
+ },
483
+ ): CliStructuredError {
484
+ return new CliStructuredError(ERROR_CODE_DESTRUCTIVE_CHANGES, summary, {
485
+ domain: 'RTM',
486
+ why: options?.why ?? 'Planned operations include destructive changes that require confirmation',
487
+ fix: options?.fix ?? 'Re-run with `-y` to apply, or use `--dry-run` to preview first',
488
+ ...(options?.meta ? { meta: options.meta } : {}),
489
+ });
490
+ }
491
+
388
492
  /**
389
493
  * Generic runtime error.
390
494
  */
@@ -0,0 +1 @@
1
+ export { EMPTY_CONTRACT_HASH } from '../constants';
@@ -2,5 +2,5 @@
2
2
 
3
3
  export { canonicalizeContract } from '../emission/canonicalization';
4
4
  export { emit } from '../emission/emit';
5
- export { computeCoreHash, computeProfileHash } from '../emission/hashing';
5
+ export { computeExecutionHash, computeProfileHash, computeStorageHash } from '../emission/hashing';
6
6
  export type { EmitOptions, EmitResult } from '../emission/types';
@@ -1,21 +1,26 @@
1
1
  export type { CliErrorConflict, CliErrorEnvelope } from '../errors';
2
2
  export {
3
3
  CliStructuredError,
4
+ ERROR_CODE_DESTRUCTIVE_CHANGES,
4
5
  errorConfigFileNotFound,
5
6
  errorConfigValidation,
6
7
  errorContractConfigMissing,
7
8
  errorContractMissingExtensionPacks,
8
9
  errorContractValidationFailed,
9
- errorDatabaseUrlRequired,
10
+ errorDatabaseConnectionRequired,
11
+ errorDestructiveChanges,
10
12
  errorDriverRequired,
11
13
  errorFamilyReadMarkerSqlRequired,
12
14
  errorFileNotFound,
13
15
  errorHashMismatch,
14
16
  errorJsonFormatNotSupported,
15
17
  errorMarkerMissing,
18
+ errorMarkerRequired,
16
19
  errorMigrationPlanningFailed,
17
20
  errorQueryRunnerFactoryRequired,
21
+ errorRunnerFailed,
18
22
  errorRuntime,
23
+ errorSchemaVerificationFailed,
19
24
  errorTargetMigrationNotSupported,
20
25
  errorTargetMismatch,
21
26
  errorUnexpected,
@@ -1,4 +1,3 @@
1
- export { createControlPlaneStack } from '../stack';
2
1
  export type {
3
2
  // Control* types (ADR 151)
4
3
  ControlAdapterDescriptor,
package/src/migrations.ts CHANGED
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import type { TargetBoundComponentDescriptor } from '@prisma-next/contract/framework-components';
13
+ import type { ContractIR } from '@prisma-next/contract/ir';
13
14
  import type { Result } from '@prisma-next/utils/result';
14
15
  import type { ControlDriverInstance, ControlFamilyInstance } from './types';
15
16
 
@@ -49,6 +50,10 @@ export interface MigrationPlanOperation {
49
50
  readonly operationClass: MigrationOperationClass;
50
51
  }
51
52
 
53
+ // ============================================================================
54
+ // Plan Types (Display-Oriented)
55
+ // ============================================================================
56
+
52
57
  /**
53
58
  * A migration plan for display purposes.
54
59
  * Contains only the fields needed for CLI output (summary, JSON envelope).
@@ -56,9 +61,17 @@ export interface MigrationPlanOperation {
56
61
  export interface MigrationPlan {
57
62
  /** The target ID this plan is for (e.g., 'postgres'). */
58
63
  readonly targetId: string;
64
+ /**
65
+ * Origin contract identity that the plan expects the database to currently be at.
66
+ * If omitted or null, the runner skips origin validation entirely.
67
+ */
68
+ readonly origin?: {
69
+ readonly storageHash: string;
70
+ readonly profileHash?: string;
71
+ } | null;
59
72
  /** Destination contract identity that the plan intends to reach. */
60
73
  readonly destination: {
61
- readonly coreHash: string;
74
+ readonly storageHash: string;
62
75
  readonly profileHash?: string;
63
76
  };
64
77
  /** Ordered list of operations to execute. */
@@ -244,4 +257,17 @@ export interface TargetMigrationsCapability<
244
257
  > {
245
258
  createPlanner(family: TFamilyInstance): MigrationPlanner<TFamilyId, TTargetId>;
246
259
  createRunner(family: TFamilyInstance): MigrationRunner<TFamilyId, TTargetId>;
260
+ /**
261
+ * Synthesizes a family-specific schema IR from a contract for offline planning.
262
+ * The returned schema can be passed to `planner.plan({ schema })` as the "from" state.
263
+ *
264
+ * @param contract - The contract to convert, or null for a new project (empty schema).
265
+ * @param frameworkComponents - Active framework components, used to derive database
266
+ * dependencies (e.g. extensions) that should be reflected in the schema IR.
267
+ * @returns Family-specific schema IR (e.g., `SqlSchemaIR` for SQL targets).
268
+ */
269
+ contractToSchema(
270
+ contract: ContractIR | null,
271
+ frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>,
272
+ ): unknown;
247
273
  }
@@ -15,7 +15,7 @@
15
15
  * // SqlSchemaIR structure:
16
16
  * // {
17
17
  * // tables: { user: { columns: {...}, primaryKey: {...}, ... }, ... },
18
- * // extensions: ['pgvector'],
18
+ * // dependencies: [{ id: 'postgres.extension.vector' }],
19
19
  * // annotations: {...}
20
20
  * // }
21
21
  *
@@ -47,9 +47,9 @@
47
47
  * // ]
48
48
  * // },
49
49
  * // {
50
- * // kind: 'extension',
51
- * // id: 'extension-pgvector',
52
- * // label: 'extension pgvector',
50
+ * // kind: 'dependency',
51
+ * // id: 'dependency-postgres.extension.pgvector',
52
+ * // label: 'pgvector extension is enabled',
53
53
  * // meta: { ... }
54
54
  * // }
55
55
  * // ]
@@ -72,7 +72,7 @@ export type SchemaNodeKind =
72
72
  | 'entity'
73
73
  | 'field'
74
74
  | 'index'
75
- | 'extension';
75
+ | 'dependency';
76
76
 
77
77
  /**
78
78
  * A node in the schema tree.
package/src/types.ts CHANGED
@@ -53,17 +53,17 @@ export interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR = unk
53
53
  * Mappings are runtime-only and should not be part of ContractIR.
54
54
  *
55
55
  * Note: The returned ContractIR may include additional fields from the emitted contract
56
- * (like coreHash, profileHash) that are not part of the ContractIR type but are preserved
56
+ * (like storageHash/executionHash, profileHash) that are not part of the ContractIR type but are preserved
57
57
  * for use by verify/sign operations.
58
58
  */
59
59
  validateContractIR(contractJson: unknown): ContractIR;
60
60
 
61
61
  /**
62
62
  * Verifies the database marker against the contract.
63
- * Compares target, coreHash, and profileHash.
63
+ * Compares target, storageHash, and profileHash.
64
64
  *
65
65
  * @param options.contractIR - The validated contract (from validateContractIR). Must have
66
- * coreHash and target fields for verification. These fields are present in emitted
66
+ * storageHash and target fields for verification. These fields are present in emitted
67
67
  * contracts but not in the ContractIR type definition.
68
68
  */
69
69
  verify(options: {
@@ -316,9 +316,14 @@ export interface ControlAdapterDescriptor<
316
316
  /**
317
317
  * Descriptor for a control-plane driver component (e.g., Postgres driver).
318
318
  *
319
+ * The connection input type is driver-specific. For example:
320
+ * - Postgres uses a connection string (URL)
321
+ * - Other drivers may accept structured objects (e.g., file paths, credentials)
322
+ *
319
323
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
320
324
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
321
325
  * @template TDriverInstance - The driver instance type
326
+ * @template TConnection - The connection input type (defaults to `string` for URL-based drivers)
322
327
  */
323
328
  export interface ControlDriverDescriptor<
324
329
  TFamilyId extends string,
@@ -327,8 +332,9 @@ export interface ControlDriverDescriptor<
327
332
  TFamilyId,
328
333
  TTargetId
329
334
  >,
335
+ TConnection = string,
330
336
  > extends DriverDescriptor<TFamilyId, TTargetId> {
331
- create(url: string): Promise<TDriverInstance>;
337
+ create(connection: TConnection): Promise<TDriverInstance>;
332
338
  }
333
339
 
334
340
  /**
@@ -357,11 +363,11 @@ export interface VerifyDatabaseResult {
357
363
  readonly code?: string;
358
364
  readonly summary: string;
359
365
  readonly contract: {
360
- readonly coreHash: string;
366
+ readonly storageHash: string;
361
367
  readonly profileHash?: string;
362
368
  };
363
369
  readonly marker?: {
364
- readonly coreHash?: string;
370
+ readonly storageHash?: string;
365
371
  readonly profileHash?: string;
366
372
  };
367
373
  readonly target: {
@@ -393,15 +399,20 @@ export interface SchemaIssue {
393
399
  | 'extra_unique_constraint'
394
400
  | 'extra_index'
395
401
  | 'type_mismatch'
402
+ | 'type_missing'
403
+ | 'type_values_mismatch'
396
404
  | 'nullability_mismatch'
397
405
  | 'primary_key_mismatch'
398
406
  | 'foreign_key_mismatch'
399
407
  | 'unique_constraint_mismatch'
400
408
  | 'index_mismatch'
401
- | 'extension_missing';
402
- readonly table: string;
409
+ | 'dependency_missing'
410
+ | 'default_missing'
411
+ | 'default_mismatch';
412
+ readonly table?: string;
403
413
  readonly column?: string;
404
414
  readonly indexOrConstraint?: string;
415
+ readonly typeName?: string;
405
416
  readonly expected?: string;
406
417
  readonly actual?: string;
407
418
  readonly message: string;
@@ -431,7 +442,7 @@ export interface VerifyDatabaseSchemaResult {
431
442
  readonly code?: string;
432
443
  readonly summary: string;
433
444
  readonly contract: {
434
- readonly coreHash: string;
445
+ readonly storageHash: string;
435
446
  readonly profileHash?: string;
436
447
  };
437
448
  readonly target: {
@@ -464,7 +475,8 @@ export interface VerifyDatabaseSchemaResult {
464
475
  export interface EmitContractResult {
465
476
  readonly contractJson: string;
466
477
  readonly contractDts: string;
467
- readonly coreHash: string;
478
+ readonly storageHash: string;
479
+ readonly executionHash?: string;
468
480
  readonly profileHash: string;
469
481
  }
470
482
 
@@ -499,7 +511,7 @@ export interface SignDatabaseResult {
499
511
  readonly ok: boolean;
500
512
  readonly summary: string;
501
513
  readonly contract: {
502
- readonly coreHash: string;
514
+ readonly storageHash: string;
503
515
  readonly profileHash?: string;
504
516
  };
505
517
  readonly target: {
@@ -510,7 +522,7 @@ export interface SignDatabaseResult {
510
522
  readonly created: boolean;
511
523
  readonly updated: boolean;
512
524
  readonly previous?: {
513
- readonly coreHash?: string;
525
+ readonly storageHash?: string;
514
526
  readonly profileHash?: string;
515
527
  };
516
528
  };
@@ -1,14 +0,0 @@
1
- // src/stack.ts
2
- function createControlPlaneStack(input) {
3
- return {
4
- target: input.target,
5
- adapter: input.adapter,
6
- driver: input.driver,
7
- extensionPacks: input.extensionPacks ?? []
8
- };
9
- }
10
-
11
- export {
12
- createControlPlaneStack
13
- };
14
- //# sourceMappingURL=chunk-473ODD3P.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/stack.ts"],"sourcesContent":["import type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlExtensionDescriptor,\n ControlPlaneStack,\n ControlTargetDescriptor,\n} from './types';\n\n/**\n * Creates a ControlPlaneStack from component descriptors.\n *\n * Provides sensible defaults:\n * - `driver` defaults to `undefined` (optional for commands that don't need DB connection)\n * - `extensionPacks` defaults to `[]` (empty array)\n *\n * @example\n * ```ts\n * const stack = createControlPlaneStack({\n * target: postgresTarget,\n * adapter: postgresAdapter,\n * driver: postgresDriver, // optional\n * extensionPacks: [pgvector], // optional\n * });\n * ```\n */\nexport function createControlPlaneStack<TFamilyId extends string, TTargetId extends string>(input: {\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;\n readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;\n readonly extensionPacks?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[] | undefined;\n}): ControlPlaneStack<TFamilyId, TTargetId> {\n return {\n target: input.target,\n adapter: input.adapter,\n driver: input.driver,\n extensionPacks: input.extensionPacks ?? [],\n };\n}\n"],"mappings":";AAyBO,SAAS,wBAA4E,OAKhD;AAC1C,SAAO;AAAA,IACL,QAAQ,MAAM;AAAA,IACd,SAAS,MAAM;AAAA,IACf,QAAQ,MAAM;AAAA,IACd,gBAAgB,MAAM,kBAAkB,CAAC;AAAA,EAC3C;AACF;","names":[]}