@prisma-next/target-postgres 0.3.0-dev.34 → 0.3.0-dev.37

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 (44) hide show
  1. package/README.md +6 -1
  2. package/dist/control.d.mts +16 -0
  3. package/dist/control.d.mts.map +1 -0
  4. package/dist/control.mjs +2494 -0
  5. package/dist/control.mjs.map +1 -0
  6. package/dist/descriptor-meta-DxB8oZzB.mjs +13 -0
  7. package/dist/descriptor-meta-DxB8oZzB.mjs.map +1 -0
  8. package/dist/pack.d.mts +7 -0
  9. package/dist/pack.d.mts.map +1 -0
  10. package/dist/pack.mjs +9 -0
  11. package/dist/pack.mjs.map +1 -0
  12. package/dist/runtime.d.mts +9 -0
  13. package/dist/runtime.d.mts.map +1 -0
  14. package/dist/runtime.mjs +21 -0
  15. package/dist/runtime.mjs.map +1 -0
  16. package/package.json +28 -28
  17. package/src/core/migrations/planner.ts +237 -22
  18. package/src/core/migrations/runner.ts +27 -20
  19. package/src/core/migrations/statement-builders.ts +6 -6
  20. package/src/core/types.ts +5 -0
  21. package/src/exports/control.ts +1 -3
  22. package/src/exports/runtime.ts +7 -12
  23. package/dist/chunk-RKEXRSSI.js +0 -14
  24. package/dist/chunk-RKEXRSSI.js.map +0 -1
  25. package/dist/core/descriptor-meta.d.ts +0 -9
  26. package/dist/core/descriptor-meta.d.ts.map +0 -1
  27. package/dist/core/migrations/planner.d.ts +0 -14
  28. package/dist/core/migrations/planner.d.ts.map +0 -1
  29. package/dist/core/migrations/runner.d.ts +0 -8
  30. package/dist/core/migrations/runner.d.ts.map +0 -1
  31. package/dist/core/migrations/statement-builders.d.ts +0 -30
  32. package/dist/core/migrations/statement-builders.d.ts.map +0 -1
  33. package/dist/exports/control.d.ts +0 -8
  34. package/dist/exports/control.d.ts.map +0 -1
  35. package/dist/exports/control.js +0 -1260
  36. package/dist/exports/control.js.map +0 -1
  37. package/dist/exports/pack.d.ts +0 -4
  38. package/dist/exports/pack.d.ts.map +0 -1
  39. package/dist/exports/pack.js +0 -11
  40. package/dist/exports/pack.js.map +0 -1
  41. package/dist/exports/runtime.d.ts +0 -12
  42. package/dist/exports/runtime.d.ts.map +0 -1
  43. package/dist/exports/runtime.js +0 -19
  44. package/dist/exports/runtime.js.map +0 -1
@@ -1,5 +1,13 @@
1
+ import {
2
+ escapeLiteral,
3
+ expandParameterizedNativeType,
4
+ normalizeSchemaNativeType,
5
+ parsePostgresDefault,
6
+ quoteIdentifier,
7
+ } from '@prisma-next/adapter-postgres/control';
1
8
  import type { SchemaIssue } from '@prisma-next/core-control-plane/types';
2
9
  import type {
10
+ CodecControlHooks,
3
11
  MigrationOperationPolicy,
4
12
  SqlMigrationPlanner,
5
13
  SqlMigrationPlannerPlanOptions,
@@ -8,6 +16,7 @@ import type {
8
16
  } from '@prisma-next/family-sql/control';
9
17
  import {
10
18
  createMigrationPlan,
19
+ extractCodecControlHooks,
11
20
  plannerFailure,
12
21
  plannerSuccess,
13
22
  } from '@prisma-next/family-sql/control';
@@ -25,8 +34,10 @@ import type {
25
34
  StorageTable,
26
35
  } from '@prisma-next/sql-contract/types';
27
36
  import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
37
+ import { ifDefined } from '@prisma-next/utils/defined';
38
+ import type { PostgresColumnDefault } from '../types';
28
39
 
29
- type OperationClass = 'extension' | 'table' | 'unique' | 'index' | 'foreignKey';
40
+ type OperationClass = 'extension' | 'type' | 'table' | 'unique' | 'index' | 'foreignKey';
30
41
 
31
42
  type PlannerFrameworkComponents = SqlMigrationPlannerPlanOptions extends {
32
43
  readonly frameworkComponents: infer T;
@@ -88,11 +99,21 @@ class PostgresMigrationPlanner implements SqlMigrationPlanner<PostgresPlanTarget
88
99
  return plannerFailure(classification.conflicts);
89
100
  }
90
101
 
102
+ // Extract codec control hooks once at entry point for reuse across all operations.
103
+ // This avoids repeated iteration over frameworkComponents for each method that needs hooks.
104
+ const codecHooks = extractCodecControlHooks(options.frameworkComponents);
105
+
91
106
  const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];
92
107
 
108
+ const storageTypePlan = this.buildStorageTypeOperations(options, schemaName, codecHooks);
109
+ if (storageTypePlan.conflicts.length > 0) {
110
+ return plannerFailure(storageTypePlan.conflicts);
111
+ }
112
+
93
113
  // Build extension operations from component-owned database dependencies
94
114
  operations.push(
95
115
  ...this.buildDatabaseDependencyOperations(options),
116
+ ...storageTypePlan.operations,
96
117
  ...this.buildTableOperations(options.contract.storage.tables, options.schema, schemaName),
97
118
  ...this.buildColumnOperations(options.contract.storage.tables, options.schema, schemaName),
98
119
  ...this.buildPrimaryKeyOperations(
@@ -102,6 +123,11 @@ class PostgresMigrationPlanner implements SqlMigrationPlanner<PostgresPlanTarget
102
123
  ),
103
124
  ...this.buildUniqueOperations(options.contract.storage.tables, options.schema, schemaName),
104
125
  ...this.buildIndexOperations(options.contract.storage.tables, options.schema, schemaName),
126
+ ...this.buildFkBackingIndexOperations(
127
+ options.contract.storage.tables,
128
+ options.schema,
129
+ schemaName,
130
+ ),
105
131
  ...this.buildForeignKeyOperations(
106
132
  options.contract.storage.tables,
107
133
  options.schema,
@@ -113,8 +139,8 @@ class PostgresMigrationPlanner implements SqlMigrationPlanner<PostgresPlanTarget
113
139
  targetId: 'postgres',
114
140
  origin: null,
115
141
  destination: {
116
- coreHash: options.contract.coreHash,
117
- ...(options.contract.profileHash ? { profileHash: options.contract.profileHash } : {}),
142
+ storageHash: options.contract.storageHash,
143
+ ...ifDefined('profileHash', options.contract.profileHash),
118
144
  },
119
145
  operations,
120
146
  });
@@ -171,6 +197,55 @@ class PostgresMigrationPlanner implements SqlMigrationPlanner<PostgresPlanTarget
171
197
 
172
198
  return operations;
173
199
  }
200
+
201
+ private buildStorageTypeOperations(
202
+ options: PlannerOptionsWithComponents,
203
+ schemaName: string,
204
+ codecHooks: Map<string, CodecControlHooks>,
205
+ ): {
206
+ readonly operations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[];
207
+ readonly conflicts: readonly SqlPlannerConflict[];
208
+ } {
209
+ const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];
210
+ const conflicts: SqlPlannerConflict[] = [];
211
+ const storageTypes = options.contract.storage.types ?? {};
212
+
213
+ for (const [typeName, typeInstance] of sortedEntries(storageTypes)) {
214
+ const hook = codecHooks.get(typeInstance.codecId);
215
+ const planResult = hook?.planTypeOperations?.({
216
+ typeName,
217
+ typeInstance,
218
+ contract: options.contract,
219
+ schema: options.schema,
220
+ schemaName,
221
+ policy: options.policy,
222
+ });
223
+ if (!planResult) {
224
+ continue;
225
+ }
226
+ for (const operation of planResult.operations) {
227
+ if (!options.policy.allowedOperationClasses.includes(operation.operationClass)) {
228
+ conflicts.push({
229
+ kind: 'missingButNonAdditive',
230
+ summary: `Storage type "${typeName}" requires "${operation.operationClass}" operation "${operation.id}"`,
231
+ location: {
232
+ type: typeName,
233
+ },
234
+ });
235
+ continue;
236
+ }
237
+ operations.push({
238
+ ...operation,
239
+ target: {
240
+ id: operation.target.id,
241
+ details: this.buildTargetDetails('type', typeName, schemaName),
242
+ },
243
+ });
244
+ }
245
+ }
246
+
247
+ return { operations, conflicts };
248
+ }
174
249
  private collectDependencies(
175
250
  options: PlannerOptionsWithComponents,
176
251
  ): ReadonlyArray<PlannerDatabaseDependency> {
@@ -263,15 +338,20 @@ class PostgresMigrationPlanner implements SqlMigrationPlanner<PostgresPlanTarget
263
338
  ): SqlMigrationPlanOperation<PostgresPlanTargetDetails> {
264
339
  const qualified = qualifyTableName(schema, tableName);
265
340
  const notNull = column.nullable === false;
341
+ const hasDefault = column.default !== undefined;
342
+ // Only require empty table for NOT NULL columns WITHOUT defaults.
343
+ // PostgreSQL allows adding NOT NULL columns with defaults to non-empty tables
344
+ // because the default value is applied to existing rows.
345
+ const requiresEmptyTable = notNull && !hasDefault;
266
346
  const precheck = [
267
347
  {
268
348
  description: `ensure column "${columnName}" is missing`,
269
349
  sql: columnExistsCheck({ schema, table: tableName, column: columnName, exists: false }),
270
350
  },
271
- ...(notNull
351
+ ...(requiresEmptyTable
272
352
  ? [
273
353
  {
274
- description: `ensure table "${tableName}" is empty before adding NOT NULL column`,
354
+ description: `ensure table "${tableName}" is empty before adding NOT NULL column without default`,
275
355
  sql: tableIsEmptyCheck(qualified),
276
356
  },
277
357
  ]
@@ -459,6 +539,65 @@ UNIQUE (${unique.columns.map(quoteIdentifier).join(', ')})`,
459
539
  return operations;
460
540
  }
461
541
 
542
+ /**
543
+ * Generates FK-backing index operations for FKs with `index: true`,
544
+ * but only when no matching user-declared index exists in `contractTable.indexes`.
545
+ */
546
+ private buildFkBackingIndexOperations(
547
+ tables: SqlContract<SqlStorage>['storage']['tables'],
548
+ schema: SqlSchemaIR,
549
+ schemaName: string,
550
+ ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {
551
+ const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];
552
+ for (const [tableName, table] of sortedEntries(tables)) {
553
+ const schemaTable = schema.tables[tableName];
554
+ // Collect column sets of user-declared indexes to avoid duplicates
555
+ const declaredIndexColumns = new Set(table.indexes.map((idx) => idx.columns.join(',')));
556
+
557
+ for (const fk of table.foreignKeys) {
558
+ if (fk.index === false) continue;
559
+ // Skip if user already declared an index with these columns
560
+ if (declaredIndexColumns.has(fk.columns.join(','))) continue;
561
+ // Skip if the index already exists in the database
562
+ if (schemaTable && hasIndex(schemaTable, fk.columns)) continue;
563
+
564
+ const indexName = `${tableName}_${fk.columns.join('_')}_idx`;
565
+ operations.push({
566
+ id: `index.${tableName}.${indexName}`,
567
+ label: `Create FK-backing index ${indexName} on ${tableName}`,
568
+ summary: `Creates FK-backing index ${indexName} on ${tableName}`,
569
+ operationClass: 'additive',
570
+ target: {
571
+ id: 'postgres',
572
+ details: this.buildTargetDetails('index', indexName, schemaName, tableName),
573
+ },
574
+ precheck: [
575
+ {
576
+ description: `ensure index "${indexName}" is missing`,
577
+ sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NULL`,
578
+ },
579
+ ],
580
+ execute: [
581
+ {
582
+ description: `create FK-backing index "${indexName}"`,
583
+ sql: `CREATE INDEX ${quoteIdentifier(indexName)} ON ${qualifyTableName(
584
+ schemaName,
585
+ tableName,
586
+ )} (${fk.columns.map(quoteIdentifier).join(', ')})`,
587
+ },
588
+ ],
589
+ postcheck: [
590
+ {
591
+ description: `verify index "${indexName}" exists`,
592
+ sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NOT NULL`,
593
+ },
594
+ ],
595
+ });
596
+ }
597
+ }
598
+ return operations;
599
+ }
600
+
462
601
  private buildForeignKeyOperations(
463
602
  tables: SqlContract<SqlStorage>['storage']['tables'],
464
603
  schema: SqlSchemaIR,
@@ -468,6 +607,7 @@ UNIQUE (${unique.columns.map(quoteIdentifier).join(', ')})`,
468
607
  for (const [tableName, table] of sortedEntries(tables)) {
469
608
  const schemaTable = schema.tables[tableName];
470
609
  for (const foreignKey of table.foreignKeys) {
610
+ if (foreignKey.constraint === false) continue;
471
611
  if (schemaTable && hasForeignKey(schemaTable, foreignKey)) {
472
612
  continue;
473
613
  }
@@ -524,7 +664,7 @@ REFERENCES ${qualifyTableName(schemaName, foreignKey.references.table)} (${forei
524
664
  schema,
525
665
  objectType,
526
666
  name,
527
- ...(table ? { table } : {}),
667
+ ...ifDefined('table', table),
528
668
  };
529
669
  }
530
670
 
@@ -540,6 +680,8 @@ REFERENCES ${qualifyTableName(schemaName, foreignKey.references.table)} (${forei
540
680
  strict: false,
541
681
  typeMetadataRegistry: new Map(),
542
682
  frameworkComponents: options.frameworkComponents,
683
+ normalizeDefault: parsePostgresDefault,
684
+ normalizeNativeType: normalizeSchemaNativeType,
543
685
  };
544
686
  const verifyResult = verifySqlSchema(verifyOptions);
545
687
 
@@ -588,16 +730,16 @@ REFERENCES ${qualifyTableName(schemaName, foreignKey.references.table)} (${forei
588
730
  const meta =
589
731
  issue.expected || issue.actual
590
732
  ? Object.freeze({
591
- ...(issue.expected ? { expected: issue.expected } : {}),
592
- ...(issue.actual ? { actual: issue.actual } : {}),
733
+ ...ifDefined('expected', issue.expected),
734
+ ...ifDefined('actual', issue.actual),
593
735
  })
594
736
  : undefined;
595
737
 
596
738
  return {
597
739
  kind,
598
740
  summary: issue.message,
599
- ...(location ? { location } : {}),
600
- ...(meta ? { meta } : {}),
741
+ ...ifDefined('location', location),
742
+ ...ifDefined('meta', meta),
601
743
  };
602
744
  }
603
745
  }
@@ -638,7 +780,8 @@ function buildCreateTableSql(qualifiedTableName: string, table: StorageTable): s
638
780
  ([columnName, column]: [string, StorageColumn]) => {
639
781
  const parts = [
640
782
  quoteIdentifier(columnName),
641
- column.nativeType,
783
+ buildColumnTypeSql(column),
784
+ buildColumnDefaultSql(column.default),
642
785
  column.nullable ? '' : 'NOT NULL',
643
786
  ].filter(Boolean);
644
787
  return parts.join(' ');
@@ -656,6 +799,83 @@ function buildCreateTableSql(qualifiedTableName: string, table: StorageTable): s
656
799
  return `CREATE TABLE ${qualifiedTableName} (\n ${allDefinitions.join(',\n ')}\n)`;
657
800
  }
658
801
 
802
+ /**
803
+ * Builds the column type SQL, handling autoincrement as a special case.
804
+ * For autoincrement on int4/int8, we use SERIAL/BIGSERIAL types.
805
+ */
806
+ function buildColumnTypeSql(column: StorageColumn): string {
807
+ const columnDefault = column.default;
808
+
809
+ // For autoincrement, use SERIAL/BIGSERIAL types instead of int4/int8
810
+ if (columnDefault?.kind === 'function' && columnDefault.expression === 'autoincrement()') {
811
+ if (column.nativeType === 'int4' || column.nativeType === 'integer') {
812
+ return 'SERIAL';
813
+ }
814
+ if (column.nativeType === 'int8' || column.nativeType === 'bigint') {
815
+ return 'BIGSERIAL';
816
+ }
817
+ if (column.nativeType === 'int2' || column.nativeType === 'smallint') {
818
+ return 'SMALLSERIAL';
819
+ }
820
+ }
821
+
822
+ if (column.typeRef) {
823
+ return quoteIdentifier(column.nativeType);
824
+ }
825
+
826
+ return renderParameterizedTypeSql(column) ?? column.nativeType;
827
+ }
828
+
829
+ /**
830
+ * Renders parameterized type SQL for a column, returning null if no expansion is needed.
831
+ *
832
+ * Uses the shared expandParameterizedNativeType utility from the postgres adapter.
833
+ * Returns null when the column has no typeParams, allowing the caller to fall back
834
+ * to the base nativeType.
835
+ */
836
+ function renderParameterizedTypeSql(column: StorageColumn): string | null {
837
+ if (!column.typeParams) {
838
+ return null;
839
+ }
840
+
841
+ const expanded = expandParameterizedNativeType({
842
+ nativeType: column.nativeType,
843
+ codecId: column.codecId,
844
+ typeParams: column.typeParams,
845
+ });
846
+
847
+ // If no expansion happened (returned the same base type), return null
848
+ // so caller can decide whether to use nativeType directly
849
+ return expanded !== column.nativeType ? expanded : null;
850
+ }
851
+
852
+ /**
853
+ * Builds the DEFAULT clause for a column definition.
854
+ * Returns empty string if no default is defined.
855
+ *
856
+ * Note: autoincrement is handled specially via SERIAL types, so we skip it here.
857
+ */
858
+ function buildColumnDefaultSql(columnDefault: PostgresColumnDefault | undefined): string {
859
+ if (!columnDefault) {
860
+ return '';
861
+ }
862
+
863
+ switch (columnDefault.kind) {
864
+ case 'literal':
865
+ return `DEFAULT ${columnDefault.expression}`;
866
+ case 'function': {
867
+ // autoincrement is handled by SERIAL type, no explicit DEFAULT needed
868
+ if (columnDefault.expression === 'autoincrement()') {
869
+ return '';
870
+ }
871
+ return `DEFAULT ${columnDefault.expression}`;
872
+ }
873
+ case 'sequence':
874
+ // Sequence names use quoteIdentifier for safe identifier handling
875
+ return `DEFAULT nextval(${quoteIdentifier(columnDefault.name)}::regclass)`;
876
+ }
877
+ }
878
+
659
879
  function qualifyTableName(schema: string, table: string): string {
660
880
  return `${quoteIdentifier(schema)}.${quoteIdentifier(table)}`;
661
881
  }
@@ -665,16 +885,6 @@ function toRegclassLiteral(schema: string, name: string): string {
665
885
  return `'${escapeLiteral(regclass)}'`;
666
886
  }
667
887
 
668
- /** Escapes and quotes a SQL identifier (table, column, schema name). */
669
- function quoteIdentifier(identifier: string): string {
670
- // TypeScript enforces string type - no runtime check needed for internal callers
671
- return `"${identifier.replace(/"/g, '""')}"`;
672
- }
673
-
674
- function escapeLiteral(value: string): string {
675
- return value.replace(/'/g, "''");
676
- }
677
-
678
888
  function sortedEntries<V>(record: Readonly<Record<string, V>>): Array<[string, V]> {
679
889
  return Object.entries(record).sort(([a], [b]) => a.localeCompare(b)) as Array<[string, V]>;
680
890
  }
@@ -746,9 +956,12 @@ function buildAddColumnSql(
746
956
  columnName: string,
747
957
  column: StorageColumn,
748
958
  ): string {
959
+ const typeSql = buildColumnTypeSql(column);
960
+ const defaultSql = buildColumnDefaultSql(column.default);
749
961
  const parts = [
750
962
  `ALTER TABLE ${qualifiedTableName}`,
751
- `ADD COLUMN ${quoteIdentifier(columnName)} ${column.nativeType}`,
963
+ `ADD COLUMN ${quoteIdentifier(columnName)} ${typeSql}`,
964
+ defaultSql,
752
965
  column.nullable ? '' : 'NOT NULL',
753
966
  ].filter(Boolean);
754
967
  return parts.join(' ');
@@ -807,6 +1020,8 @@ function hasForeignKey(table: SqlSchemaIR['tables'][string], fk: ForeignKey): bo
807
1020
 
808
1021
  function isAdditiveIssue(issue: SchemaIssue): boolean {
809
1022
  switch (issue.kind) {
1023
+ case 'type_missing':
1024
+ case 'type_values_mismatch':
810
1025
  case 'missing_table':
811
1026
  case 'missing_column':
812
1027
  case 'extension_missing':
@@ -1,3 +1,7 @@
1
+ import {
2
+ normalizeSchemaNativeType,
3
+ parsePostgresDefault,
4
+ } from '@prisma-next/adapter-postgres/control';
1
5
  import type { ContractMarkerRecord } from '@prisma-next/contract/types';
2
6
  import type {
3
7
  MigrationOperationPolicy,
@@ -14,6 +18,7 @@ import { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';
14
18
  import { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';
15
19
  import { readMarker } from '@prisma-next/family-sql/verify';
16
20
  import { SqlQueryError } from '@prisma-next/sql-errors';
21
+ import { ifDefined } from '@prisma-next/utils/defined';
17
22
  import type { Result } from '@prisma-next/utils/result';
18
23
  import { ok, okVoid } from '@prisma-next/utils/result';
19
24
  import type { PostgresPlanTargetDetails } from './planner';
@@ -141,6 +146,8 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
141
146
  context: options.context ?? {},
142
147
  typeMetadataRegistry: this.family.typeMetadataRegistry,
143
148
  frameworkComponents: options.frameworkComponents,
149
+ normalizeDefault: parsePostgresDefault,
150
+ normalizeNativeType: normalizeSchemaNativeType,
144
151
  });
145
152
  if (!schemaVerifyResult.ok) {
146
153
  return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
@@ -371,13 +378,13 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
371
378
  return Object.freeze({
372
379
  id: operation.id,
373
380
  label: operation.label,
374
- ...(operation.summary ? { summary: operation.summary } : {}),
381
+ ...ifDefined('summary', operation.summary),
375
382
  operationClass: operation.operationClass,
376
383
  target: operation.target, // Already frozen from plan creation
377
384
  precheck: Object.freeze([]),
378
385
  execute: Object.freeze([]),
379
386
  postcheck: frozenPostcheck,
380
- ...(operation.meta || mergedMeta ? { meta: mergedMeta } : {}),
387
+ ...ifDefined('meta', operation.meta || mergedMeta ? mergedMeta : undefined),
381
388
  });
382
389
  }
383
390
 
@@ -388,7 +395,7 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
388
395
  if (!marker) {
389
396
  return false;
390
397
  }
391
- if (marker.coreHash !== plan.destination.coreHash) {
398
+ if (marker.storageHash !== plan.destination.storageHash) {
392
399
  return false;
393
400
  }
394
401
  if (plan.destination.profileHash && marker.profileHash !== plan.destination.profileHash) {
@@ -435,10 +442,10 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
435
442
  }
436
443
  return runnerFailure(
437
444
  'MARKER_ORIGIN_MISMATCH',
438
- `Existing contract marker (${marker.coreHash}) does not match plan origin (no marker expected).`,
445
+ `Existing contract marker (${marker.storageHash}) does not match plan origin (no marker expected).`,
439
446
  {
440
447
  meta: {
441
- markerCoreHash: marker.coreHash,
448
+ markerStorageHash: marker.storageHash,
442
449
  expectedOrigin: null,
443
450
  },
444
451
  },
@@ -448,22 +455,22 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
448
455
  if (!marker) {
449
456
  return runnerFailure(
450
457
  'MARKER_ORIGIN_MISMATCH',
451
- `Missing contract marker: expected origin core hash ${origin.coreHash}.`,
458
+ `Missing contract marker: expected origin storage hash ${origin.storageHash}.`,
452
459
  {
453
460
  meta: {
454
- expectedOriginCoreHash: origin.coreHash,
461
+ expectedOriginStorageHash: origin.storageHash,
455
462
  },
456
463
  },
457
464
  );
458
465
  }
459
- if (marker.coreHash !== origin.coreHash) {
466
+ if (marker.storageHash !== origin.storageHash) {
460
467
  return runnerFailure(
461
468
  'MARKER_ORIGIN_MISMATCH',
462
- `Existing contract marker (${marker.coreHash}) does not match plan origin (${origin.coreHash}).`,
469
+ `Existing contract marker (${marker.storageHash}) does not match plan origin (${origin.storageHash}).`,
463
470
  {
464
471
  meta: {
465
- markerCoreHash: marker.coreHash,
466
- expectedOriginCoreHash: origin.coreHash,
472
+ markerStorageHash: marker.storageHash,
473
+ expectedOriginStorageHash: origin.storageHash,
467
474
  },
468
475
  },
469
476
  );
@@ -487,14 +494,14 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
487
494
  destination: SqlMigrationPlanContractInfo,
488
495
  contract: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['destinationContract'],
489
496
  ): Result<void, SqlMigrationRunnerFailure> {
490
- if (destination.coreHash !== contract.coreHash) {
497
+ if (destination.storageHash !== contract.storageHash) {
491
498
  return runnerFailure(
492
499
  'DESTINATION_CONTRACT_MISMATCH',
493
- `Plan destination core hash (${destination.coreHash}) does not match provided contract core hash (${contract.coreHash}).`,
500
+ `Plan destination storage hash (${destination.storageHash}) does not match provided contract storage hash (${contract.storageHash}).`,
494
501
  {
495
502
  meta: {
496
- planCoreHash: destination.coreHash,
497
- contractCoreHash: contract.coreHash,
503
+ planStorageHash: destination.storageHash,
504
+ contractStorageHash: contract.storageHash,
498
505
  },
499
506
  },
500
507
  );
@@ -524,11 +531,11 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
524
531
  existingMarker: ContractMarkerRecord | null,
525
532
  ): Promise<void> {
526
533
  const writeStatements = buildWriteMarkerStatements({
527
- coreHash: options.plan.destination.coreHash,
534
+ storageHash: options.plan.destination.storageHash,
528
535
  profileHash:
529
536
  options.plan.destination.profileHash ??
530
537
  options.destinationContract.profileHash ??
531
- options.plan.destination.coreHash,
538
+ options.plan.destination.storageHash,
532
539
  contractJson: options.destinationContract,
533
540
  canonicalVersion: null,
534
541
  meta: {},
@@ -544,13 +551,13 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
544
551
  executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],
545
552
  ): Promise<void> {
546
553
  const ledgerStatement = buildLedgerInsertStatement({
547
- originCoreHash: existingMarker?.coreHash ?? null,
554
+ originStorageHash: existingMarker?.storageHash ?? null,
548
555
  originProfileHash: existingMarker?.profileHash ?? null,
549
- destinationCoreHash: options.plan.destination.coreHash,
556
+ destinationStorageHash: options.plan.destination.storageHash,
550
557
  destinationProfileHash:
551
558
  options.plan.destination.profileHash ??
552
559
  options.destinationContract.profileHash ??
553
- options.plan.destination.coreHash,
560
+ options.plan.destination.storageHash,
554
561
  contractJsonBefore: existingMarker?.contractJson ?? null,
555
562
  contractJsonAfter: options.destinationContract,
556
563
  operations: executedOperations,
@@ -38,7 +38,7 @@ export const ensureLedgerTableStatement: SqlStatement = {
38
38
  };
39
39
 
40
40
  export interface WriteMarkerInput {
41
- readonly coreHash: string;
41
+ readonly storageHash: string;
42
42
  readonly profileHash: string;
43
43
  readonly contractJson?: unknown;
44
44
  readonly canonicalVersion?: number | null;
@@ -52,7 +52,7 @@ export function buildWriteMarkerStatements(input: WriteMarkerInput): {
52
52
  } {
53
53
  const params: readonly unknown[] = [
54
54
  1,
55
- input.coreHash,
55
+ input.storageHash,
56
56
  input.profileHash,
57
57
  jsonParam(input.contractJson),
58
58
  input.canonicalVersion ?? null,
@@ -99,9 +99,9 @@ export function buildWriteMarkerStatements(input: WriteMarkerInput): {
99
99
  }
100
100
 
101
101
  export interface LedgerInsertInput {
102
- readonly originCoreHash?: string | null;
102
+ readonly originStorageHash?: string | null;
103
103
  readonly originProfileHash?: string | null;
104
- readonly destinationCoreHash: string;
104
+ readonly destinationStorageHash: string;
105
105
  readonly destinationProfileHash?: string | null;
106
106
  readonly contractJsonBefore?: unknown;
107
107
  readonly contractJsonAfter?: unknown;
@@ -128,9 +128,9 @@ export function buildLedgerInsertStatement(input: LedgerInsertInput): SqlStateme
128
128
  $7::jsonb
129
129
  )`,
130
130
  params: [
131
- input.originCoreHash ?? null,
131
+ input.originStorageHash ?? null,
132
132
  input.originProfileHash ?? null,
133
- input.destinationCoreHash,
133
+ input.destinationStorageHash,
134
134
  input.destinationProfileHash ?? null,
135
135
  jsonParam(input.contractJsonBefore),
136
136
  jsonParam(input.contractJsonAfter),
@@ -0,0 +1,5 @@
1
+ import type { ColumnDefault } from '@prisma-next/contract/types';
2
+
3
+ export type PostgresColumnDefault =
4
+ | ColumnDefault
5
+ | { readonly kind: 'sequence'; readonly name: string };
@@ -12,12 +12,10 @@ import type { PostgresPlanTargetDetails } from '../core/migrations/planner';
12
12
  import { createPostgresMigrationPlanner } from '../core/migrations/planner';
13
13
  import { createPostgresMigrationRunner } from '../core/migrations/runner';
14
14
 
15
- /**
16
- * Postgres target descriptor for CLI config.
17
- */
18
15
  const postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresPlanTargetDetails> =
19
16
  {
20
17
  ...postgresTargetDescriptorMeta,
18
+ operationSignatures: () => [],
21
19
  /**
22
20
  * Migrations capability for CLI to access planner/runner via core types.
23
21
  * The SQL-specific planner/runner types are compatible with the generic
@@ -1,23 +1,18 @@
1
- import type {
2
- RuntimeTargetDescriptor,
3
- RuntimeTargetInstance,
4
- } from '@prisma-next/core-execution-plane/types';
1
+ import type { RuntimeTargetInstance } from '@prisma-next/core-execution-plane/types';
2
+ import { createCodecRegistry } from '@prisma-next/sql-relational-core/ast';
3
+ import type { SqlRuntimeTargetDescriptor } from '@prisma-next/sql-runtime';
5
4
  import { postgresTargetDescriptorMeta } from '../core/descriptor-meta';
6
5
 
7
- /**
8
- * Postgres runtime target instance interface.
9
- */
10
6
  export interface PostgresRuntimeTargetInstance extends RuntimeTargetInstance<'sql', 'postgres'> {}
11
7
 
12
- /**
13
- * Postgres target descriptor for runtime plane.
14
- */
15
- const postgresRuntimeTargetDescriptor: RuntimeTargetDescriptor<
16
- 'sql',
8
+ const postgresRuntimeTargetDescriptor: SqlRuntimeTargetDescriptor<
17
9
  'postgres',
18
10
  PostgresRuntimeTargetInstance
19
11
  > = {
20
12
  ...postgresTargetDescriptorMeta,
13
+ codecs: () => createCodecRegistry(),
14
+ operationSignatures: () => [],
15
+ parameterizedCodecs: () => [],
21
16
  create(): PostgresRuntimeTargetInstance {
22
17
  return {
23
18
  familyId: 'sql',
@@ -1,14 +0,0 @@
1
- // src/core/descriptor-meta.ts
2
- var postgresTargetDescriptorMeta = {
3
- kind: "target",
4
- familyId: "sql",
5
- targetId: "postgres",
6
- id: "postgres",
7
- version: "0.0.1",
8
- capabilities: {}
9
- };
10
-
11
- export {
12
- postgresTargetDescriptorMeta
13
- };
14
- //# sourceMappingURL=chunk-RKEXRSSI.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/descriptor-meta.ts"],"sourcesContent":["export const postgresTargetDescriptorMeta = {\n kind: 'target',\n familyId: 'sql',\n targetId: 'postgres',\n id: 'postgres',\n version: '0.0.1',\n capabilities: {},\n} as const;\n"],"mappings":";AAAO,IAAM,+BAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,cAAc,CAAC;AACjB;","names":[]}
@@ -1,9 +0,0 @@
1
- export declare const postgresTargetDescriptorMeta: {
2
- readonly kind: "target";
3
- readonly familyId: "sql";
4
- readonly targetId: "postgres";
5
- readonly id: "postgres";
6
- readonly version: "0.0.1";
7
- readonly capabilities: {};
8
- };
9
- //# sourceMappingURL=descriptor-meta.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"descriptor-meta.d.ts","sourceRoot":"","sources":["../../src/core/descriptor-meta.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B;;;;;;;CAO/B,CAAC"}