@prisma-next/target-postgres 0.1.0-dev.19 → 0.1.0-dev.21

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.
package/README.md CHANGED
@@ -19,6 +19,7 @@ Provides the Postgres target descriptor (`SqlControlTargetDescriptor`) for CLI c
19
19
  - **Multi-Plane Support**: Provides both migration-plane (control) and runtime-plane entry points for the Postgres target
20
20
  - **Planner Factory**: Implements `createPlanner()` to create Postgres-specific migration planners
21
21
  - **Runner Factory**: Implements `createRunner()` to create Postgres-specific migration runners
22
+ - **Database Dependency Consumption**: The planner extracts database dependencies from the configured framework components (passed as `frameworkComponents`), verifies each dependency against the live schema, and only emits install operations when required. The runner reuses the same metadata for post-apply verification, so there are no hardcoded extension mappings—database dependencies stay component-owned.
22
23
 
23
24
  This package spans multiple planes:
24
25
  - **Migration plane** (`src/exports/control.ts`): Control plane entry point that exports `SqlControlTargetDescriptor` for config files
@@ -91,7 +92,7 @@ Both the planner and runner return structured results instead of throwing:
91
92
 
92
93
  **Planner** returns `PlannerResult` with either:
93
94
  - `kind: 'success'` with a `MigrationPlan`
94
- - `kind: 'failure'` with a list of `PlannerConflict` objects (e.g., `unsupportedExtension`, `unsupportedOperation`)
95
+ - `kind: 'failure'` with a list of `PlannerConflict` objects (e.g., `unsupportedOperation`, `policyViolation`)
95
96
 
96
97
  **Runner** returns `MigrationRunnerResult` (`Result<MigrationRunnerSuccessValue, MigrationRunnerFailure>`) with either:
97
98
  - `ok: true` with operation counts
@@ -10,13 +10,10 @@ import {
10
10
  plannerFailure,
11
11
  plannerSuccess
12
12
  } from "@prisma-next/family-sql/control";
13
+ import { arraysEqual, verifySqlSchema } from "@prisma-next/family-sql/schema-verify";
13
14
  var DEFAULT_PLANNER_CONFIG = {
14
15
  defaultSchema: "public"
15
16
  };
16
- var PG_EXTENSION_SQL = {
17
- pgvector: "CREATE EXTENSION IF NOT EXISTS vector"
18
- };
19
- var ADAPTER_LEVEL_EXTENSIONS = /* @__PURE__ */ new Set(["pg", "postgres"]);
20
17
  function createPostgresMigrationPlanner(config = {}) {
21
18
  return new PostgresMigrationPlanner({
22
19
  ...DEFAULT_PLANNER_CONFIG,
@@ -33,28 +30,27 @@ var PostgresMigrationPlanner = class {
33
30
  if (policyResult) {
34
31
  return policyResult;
35
32
  }
36
- const existingTables = Object.keys(options.schema.tables);
37
- if (existingTables.length > 0) {
38
- const tableList = existingTables.sort().join(", ");
39
- return plannerFailure([
40
- {
41
- kind: "unsupportedOperation",
42
- summary: `The Postgres migration planner currently supports only empty databases. Found ${existingTables.length} existing table(s): ${tableList}`,
43
- why: "Remove existing tables or use a future planner mode that handles subsets/supersets."
44
- }
45
- ]);
46
- }
47
- const extensionResult = this.validateExtensions(options.contract);
48
- if (extensionResult) {
49
- return extensionResult;
33
+ const classification = this.classifySchema(options);
34
+ if (classification.kind === "conflict") {
35
+ return plannerFailure(classification.conflicts);
50
36
  }
51
37
  const operations = [];
52
38
  operations.push(
53
- ...this.buildExtensionOperations(options.contract, schemaName),
54
- ...this.buildTableOperations(options.contract.storage.tables, schemaName),
55
- ...this.buildUniqueOperations(options.contract.storage.tables, schemaName),
56
- ...this.buildIndexOperations(options.contract.storage.tables, schemaName),
57
- ...this.buildForeignKeyOperations(options.contract.storage.tables, schemaName)
39
+ ...this.buildDatabaseDependencyOperations(options),
40
+ ...this.buildTableOperations(options.contract.storage.tables, options.schema, schemaName),
41
+ ...this.buildColumnOperations(options.contract.storage.tables, options.schema, schemaName),
42
+ ...this.buildPrimaryKeyOperations(
43
+ options.contract.storage.tables,
44
+ options.schema,
45
+ schemaName
46
+ ),
47
+ ...this.buildUniqueOperations(options.contract.storage.tables, options.schema, schemaName),
48
+ ...this.buildIndexOperations(options.contract.storage.tables, options.schema, schemaName),
49
+ ...this.buildForeignKeyOperations(
50
+ options.contract.storage.tables,
51
+ options.schema,
52
+ schemaName
53
+ )
58
54
  );
59
55
  const plan = createMigrationPlan({
60
56
  targetId: "postgres",
@@ -67,29 +63,6 @@ var PostgresMigrationPlanner = class {
67
63
  });
68
64
  return plannerSuccess(plan);
69
65
  }
70
- validateExtensions(contract) {
71
- const extensions = contract.extensions ?? {};
72
- const extensionNames = Object.keys(extensions);
73
- const databaseExtensions = extensionNames.filter(
74
- (extensionName) => !ADAPTER_LEVEL_EXTENSIONS.has(extensionName)
75
- );
76
- const unsupportedExtensions = databaseExtensions.filter(
77
- (extensionName) => !PG_EXTENSION_SQL[extensionName]
78
- );
79
- if (unsupportedExtensions.length > 0) {
80
- const supportedExtensions = Object.keys(PG_EXTENSION_SQL).join(", ");
81
- const unsupportedList = unsupportedExtensions.join(", ");
82
- return plannerFailure([
83
- {
84
- kind: "unsupportedExtension",
85
- summary: `Unsupported PostgreSQL extensions in contract: ${unsupportedList}`,
86
- why: `The Postgres migration planner currently only supports: ${supportedExtensions}. Extensions are defined in contract.extensions.`,
87
- location: { extension: unsupportedList }
88
- }
89
- ]);
90
- }
91
- return null;
92
- }
93
66
  ensureAdditivePolicy(policy) {
94
67
  if (!policy.allowedOperationClasses.includes("additive")) {
95
68
  return plannerFailure([
@@ -102,96 +75,204 @@ var PostgresMigrationPlanner = class {
102
75
  }
103
76
  return null;
104
77
  }
105
- buildExtensionOperations(contract, schema) {
106
- const extensions = contract.extensions ?? {};
107
- const extensionNames = Object.keys(extensions);
78
+ /**
79
+ * Builds migration operations from component-owned database dependencies.
80
+ * These operations install database-side persistence structures declared by components.
81
+ */
82
+ buildDatabaseDependencyOperations(options) {
83
+ const dependencies = this.collectDependencies(options);
108
84
  const operations = [];
109
- for (const extensionName of extensionNames) {
110
- if (ADAPTER_LEVEL_EXTENSIONS.has(extensionName)) {
85
+ const seenDependencyIds = /* @__PURE__ */ new Set();
86
+ const seenOperationIds = /* @__PURE__ */ new Set();
87
+ for (const dependency of dependencies) {
88
+ if (seenDependencyIds.has(dependency.id)) {
89
+ continue;
90
+ }
91
+ seenDependencyIds.add(dependency.id);
92
+ const issues = dependency.verifyDatabaseDependencyInstalled(options.schema);
93
+ if (issues.length === 0) {
111
94
  continue;
112
95
  }
113
- const sql = PG_EXTENSION_SQL[extensionName];
114
- if (!sql) {
115
- throw new Error(`Extension SQL not found for ${extensionName}`);
96
+ for (const installOp of dependency.install) {
97
+ if (seenOperationIds.has(installOp.id)) {
98
+ continue;
99
+ }
100
+ seenOperationIds.add(installOp.id);
101
+ operations.push(installOp);
116
102
  }
117
- const details = this.buildTargetDetails("extension", extensionName, schema);
103
+ }
104
+ return operations;
105
+ }
106
+ collectDependencies(options) {
107
+ const components = options.frameworkComponents;
108
+ if (components.length === 0) {
109
+ return [];
110
+ }
111
+ const deps = [];
112
+ for (const component of components) {
113
+ if (!isSqlDependencyProvider(component)) {
114
+ continue;
115
+ }
116
+ const initDeps = component.databaseDependencies?.init;
117
+ if (initDeps && initDeps.length > 0) {
118
+ deps.push(...initDeps);
119
+ }
120
+ }
121
+ return sortDependencies(deps);
122
+ }
123
+ buildTableOperations(tables, schema, schemaName) {
124
+ const operations = [];
125
+ for (const [tableName, table] of sortedEntries(tables)) {
126
+ if (schema.tables[tableName]) {
127
+ continue;
128
+ }
129
+ const qualified = qualifyTableName(schemaName, tableName);
118
130
  operations.push({
119
- id: `extension.${extensionName}`,
120
- label: `Enable extension "${extensionName}"`,
121
- summary: `Ensures the ${extensionName} extension is available`,
131
+ id: `table.${tableName}`,
132
+ label: `Create table ${tableName}`,
133
+ summary: `Creates table ${tableName} with required columns`,
122
134
  operationClass: "additive",
123
- target: { id: "postgres", details },
135
+ target: {
136
+ id: "postgres",
137
+ details: this.buildTargetDetails("table", tableName, schemaName)
138
+ },
124
139
  precheck: [
125
140
  {
126
- description: `verify extension "${extensionName}" is not already enabled`,
127
- sql: `SELECT NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = '${escapeLiteral(
128
- this.extensionDatabaseName(extensionName)
129
- )}')`
141
+ description: `ensure table "${tableName}" does not exist`,
142
+ sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NULL`
130
143
  }
131
144
  ],
132
145
  execute: [
133
146
  {
134
- description: `create extension "${extensionName}"`,
135
- sql
147
+ description: `create table "${tableName}"`,
148
+ sql: buildCreateTableSql(qualified, table)
136
149
  }
137
150
  ],
138
151
  postcheck: [
139
152
  {
140
- description: `confirm extension "${extensionName}" is enabled`,
141
- sql: `SELECT EXISTS (SELECT 1 FROM pg_extension WHERE extname = '${escapeLiteral(
142
- this.extensionDatabaseName(extensionName)
143
- )}')`
153
+ description: `verify table "${tableName}" exists`,
154
+ sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NOT NULL`
144
155
  }
145
156
  ]
146
157
  });
147
158
  }
148
159
  return operations;
149
160
  }
150
- extensionDatabaseName(extensionName) {
151
- if (extensionName === "pgvector") {
152
- return "vector";
161
+ buildColumnOperations(tables, schema, schemaName) {
162
+ const operations = [];
163
+ for (const [tableName, table] of sortedEntries(tables)) {
164
+ const schemaTable = schema.tables[tableName];
165
+ if (!schemaTable) {
166
+ continue;
167
+ }
168
+ for (const [columnName, column] of sortedEntries(table.columns)) {
169
+ if (schemaTable.columns[columnName]) {
170
+ continue;
171
+ }
172
+ operations.push(this.buildAddColumnOperation(schemaName, tableName, columnName, column));
173
+ }
153
174
  }
154
- return extensionName;
175
+ return operations;
176
+ }
177
+ buildAddColumnOperation(schema, tableName, columnName, column) {
178
+ const qualified = qualifyTableName(schema, tableName);
179
+ const notNull = column.nullable === false;
180
+ const precheck = [
181
+ {
182
+ description: `ensure column "${columnName}" is missing`,
183
+ sql: columnExistsCheck({ schema, table: tableName, column: columnName, exists: false })
184
+ },
185
+ ...notNull ? [
186
+ {
187
+ description: `ensure table "${tableName}" is empty before adding NOT NULL column`,
188
+ sql: tableIsEmptyCheck(qualified)
189
+ }
190
+ ] : []
191
+ ];
192
+ const execute = [
193
+ {
194
+ description: `add column "${columnName}"`,
195
+ sql: buildAddColumnSql(qualified, columnName, column)
196
+ }
197
+ ];
198
+ const postcheck = [
199
+ {
200
+ description: `verify column "${columnName}" exists`,
201
+ sql: columnExistsCheck({ schema, table: tableName, column: columnName })
202
+ },
203
+ ...notNull ? [
204
+ {
205
+ description: `verify column "${columnName}" is NOT NULL`,
206
+ sql: columnIsNotNullCheck({ schema, table: tableName, column: columnName })
207
+ }
208
+ ] : []
209
+ ];
210
+ return {
211
+ id: `column.${tableName}.${columnName}`,
212
+ label: `Add column ${columnName} to ${tableName}`,
213
+ summary: `Adds column ${columnName} to table ${tableName}`,
214
+ operationClass: "additive",
215
+ target: {
216
+ id: "postgres",
217
+ details: this.buildTargetDetails("table", tableName, schema)
218
+ },
219
+ precheck,
220
+ execute,
221
+ postcheck
222
+ };
155
223
  }
156
- buildTableOperations(tables, schema) {
224
+ buildPrimaryKeyOperations(tables, schema, schemaName) {
157
225
  const operations = [];
158
226
  for (const [tableName, table] of sortedEntries(tables)) {
159
- const qualified = qualifyTableName(schema, tableName);
227
+ if (!table.primaryKey) {
228
+ continue;
229
+ }
230
+ const schemaTable = schema.tables[tableName];
231
+ if (!schemaTable || schemaTable.primaryKey) {
232
+ continue;
233
+ }
234
+ const constraintName = table.primaryKey.name ?? `${tableName}_pkey`;
160
235
  operations.push({
161
- id: `table.${tableName}`,
162
- label: `Create table ${tableName}`,
163
- summary: `Creates table ${tableName} with required columns`,
236
+ id: `primaryKey.${tableName}.${constraintName}`,
237
+ label: `Add primary key ${constraintName} on ${tableName}`,
238
+ summary: `Adds primary key ${constraintName} on ${tableName}`,
164
239
  operationClass: "additive",
165
240
  target: {
166
241
  id: "postgres",
167
- details: this.buildTargetDetails("table", tableName, schema)
242
+ details: this.buildTargetDetails("table", tableName, schemaName)
168
243
  },
169
244
  precheck: [
170
245
  {
171
- description: `ensure table "${tableName}" does not exist`,
172
- sql: `SELECT to_regclass(${toRegclassLiteral(schema, tableName)}) IS NULL`
246
+ description: `ensure primary key does not exist on "${tableName}"`,
247
+ sql: tableHasPrimaryKeyCheck(schemaName, tableName, false)
173
248
  }
174
249
  ],
175
250
  execute: [
176
251
  {
177
- description: `create table "${tableName}"`,
178
- sql: buildCreateTableSql(qualified, table)
252
+ description: `add primary key "${constraintName}"`,
253
+ sql: `ALTER TABLE ${qualifyTableName(schemaName, tableName)}
254
+ ADD CONSTRAINT ${quoteIdentifier(constraintName)}
255
+ PRIMARY KEY (${table.primaryKey.columns.map(quoteIdentifier).join(", ")})`
179
256
  }
180
257
  ],
181
258
  postcheck: [
182
259
  {
183
- description: `verify table "${tableName}" exists`,
184
- sql: `SELECT to_regclass(${toRegclassLiteral(schema, tableName)}) IS NOT NULL`
260
+ description: `verify primary key "${constraintName}" exists`,
261
+ sql: tableHasPrimaryKeyCheck(schemaName, tableName, true, constraintName)
185
262
  }
186
263
  ]
187
264
  });
188
265
  }
189
266
  return operations;
190
267
  }
191
- buildUniqueOperations(tables, schema) {
268
+ buildUniqueOperations(tables, schema, schemaName) {
192
269
  const operations = [];
193
270
  for (const [tableName, table] of sortedEntries(tables)) {
271
+ const schemaTable = schema.tables[tableName];
194
272
  for (const unique of table.uniques) {
273
+ if (schemaTable && hasUniqueConstraint(schemaTable, unique.columns)) {
274
+ continue;
275
+ }
195
276
  const constraintName = unique.name ?? `${tableName}_${unique.columns.join("_")}_key`;
196
277
  operations.push({
197
278
  id: `unique.${tableName}.${constraintName}`,
@@ -200,18 +281,18 @@ var PostgresMigrationPlanner = class {
200
281
  operationClass: "additive",
201
282
  target: {
202
283
  id: "postgres",
203
- details: this.buildTargetDetails("unique", constraintName, schema, tableName)
284
+ details: this.buildTargetDetails("unique", constraintName, schemaName, tableName)
204
285
  },
205
286
  precheck: [
206
287
  {
207
288
  description: `ensure unique constraint "${constraintName}" is missing`,
208
- sql: constraintExistsCheck({ constraintName, schema, exists: false })
289
+ sql: constraintExistsCheck({ constraintName, schema: schemaName, exists: false })
209
290
  }
210
291
  ],
211
292
  execute: [
212
293
  {
213
294
  description: `add unique constraint "${constraintName}"`,
214
- sql: `ALTER TABLE ${qualifyTableName(schema, tableName)}
295
+ sql: `ALTER TABLE ${qualifyTableName(schemaName, tableName)}
215
296
  ADD CONSTRAINT ${quoteIdentifier(constraintName)}
216
297
  UNIQUE (${unique.columns.map(quoteIdentifier).join(", ")})`
217
298
  }
@@ -219,7 +300,7 @@ UNIQUE (${unique.columns.map(quoteIdentifier).join(", ")})`
219
300
  postcheck: [
220
301
  {
221
302
  description: `verify unique constraint "${constraintName}" exists`,
222
- sql: constraintExistsCheck({ constraintName, schema })
303
+ sql: constraintExistsCheck({ constraintName, schema: schemaName })
223
304
  }
224
305
  ]
225
306
  });
@@ -227,10 +308,14 @@ UNIQUE (${unique.columns.map(quoteIdentifier).join(", ")})`
227
308
  }
228
309
  return operations;
229
310
  }
230
- buildIndexOperations(tables, schema) {
311
+ buildIndexOperations(tables, schema, schemaName) {
231
312
  const operations = [];
232
313
  for (const [tableName, table] of sortedEntries(tables)) {
314
+ const schemaTable = schema.tables[tableName];
233
315
  for (const index of table.indexes) {
316
+ if (schemaTable && hasIndex(schemaTable, index.columns)) {
317
+ continue;
318
+ }
234
319
  const indexName = index.name ?? `${tableName}_${index.columns.join("_")}_idx`;
235
320
  operations.push({
236
321
  id: `index.${tableName}.${indexName}`,
@@ -239,19 +324,19 @@ UNIQUE (${unique.columns.map(quoteIdentifier).join(", ")})`
239
324
  operationClass: "additive",
240
325
  target: {
241
326
  id: "postgres",
242
- details: this.buildTargetDetails("index", indexName, schema, tableName)
327
+ details: this.buildTargetDetails("index", indexName, schemaName, tableName)
243
328
  },
244
329
  precheck: [
245
330
  {
246
331
  description: `ensure index "${indexName}" is missing`,
247
- sql: `SELECT to_regclass(${toRegclassLiteral(schema, indexName)}) IS NULL`
332
+ sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NULL`
248
333
  }
249
334
  ],
250
335
  execute: [
251
336
  {
252
337
  description: `create index "${indexName}"`,
253
338
  sql: `CREATE INDEX ${quoteIdentifier(indexName)} ON ${qualifyTableName(
254
- schema,
339
+ schemaName,
255
340
  tableName
256
341
  )} (${index.columns.map(quoteIdentifier).join(", ")})`
257
342
  }
@@ -259,7 +344,7 @@ UNIQUE (${unique.columns.map(quoteIdentifier).join(", ")})`
259
344
  postcheck: [
260
345
  {
261
346
  description: `verify index "${indexName}" exists`,
262
- sql: `SELECT to_regclass(${toRegclassLiteral(schema, indexName)}) IS NOT NULL`
347
+ sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NOT NULL`
263
348
  }
264
349
  ]
265
350
  });
@@ -267,10 +352,14 @@ UNIQUE (${unique.columns.map(quoteIdentifier).join(", ")})`
267
352
  }
268
353
  return operations;
269
354
  }
270
- buildForeignKeyOperations(tables, schema) {
355
+ buildForeignKeyOperations(tables, schema, schemaName) {
271
356
  const operations = [];
272
357
  for (const [tableName, table] of sortedEntries(tables)) {
358
+ const schemaTable = schema.tables[tableName];
273
359
  for (const foreignKey of table.foreignKeys) {
360
+ if (schemaTable && hasForeignKey(schemaTable, foreignKey)) {
361
+ continue;
362
+ }
274
363
  const fkName = foreignKey.name ?? `${tableName}_${foreignKey.columns.join("_")}_fkey`;
275
364
  operations.push({
276
365
  id: `foreignKey.${tableName}.${fkName}`,
@@ -279,27 +368,31 @@ UNIQUE (${unique.columns.map(quoteIdentifier).join(", ")})`
279
368
  operationClass: "additive",
280
369
  target: {
281
370
  id: "postgres",
282
- details: this.buildTargetDetails("foreignKey", fkName, schema, tableName)
371
+ details: this.buildTargetDetails("foreignKey", fkName, schemaName, tableName)
283
372
  },
284
373
  precheck: [
285
374
  {
286
375
  description: `ensure foreign key "${fkName}" is missing`,
287
- sql: constraintExistsCheck({ constraintName: fkName, schema, exists: false })
376
+ sql: constraintExistsCheck({
377
+ constraintName: fkName,
378
+ schema: schemaName,
379
+ exists: false
380
+ })
288
381
  }
289
382
  ],
290
383
  execute: [
291
384
  {
292
385
  description: `add foreign key "${fkName}"`,
293
- sql: `ALTER TABLE ${qualifyTableName(schema, tableName)}
386
+ sql: `ALTER TABLE ${qualifyTableName(schemaName, tableName)}
294
387
  ADD CONSTRAINT ${quoteIdentifier(fkName)}
295
388
  FOREIGN KEY (${foreignKey.columns.map(quoteIdentifier).join(", ")})
296
- REFERENCES ${qualifyTableName(schema, foreignKey.references.table)} (${foreignKey.references.columns.map(quoteIdentifier).join(", ")})`
389
+ REFERENCES ${qualifyTableName(schemaName, foreignKey.references.table)} (${foreignKey.references.columns.map(quoteIdentifier).join(", ")})`
297
390
  }
298
391
  ],
299
392
  postcheck: [
300
393
  {
301
394
  description: `verify foreign key "${fkName}" exists`,
302
- sql: constraintExistsCheck({ constraintName: fkName, schema })
395
+ sql: constraintExistsCheck({ constraintName: fkName, schema: schemaName })
303
396
  }
304
397
  ]
305
398
  });
@@ -315,7 +408,86 @@ REFERENCES ${qualifyTableName(schema, foreignKey.references.table)} (${foreignKe
315
408
  ...table ? { table } : {}
316
409
  };
317
410
  }
411
+ classifySchema(options) {
412
+ const verifyOptions = {
413
+ contract: options.contract,
414
+ schema: options.schema,
415
+ strict: false,
416
+ typeMetadataRegistry: /* @__PURE__ */ new Map(),
417
+ frameworkComponents: options.frameworkComponents
418
+ };
419
+ const verifyResult = verifySqlSchema(verifyOptions);
420
+ const conflicts = this.extractConflicts(verifyResult.schema.issues);
421
+ if (conflicts.length > 0) {
422
+ return { kind: "conflict", conflicts };
423
+ }
424
+ return { kind: "ok" };
425
+ }
426
+ extractConflicts(issues) {
427
+ const conflicts = [];
428
+ for (const issue of issues) {
429
+ if (isAdditiveIssue(issue)) {
430
+ continue;
431
+ }
432
+ const conflict = this.convertIssueToConflict(issue);
433
+ if (conflict) {
434
+ conflicts.push(conflict);
435
+ }
436
+ }
437
+ return conflicts.sort(conflictComparator);
438
+ }
439
+ convertIssueToConflict(issue) {
440
+ switch (issue.kind) {
441
+ case "type_mismatch":
442
+ return this.buildConflict("typeMismatch", issue);
443
+ case "nullability_mismatch":
444
+ return this.buildConflict("nullabilityConflict", issue);
445
+ case "primary_key_mismatch":
446
+ return this.buildConflict("indexIncompatible", issue);
447
+ case "unique_constraint_mismatch":
448
+ return this.buildConflict("indexIncompatible", issue);
449
+ case "index_mismatch":
450
+ return this.buildConflict("indexIncompatible", issue);
451
+ case "foreign_key_mismatch":
452
+ return this.buildConflict("foreignKeyConflict", issue);
453
+ default:
454
+ return null;
455
+ }
456
+ }
457
+ buildConflict(kind, issue) {
458
+ const location = buildConflictLocation(issue);
459
+ const meta = issue.expected || issue.actual ? Object.freeze({
460
+ ...issue.expected ? { expected: issue.expected } : {},
461
+ ...issue.actual ? { actual: issue.actual } : {}
462
+ }) : void 0;
463
+ return {
464
+ kind,
465
+ summary: issue.message,
466
+ ...location ? { location } : {},
467
+ ...meta ? { meta } : {}
468
+ };
469
+ }
318
470
  };
471
+ function isSqlDependencyProvider(component) {
472
+ if (typeof component !== "object" || component === null) {
473
+ return false;
474
+ }
475
+ const record = component;
476
+ if (Object.hasOwn(record, "familyId") && record["familyId"] !== "sql") {
477
+ return false;
478
+ }
479
+ if (!Object.hasOwn(record, "databaseDependencies")) {
480
+ return false;
481
+ }
482
+ const deps = record["databaseDependencies"];
483
+ return deps === void 0 || typeof deps === "object" && deps !== null;
484
+ }
485
+ function sortDependencies(dependencies) {
486
+ if (dependencies.length <= 1) {
487
+ return dependencies;
488
+ }
489
+ return [...dependencies].sort((a, b) => a.id.localeCompare(b.id));
490
+ }
319
491
  function buildCreateTableSql(qualifiedTableName, table) {
320
492
  const columnDefinitions = Object.entries(table.columns).map(
321
493
  ([columnName, column]) => {
@@ -367,10 +539,137 @@ function constraintExistsCheck({
367
539
  AND n.nspname = '${escapeLiteral(schema)}'
368
540
  )`;
369
541
  }
542
+ function columnExistsCheck({
543
+ schema,
544
+ table,
545
+ column,
546
+ exists = true
547
+ }) {
548
+ const existsClause = exists ? "" : "NOT ";
549
+ return `SELECT ${existsClause}EXISTS (
550
+ SELECT 1
551
+ FROM information_schema.columns
552
+ WHERE table_schema = '${escapeLiteral(schema)}'
553
+ AND table_name = '${escapeLiteral(table)}'
554
+ AND column_name = '${escapeLiteral(column)}'
555
+ )`;
556
+ }
557
+ function columnIsNotNullCheck({
558
+ schema,
559
+ table,
560
+ column
561
+ }) {
562
+ return `SELECT EXISTS (
563
+ SELECT 1
564
+ FROM information_schema.columns
565
+ WHERE table_schema = '${escapeLiteral(schema)}'
566
+ AND table_name = '${escapeLiteral(table)}'
567
+ AND column_name = '${escapeLiteral(column)}'
568
+ AND is_nullable = 'NO'
569
+ )`;
570
+ }
571
+ function tableIsEmptyCheck(qualifiedTableName) {
572
+ return `SELECT NOT EXISTS (SELECT 1 FROM ${qualifiedTableName} LIMIT 1)`;
573
+ }
574
+ function buildAddColumnSql(qualifiedTableName, columnName, column) {
575
+ const parts = [
576
+ `ALTER TABLE ${qualifiedTableName}`,
577
+ `ADD COLUMN ${quoteIdentifier(columnName)} ${column.nativeType}`,
578
+ column.nullable ? "" : "NOT NULL"
579
+ ].filter(Boolean);
580
+ return parts.join(" ");
581
+ }
582
+ function tableHasPrimaryKeyCheck(schema, table, exists, constraintName) {
583
+ const comparison = exists ? "" : "NOT ";
584
+ const constraintFilter = constraintName ? `AND c2.relname = '${escapeLiteral(constraintName)}'` : "";
585
+ return `SELECT ${comparison}EXISTS (
586
+ SELECT 1
587
+ FROM pg_index i
588
+ JOIN pg_class c ON c.oid = i.indrelid
589
+ JOIN pg_namespace n ON n.oid = c.relnamespace
590
+ LEFT JOIN pg_class c2 ON c2.oid = i.indexrelid
591
+ WHERE n.nspname = '${escapeLiteral(schema)}'
592
+ AND c.relname = '${escapeLiteral(table)}'
593
+ AND i.indisprimary
594
+ ${constraintFilter}
595
+ )`;
596
+ }
597
+ function hasUniqueConstraint(table, columns) {
598
+ return table.uniques.some((unique) => arraysEqual(unique.columns, columns));
599
+ }
600
+ function hasIndex(table, columns) {
601
+ return table.indexes.some((index) => !index.unique && arraysEqual(index.columns, columns));
602
+ }
603
+ function hasForeignKey(table, fk) {
604
+ return table.foreignKeys.some(
605
+ (candidate) => arraysEqual(candidate.columns, fk.columns) && candidate.referencedTable === fk.references.table && arraysEqual(candidate.referencedColumns, fk.references.columns)
606
+ );
607
+ }
608
+ function isAdditiveIssue(issue) {
609
+ switch (issue.kind) {
610
+ case "missing_table":
611
+ case "missing_column":
612
+ case "extension_missing":
613
+ return true;
614
+ case "primary_key_mismatch":
615
+ return issue.actual === void 0;
616
+ case "unique_constraint_mismatch":
617
+ case "index_mismatch":
618
+ case "foreign_key_mismatch":
619
+ return issue.indexOrConstraint === void 0;
620
+ default:
621
+ return false;
622
+ }
623
+ }
624
+ function buildConflictLocation(issue) {
625
+ const location = {};
626
+ if (issue.table) {
627
+ location.table = issue.table;
628
+ }
629
+ if (issue.column) {
630
+ location.column = issue.column;
631
+ }
632
+ if (issue.indexOrConstraint) {
633
+ location.constraint = issue.indexOrConstraint;
634
+ }
635
+ return Object.keys(location).length > 0 ? location : void 0;
636
+ }
637
+ function conflictComparator(a, b) {
638
+ if (a.kind !== b.kind) {
639
+ return a.kind < b.kind ? -1 : 1;
640
+ }
641
+ const aLocation = a.location ?? {};
642
+ const bLocation = b.location ?? {};
643
+ const tableCompare = compareStrings(aLocation.table, bLocation.table);
644
+ if (tableCompare !== 0) {
645
+ return tableCompare;
646
+ }
647
+ const columnCompare = compareStrings(aLocation.column, bLocation.column);
648
+ if (columnCompare !== 0) {
649
+ return columnCompare;
650
+ }
651
+ const constraintCompare = compareStrings(aLocation.constraint, bLocation.constraint);
652
+ if (constraintCompare !== 0) {
653
+ return constraintCompare;
654
+ }
655
+ return compareStrings(a.summary, b.summary);
656
+ }
657
+ function compareStrings(a, b) {
658
+ if (a === b) {
659
+ return 0;
660
+ }
661
+ if (a === void 0) {
662
+ return -1;
663
+ }
664
+ if (b === void 0) {
665
+ return 1;
666
+ }
667
+ return a < b ? -1 : 1;
668
+ }
370
669
 
371
670
  // src/core/migrations/runner.ts
372
671
  import { runnerFailure, runnerSuccess } from "@prisma-next/family-sql/control";
373
- import { verifySqlSchema } from "@prisma-next/family-sql/schema-verify";
672
+ import { verifySqlSchema as verifySqlSchema2 } from "@prisma-next/family-sql/schema-verify";
374
673
  import { readMarker } from "@prisma-next/family-sql/verify";
375
674
  import { ok, okVoid } from "@prisma-next/utils/result";
376
675
 
@@ -555,12 +854,13 @@ var PostgresMigrationRunner = class {
555
854
  driver,
556
855
  contractIR: options.destinationContract
557
856
  });
558
- const schemaVerifyResult = verifySqlSchema({
857
+ const schemaVerifyResult = verifySqlSchema2({
559
858
  contract: options.destinationContract,
560
859
  schema: schemaIR,
561
860
  strict: options.strictVerification ?? true,
562
861
  context: options.context ?? {},
563
- typeMetadataRegistry: this.family.typeMetadataRegistry
862
+ typeMetadataRegistry: this.family.typeMetadataRegistry,
863
+ frameworkComponents: options.frameworkComponents
564
864
  });
565
865
  if (!schemaVerifyResult.ok) {
566
866
  return runnerFailure("SCHEMA_VERIFY_FAILED", schemaVerifyResult.summary, {
@@ -935,6 +1235,8 @@ var postgresTargetDescriptor = {
935
1235
  manifest: loadTargetManifest(),
936
1236
  /**
937
1237
  * Migrations capability for CLI to access planner/runner via core types.
1238
+ * The SQL-specific planner/runner types are compatible with the generic
1239
+ * MigrationPlanner/MigrationRunner interfaces at runtime.
938
1240
  */
939
1241
  migrations: {
940
1242
  createPlanner(_family) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exports/control.ts","../../src/core/migrations/planner.ts","../../src/core/migrations/runner.ts","../../src/core/migrations/statement-builders.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { ExtensionPackManifest } from '@prisma-next/contract/pack-manifest-types';\nimport type { ControlTargetInstance } from '@prisma-next/core-control-plane/types';\nimport type {\n SqlControlFamilyInstance,\n SqlControlTargetDescriptor,\n} from '@prisma-next/family-sql/control';\nimport { type } from 'arktype';\nimport type { PostgresPlanTargetDetails } from '../core/migrations/planner';\nimport { createPostgresMigrationPlanner } from '../core/migrations/planner';\nimport { createPostgresMigrationRunner } from '../core/migrations/runner';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst TypesImportSpecSchema = type({\n package: 'string',\n named: 'string',\n alias: 'string',\n});\n\nconst ExtensionPackManifestSchema = type({\n id: 'string',\n version: 'string',\n 'targets?': type({ '[string]': type({ 'minVersion?': 'string' }) }),\n 'capabilities?': 'Record<string, unknown>',\n 'types?': type({\n 'codecTypes?': type({\n import: TypesImportSpecSchema,\n }),\n 'operationTypes?': type({\n import: TypesImportSpecSchema,\n }),\n }),\n 'operations?': 'unknown[]',\n});\n\n/**\n * Loads the target manifest from packs/manifest.json.\n */\nfunction loadTargetManifest(): ExtensionPackManifest {\n const manifestPath = join(__dirname, '../../packs/manifest.json');\n const manifestJson = JSON.parse(readFileSync(manifestPath, 'utf-8'));\n\n const result = ExtensionPackManifestSchema(manifestJson);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Invalid target manifest structure at ${manifestPath}: ${messages}`);\n }\n\n return result as ExtensionPackManifest;\n}\n\n/**\n * Postgres target descriptor for CLI config.\n */\nconst postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresPlanTargetDetails> =\n {\n kind: 'target',\n familyId: 'sql',\n targetId: 'postgres',\n id: 'postgres',\n manifest: loadTargetManifest(),\n /**\n * Migrations capability for CLI to access planner/runner via core types.\n */\n migrations: {\n createPlanner(_family: SqlControlFamilyInstance) {\n return createPostgresMigrationPlanner();\n },\n createRunner(family) {\n return createPostgresMigrationRunner(family);\n },\n },\n create(): ControlTargetInstance<'sql', 'postgres'> {\n return {\n familyId: 'sql',\n targetId: 'postgres',\n };\n },\n /**\n * Direct method for SQL-specific usage.\n * @deprecated Use migrations.createPlanner() for CLI compatibility.\n */\n createPlanner(_family: SqlControlFamilyInstance) {\n return createPostgresMigrationPlanner();\n },\n /**\n * Direct method for SQL-specific usage.\n * @deprecated Use migrations.createRunner() for CLI compatibility.\n */\n createRunner(family) {\n return createPostgresMigrationRunner(family);\n },\n };\n\nexport default postgresTargetDescriptor;\n","import type {\n MigrationOperationPolicy,\n SqlMigrationPlanner,\n SqlMigrationPlannerPlanOptions,\n SqlMigrationPlanOperation,\n} from '@prisma-next/family-sql/control';\nimport {\n createMigrationPlan,\n plannerFailure,\n plannerSuccess,\n} from '@prisma-next/family-sql/control';\nimport type {\n SqlContract,\n SqlStorage,\n StorageColumn,\n StorageTable,\n} from '@prisma-next/sql-contract/types';\n\ntype OperationClass = 'extension' | 'table' | 'unique' | 'index' | 'foreignKey';\n\nexport interface PostgresPlanTargetDetails {\n readonly schema: string;\n readonly objectType: OperationClass;\n readonly name: string;\n readonly table?: string;\n}\n\ninterface PlannerConfig {\n readonly defaultSchema: string;\n}\n\nconst DEFAULT_PLANNER_CONFIG: PlannerConfig = {\n defaultSchema: 'public',\n};\n\nconst PG_EXTENSION_SQL: Record<string, string> = {\n pgvector: 'CREATE EXTENSION IF NOT EXISTS vector',\n};\n\n/**\n * Adapter-level extensions that are NOT PostgreSQL database extensions.\n * These are metadata namespaces used by adapters for codec IDs (e.g., 'pg/int4@1').\n * The planner should skip these when validating extensions.\n */\nconst ADAPTER_LEVEL_EXTENSIONS = new Set(['pg', 'postgres']);\n\nexport function createPostgresMigrationPlanner(\n config: Partial<PlannerConfig> = {},\n): SqlMigrationPlanner<PostgresPlanTargetDetails> {\n return new PostgresMigrationPlanner({\n ...DEFAULT_PLANNER_CONFIG,\n ...config,\n });\n}\n\nclass PostgresMigrationPlanner implements SqlMigrationPlanner<PostgresPlanTargetDetails> {\n constructor(private readonly config: PlannerConfig) {}\n\n plan(options: SqlMigrationPlannerPlanOptions) {\n const schemaName = options.schemaName ?? this.config.defaultSchema;\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) {\n return policyResult;\n }\n\n const existingTables = Object.keys(options.schema.tables);\n if (existingTables.length > 0) {\n const tableList = existingTables.sort().join(', ');\n return plannerFailure([\n {\n kind: 'unsupportedOperation',\n summary: `The Postgres migration planner currently supports only empty databases. Found ${existingTables.length} existing table(s): ${tableList}`,\n why: 'Remove existing tables or use a future planner mode that handles subsets/supersets.',\n },\n ]);\n }\n\n const extensionResult = this.validateExtensions(options.contract);\n if (extensionResult) {\n return extensionResult;\n }\n\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n\n operations.push(\n ...this.buildExtensionOperations(options.contract, schemaName),\n ...this.buildTableOperations(options.contract.storage.tables, schemaName),\n ...this.buildUniqueOperations(options.contract.storage.tables, schemaName),\n ...this.buildIndexOperations(options.contract.storage.tables, schemaName),\n ...this.buildForeignKeyOperations(options.contract.storage.tables, schemaName),\n );\n\n const plan = createMigrationPlan<PostgresPlanTargetDetails>({\n targetId: 'postgres',\n origin: null,\n destination: {\n coreHash: options.contract.coreHash,\n ...(options.contract.profileHash ? { profileHash: options.contract.profileHash } : {}),\n },\n operations,\n });\n\n return plannerSuccess(plan);\n }\n\n private validateExtensions(contract: SqlContract<SqlStorage>) {\n const extensions = contract.extensions ?? {};\n const extensionNames = Object.keys(extensions);\n // Filter out adapter-level extensions (like 'pg', 'postgres') which are metadata namespaces\n // used by adapters for codec IDs, not PostgreSQL database extensions\n const databaseExtensions = extensionNames.filter(\n (extensionName) => !ADAPTER_LEVEL_EXTENSIONS.has(extensionName),\n );\n const unsupportedExtensions = databaseExtensions.filter(\n (extensionName) => !PG_EXTENSION_SQL[extensionName],\n );\n if (unsupportedExtensions.length > 0) {\n const supportedExtensions = Object.keys(PG_EXTENSION_SQL).join(', ');\n const unsupportedList = unsupportedExtensions.join(', ');\n return plannerFailure([\n {\n kind: 'unsupportedExtension' as const,\n summary: `Unsupported PostgreSQL extensions in contract: ${unsupportedList}`,\n why: `The Postgres migration planner currently only supports: ${supportedExtensions}. Extensions are defined in contract.extensions.`,\n location: { extension: unsupportedList },\n },\n ]);\n }\n return null;\n }\n\n private ensureAdditivePolicy(policy: MigrationOperationPolicy) {\n if (!policy.allowedOperationClasses.includes('additive')) {\n return plannerFailure([\n {\n kind: 'unsupportedOperation',\n summary: 'Init planner requires additive operations be allowed',\n why: 'The init planner only emits additive operations. Update the policy to include \"additive\".',\n },\n ]);\n }\n return null;\n }\n\n private buildExtensionOperations(\n contract: SqlContract<SqlStorage>,\n schema: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const extensions = contract.extensions ?? {};\n const extensionNames = Object.keys(extensions);\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n\n // Extensions are validated in validateExtensions() before this method is called\n for (const extensionName of extensionNames) {\n // Skip adapter-level extensions (metadata namespaces, not database extensions)\n if (ADAPTER_LEVEL_EXTENSIONS.has(extensionName)) {\n continue;\n }\n const sql = PG_EXTENSION_SQL[extensionName];\n if (!sql) {\n // This should never happen since we validate extensions in validateExtensions(), but TypeScript requires this check\n throw new Error(`Extension SQL not found for ${extensionName}`);\n }\n const details = this.buildTargetDetails('extension', extensionName, schema);\n operations.push({\n id: `extension.${extensionName}`,\n label: `Enable extension \"${extensionName}\"`,\n summary: `Ensures the ${extensionName} extension is available`,\n operationClass: 'additive',\n target: { id: 'postgres', details },\n precheck: [\n {\n description: `verify extension \"${extensionName}\" is not already enabled`,\n sql: `SELECT NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = '${escapeLiteral(\n this.extensionDatabaseName(extensionName),\n )}')`,\n },\n ],\n execute: [\n {\n description: `create extension \"${extensionName}\"`,\n sql,\n },\n ],\n postcheck: [\n {\n description: `confirm extension \"${extensionName}\" is enabled`,\n sql: `SELECT EXISTS (SELECT 1 FROM pg_extension WHERE extname = '${escapeLiteral(\n this.extensionDatabaseName(extensionName),\n )}')`,\n },\n ],\n });\n }\n\n return operations;\n }\n\n private extensionDatabaseName(extensionName: string): string {\n if (extensionName === 'pgvector') {\n return 'vector';\n }\n return extensionName;\n }\n\n private buildTableOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n const qualified = qualifyTableName(schema, tableName);\n operations.push({\n id: `table.${tableName}`,\n label: `Create table ${tableName}`,\n summary: `Creates table ${tableName} with required columns`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('table', tableName, schema),\n },\n precheck: [\n {\n description: `ensure table \"${tableName}\" does not exist`,\n sql: `SELECT to_regclass(${toRegclassLiteral(schema, tableName)}) IS NULL`,\n },\n ],\n execute: [\n {\n description: `create table \"${tableName}\"`,\n sql: buildCreateTableSql(qualified, table),\n },\n ],\n postcheck: [\n {\n description: `verify table \"${tableName}\" exists`,\n sql: `SELECT to_regclass(${toRegclassLiteral(schema, tableName)}) IS NOT NULL`,\n },\n ],\n });\n }\n return operations;\n }\n\n private buildUniqueOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n for (const unique of table.uniques) {\n const constraintName = unique.name ?? `${tableName}_${unique.columns.join('_')}_key`;\n operations.push({\n id: `unique.${tableName}.${constraintName}`,\n label: `Add unique constraint ${constraintName} on ${tableName}`,\n summary: `Adds unique constraint ${constraintName} on ${tableName}`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('unique', constraintName, schema, tableName),\n },\n precheck: [\n {\n description: `ensure unique constraint \"${constraintName}\" is missing`,\n sql: constraintExistsCheck({ constraintName, schema, exists: false }),\n },\n ],\n execute: [\n {\n description: `add unique constraint \"${constraintName}\"`,\n sql: `ALTER TABLE ${qualifyTableName(schema, tableName)}\nADD CONSTRAINT ${quoteIdentifier(constraintName)}\nUNIQUE (${unique.columns.map(quoteIdentifier).join(', ')})`,\n },\n ],\n postcheck: [\n {\n description: `verify unique constraint \"${constraintName}\" exists`,\n sql: constraintExistsCheck({ constraintName, schema }),\n },\n ],\n });\n }\n }\n return operations;\n }\n\n private buildIndexOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n for (const index of table.indexes) {\n const indexName = index.name ?? `${tableName}_${index.columns.join('_')}_idx`;\n operations.push({\n id: `index.${tableName}.${indexName}`,\n label: `Create index ${indexName} on ${tableName}`,\n summary: `Creates index ${indexName} on ${tableName}`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('index', indexName, schema, tableName),\n },\n precheck: [\n {\n description: `ensure index \"${indexName}\" is missing`,\n sql: `SELECT to_regclass(${toRegclassLiteral(schema, indexName)}) IS NULL`,\n },\n ],\n execute: [\n {\n description: `create index \"${indexName}\"`,\n sql: `CREATE INDEX ${quoteIdentifier(indexName)} ON ${qualifyTableName(\n schema,\n tableName,\n )} (${index.columns.map(quoteIdentifier).join(', ')})`,\n },\n ],\n postcheck: [\n {\n description: `verify index \"${indexName}\" exists`,\n sql: `SELECT to_regclass(${toRegclassLiteral(schema, indexName)}) IS NOT NULL`,\n },\n ],\n });\n }\n }\n return operations;\n }\n\n private buildForeignKeyOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n for (const foreignKey of table.foreignKeys) {\n const fkName = foreignKey.name ?? `${tableName}_${foreignKey.columns.join('_')}_fkey`;\n operations.push({\n id: `foreignKey.${tableName}.${fkName}`,\n label: `Add foreign key ${fkName} on ${tableName}`,\n summary: `Adds foreign key ${fkName} referencing ${foreignKey.references.table}`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('foreignKey', fkName, schema, tableName),\n },\n precheck: [\n {\n description: `ensure foreign key \"${fkName}\" is missing`,\n sql: constraintExistsCheck({ constraintName: fkName, schema, exists: false }),\n },\n ],\n execute: [\n {\n description: `add foreign key \"${fkName}\"`,\n sql: `ALTER TABLE ${qualifyTableName(schema, tableName)}\nADD CONSTRAINT ${quoteIdentifier(fkName)}\nFOREIGN KEY (${foreignKey.columns.map(quoteIdentifier).join(', ')})\nREFERENCES ${qualifyTableName(schema, foreignKey.references.table)} (${foreignKey.references.columns\n .map(quoteIdentifier)\n .join(', ')})`,\n },\n ],\n postcheck: [\n {\n description: `verify foreign key \"${fkName}\" exists`,\n sql: constraintExistsCheck({ constraintName: fkName, schema }),\n },\n ],\n });\n }\n }\n return operations;\n }\n\n private buildTargetDetails(\n objectType: OperationClass,\n name: string,\n schema: string,\n table?: string,\n ): PostgresPlanTargetDetails {\n return {\n schema,\n objectType,\n name,\n ...(table ? { table } : {}),\n };\n }\n}\n\nfunction buildCreateTableSql(qualifiedTableName: string, table: StorageTable): string {\n const columnDefinitions = Object.entries(table.columns).map(\n ([columnName, column]: [string, StorageColumn]) => {\n const parts = [\n quoteIdentifier(columnName),\n column.nativeType,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n },\n );\n\n const constraintDefinitions: string[] = [];\n if (table.primaryKey) {\n constraintDefinitions.push(\n `PRIMARY KEY (${table.primaryKey.columns.map(quoteIdentifier).join(', ')})`,\n );\n }\n\n const allDefinitions = [...columnDefinitions, ...constraintDefinitions];\n return `CREATE TABLE ${qualifiedTableName} (\\n ${allDefinitions.join(',\\n ')}\\n)`;\n}\n\nfunction qualifyTableName(schema: string, table: string): string {\n return `${quoteIdentifier(schema)}.${quoteIdentifier(table)}`;\n}\n\nfunction toRegclassLiteral(schema: string, name: string): string {\n const regclass = `${quoteIdentifier(schema)}.${quoteIdentifier(name)}`;\n return `'${escapeLiteral(regclass)}'`;\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction escapeLiteral(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\nfunction sortedEntries<V>(record: Readonly<Record<string, V>>): Array<[string, V]> {\n return Object.entries(record).sort(([a], [b]) => a.localeCompare(b)) as Array<[string, V]>;\n}\n\nfunction constraintExistsCheck({\n constraintName,\n schema,\n exists = true,\n}: {\n constraintName: string;\n schema: string;\n exists?: boolean;\n}): string {\n const existsClause = exists ? 'EXISTS' : 'NOT EXISTS';\n return `SELECT ${existsClause} (\n SELECT 1 FROM pg_constraint c\n JOIN pg_namespace n ON c.connamespace = n.oid\n WHERE c.conname = '${escapeLiteral(constraintName)}'\n AND n.nspname = '${escapeLiteral(schema)}'\n)`;\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlControlFamilyInstance,\n SqlMigrationPlanContractInfo,\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n SqlMigrationRunner,\n SqlMigrationRunnerExecuteOptions,\n SqlMigrationRunnerFailure,\n SqlMigrationRunnerResult,\n} from '@prisma-next/family-sql/control';\nimport { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport { readMarker } from '@prisma-next/family-sql/verify';\nimport type { Result } from '@prisma-next/utils/result';\nimport { ok, okVoid } from '@prisma-next/utils/result';\nimport type { PostgresPlanTargetDetails } from './planner';\nimport {\n buildLedgerInsertStatement,\n buildWriteMarkerStatements,\n ensureLedgerTableStatement,\n ensureMarkerTableStatement,\n ensurePrismaContractSchemaStatement,\n type SqlStatement,\n} from './statement-builders';\n\ninterface RunnerConfig {\n readonly defaultSchema: string;\n}\n\ninterface ApplyPlanSuccessValue {\n readonly operationsExecuted: number;\n readonly executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[];\n}\n\nconst DEFAULT_CONFIG: RunnerConfig = {\n defaultSchema: 'public',\n};\n\nconst LOCK_DOMAIN = 'prisma_next.contract.marker';\n\n/**\n * Deep clones and freezes a record object to prevent mutation.\n * Recursively clones nested objects and arrays to ensure complete isolation.\n */\nfunction cloneAndFreezeRecord<T extends Record<string, unknown>>(value: T): T {\n const cloned: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (val === null || val === undefined) {\n cloned[key] = val;\n } else if (Array.isArray(val)) {\n // Clone array (shallow clone of array elements)\n cloned[key] = Object.freeze([...val]);\n } else if (typeof val === 'object') {\n // Recursively clone nested objects\n cloned[key] = cloneAndFreezeRecord(val as Record<string, unknown>);\n } else {\n // Primitives are copied as-is\n cloned[key] = val;\n }\n }\n return Object.freeze(cloned) as T;\n}\n\nexport function createPostgresMigrationRunner(\n family: SqlControlFamilyInstance,\n config: Partial<RunnerConfig> = {},\n): SqlMigrationRunner<PostgresPlanTargetDetails> {\n return new PostgresMigrationRunner(family, { ...DEFAULT_CONFIG, ...config });\n}\n\nclass PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDetails> {\n constructor(\n private readonly family: SqlControlFamilyInstance,\n private readonly config: RunnerConfig,\n ) {}\n\n async execute(\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n ): Promise<SqlMigrationRunnerResult> {\n const schema = options.schemaName ?? this.config.defaultSchema;\n const driver = options.driver;\n const lockKey = `${LOCK_DOMAIN}:${schema}`;\n\n // Static checks - fail fast before transaction\n const destinationCheck = this.ensurePlanMatchesDestinationContract(\n options.plan.destination,\n options.destinationContract,\n );\n if (!destinationCheck.ok) {\n return destinationCheck;\n }\n\n const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);\n if (!policyCheck.ok) {\n return policyCheck;\n }\n\n // Begin transaction for DB operations\n await this.beginTransaction(driver);\n let committed = false;\n try {\n await this.acquireLock(driver, lockKey);\n await this.ensureControlTables(driver);\n const existingMarker = await readMarker(driver);\n\n // Validate plan origin matches existing marker (needs marker from DB)\n const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);\n if (!markerCheck.ok) {\n return markerCheck;\n }\n\n // Apply plan operations or skip if marker already at destination\n const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);\n let applyValue: ApplyPlanSuccessValue;\n\n if (markerAtDestination) {\n applyValue = { operationsExecuted: 0, executedOperations: [] };\n } else {\n const applyResult = await this.applyPlan(driver, options);\n if (!applyResult.ok) {\n return applyResult;\n }\n applyValue = applyResult.value;\n }\n\n // Verify resulting schema matches contract\n // Step 1: Introspect live schema (DB I/O, family-owned)\n const schemaIR = await this.family.introspect({\n driver,\n contractIR: options.destinationContract,\n });\n\n // Step 2: Pure verification (no DB I/O)\n const schemaVerifyResult = verifySqlSchema({\n contract: options.destinationContract,\n schema: schemaIR,\n strict: options.strictVerification ?? true,\n context: options.context ?? {},\n typeMetadataRegistry: this.family.typeMetadataRegistry,\n });\n if (!schemaVerifyResult.ok) {\n return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {\n why: 'The resulting database schema does not satisfy the destination contract.',\n meta: {\n issues: schemaVerifyResult.schema.issues,\n },\n });\n }\n\n // Record marker and ledger entries\n await this.upsertMarker(driver, options, existingMarker);\n await this.recordLedgerEntry(driver, options, existingMarker, applyValue.executedOperations);\n\n await this.commitTransaction(driver);\n committed = true;\n return runnerSuccess({\n operationsPlanned: options.plan.operations.length,\n operationsExecuted: applyValue.operationsExecuted,\n });\n } finally {\n if (!committed) {\n await this.rollbackTransaction(driver);\n }\n }\n }\n\n private async applyPlan(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n ): Promise<Result<ApplyPlanSuccessValue, SqlMigrationRunnerFailure>> {\n let operationsExecuted = 0;\n const executedOperations: Array<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> = [];\n for (const operation of options.plan.operations) {\n options.callbacks?.onOperationStart?.(operation);\n try {\n const postcheckAlreadySatisfied = await this.expectationsAreSatisfied(\n driver,\n operation.postcheck,\n );\n if (postcheckAlreadySatisfied) {\n executedOperations.push(this.createPostcheckPreSatisfiedSkipRecord(operation));\n continue;\n }\n\n const precheckResult = await this.runExpectationSteps(\n driver,\n operation.precheck,\n operation,\n 'precheck',\n );\n if (!precheckResult.ok) {\n return precheckResult;\n }\n\n const executeResult = await this.runExecuteSteps(driver, operation.execute, operation);\n if (!executeResult.ok) {\n return executeResult;\n }\n\n const postcheckResult = await this.runExpectationSteps(\n driver,\n operation.postcheck,\n operation,\n 'postcheck',\n );\n if (!postcheckResult.ok) {\n return postcheckResult;\n }\n\n executedOperations.push(operation);\n operationsExecuted += 1;\n } finally {\n options.callbacks?.onOperationComplete?.(operation);\n }\n }\n return ok({ operationsExecuted, executedOperations });\n }\n\n private async ensureControlTables(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await this.executeStatement(driver, ensurePrismaContractSchemaStatement);\n await this.executeStatement(driver, ensureMarkerTableStatement);\n await this.executeStatement(driver, ensureLedgerTableStatement);\n }\n\n private async runExpectationSteps(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n phase: 'precheck' | 'postcheck',\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n for (const step of steps) {\n const result = await driver.query(step.sql);\n if (!this.stepResultIsTrue(result.rows)) {\n const code = phase === 'precheck' ? 'PRECHECK_FAILED' : 'POSTCHECK_FAILED';\n return runnerFailure(\n code,\n `Operation ${operation.id} failed during ${phase}: ${step.description}`,\n {\n meta: {\n operationId: operation.id,\n phase,\n stepDescription: step.description,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private async runExecuteSteps(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n for (const step of steps) {\n try {\n await driver.query(step.sql);\n } catch (error) {\n return runnerFailure(\n 'EXECUTION_FAILED',\n `Operation ${operation.id} failed during execution: ${step.description}`,\n {\n why: error instanceof Error ? error.message : String(error),\n meta: {\n operationId: operation.id,\n stepDescription: step.description,\n sql: step.sql,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private stepResultIsTrue(rows: readonly Record<string, unknown>[]): boolean {\n if (!rows || rows.length === 0) {\n return false;\n }\n const firstRow = rows[0];\n const firstValue = firstRow ? Object.values(firstRow)[0] : undefined;\n if (typeof firstValue === 'boolean') {\n return firstValue;\n }\n if (typeof firstValue === 'number') {\n return firstValue !== 0;\n }\n if (typeof firstValue === 'string') {\n const lower = firstValue.toLowerCase();\n // PostgreSQL boolean representations: 't'/'f', 'true'/'false', '1'/'0'\n if (lower === 't' || lower === 'true' || lower === '1') {\n return true;\n }\n if (lower === 'f' || lower === 'false' || lower === '0') {\n return false;\n }\n // For other strings, non-empty is truthy (though this case shouldn't occur for boolean checks)\n return firstValue.length > 0;\n }\n return Boolean(firstValue);\n }\n\n private async expectationsAreSatisfied(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n ): Promise<boolean> {\n if (steps.length === 0) {\n return false;\n }\n for (const step of steps) {\n const result = await driver.query(step.sql);\n if (!this.stepResultIsTrue(result.rows)) {\n return false;\n }\n }\n return true;\n }\n\n private createPostcheckPreSatisfiedSkipRecord(\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n ): SqlMigrationPlanOperation<PostgresPlanTargetDetails> {\n // Clone and freeze existing meta if present\n const clonedMeta = operation.meta ? cloneAndFreezeRecord(operation.meta) : undefined;\n\n // Create frozen runner metadata\n const runnerMeta = Object.freeze({\n skipped: true,\n reason: 'postcheck_pre_satisfied',\n });\n\n // Merge and freeze the combined meta\n const mergedMeta = Object.freeze({\n ...(clonedMeta ?? {}),\n runner: runnerMeta,\n });\n\n // Clone and freeze arrays to prevent mutation\n const frozenPostcheck = Object.freeze([...operation.postcheck]);\n\n return Object.freeze({\n id: operation.id,\n label: operation.label,\n ...(operation.summary ? { summary: operation.summary } : {}),\n operationClass: operation.operationClass,\n target: operation.target, // Already frozen from plan creation\n precheck: Object.freeze([]),\n execute: Object.freeze([]),\n postcheck: frozenPostcheck,\n ...(operation.meta || mergedMeta ? { meta: mergedMeta } : {}),\n });\n }\n\n private markerMatchesDestination(\n marker: ContractMarkerRecord | null,\n plan: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['plan'],\n ): boolean {\n if (!marker) {\n return false;\n }\n if (marker.coreHash !== plan.destination.coreHash) {\n return false;\n }\n if (plan.destination.profileHash && marker.profileHash !== plan.destination.profileHash) {\n return false;\n }\n return true;\n }\n\n private enforcePolicyCompatibility(\n policy: MigrationOperationPolicy,\n operations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],\n ): Result<void, SqlMigrationRunnerFailure> {\n const allowedClasses = new Set(policy.allowedOperationClasses);\n for (const operation of operations) {\n if (!allowedClasses.has(operation.operationClass)) {\n return runnerFailure(\n 'POLICY_VIOLATION',\n `Operation ${operation.id} has class \"${operation.operationClass}\" which is not allowed by policy.`,\n {\n why: `Policy only allows: ${policy.allowedOperationClasses.join(', ')}.`,\n meta: {\n operationId: operation.id,\n operationClass: operation.operationClass,\n allowedClasses: policy.allowedOperationClasses,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private ensureMarkerCompatibility(\n marker: ContractMarkerRecord | null,\n plan: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['plan'],\n ): Result<void, SqlMigrationRunnerFailure> {\n const origin = plan.origin ?? null;\n if (!origin) {\n if (!marker) {\n return okVoid();\n }\n if (this.markerMatchesDestination(marker, plan)) {\n return okVoid();\n }\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.coreHash}) does not match plan origin (no marker expected).`,\n {\n meta: {\n markerCoreHash: marker.coreHash,\n expectedOrigin: null,\n },\n },\n );\n }\n\n if (!marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Missing contract marker: expected origin core hash ${origin.coreHash}.`,\n {\n meta: {\n expectedOriginCoreHash: origin.coreHash,\n },\n },\n );\n }\n if (marker.coreHash !== origin.coreHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.coreHash}) does not match plan origin (${origin.coreHash}).`,\n {\n meta: {\n markerCoreHash: marker.coreHash,\n expectedOriginCoreHash: origin.coreHash,\n },\n },\n );\n }\n if (origin.profileHash && marker.profileHash !== origin.profileHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker profile hash (${marker.profileHash}) does not match plan origin profile hash (${origin.profileHash}).`,\n {\n meta: {\n markerProfileHash: marker.profileHash,\n expectedOriginProfileHash: origin.profileHash,\n },\n },\n );\n }\n return okVoid();\n }\n\n private ensurePlanMatchesDestinationContract(\n destination: SqlMigrationPlanContractInfo,\n contract: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['destinationContract'],\n ): Result<void, SqlMigrationRunnerFailure> {\n if (destination.coreHash !== contract.coreHash) {\n return runnerFailure(\n 'DESTINATION_CONTRACT_MISMATCH',\n `Plan destination core hash (${destination.coreHash}) does not match provided contract core hash (${contract.coreHash}).`,\n {\n meta: {\n planCoreHash: destination.coreHash,\n contractCoreHash: contract.coreHash,\n },\n },\n );\n }\n if (\n destination.profileHash &&\n contract.profileHash &&\n destination.profileHash !== contract.profileHash\n ) {\n return runnerFailure(\n 'DESTINATION_CONTRACT_MISMATCH',\n `Plan destination profile hash (${destination.profileHash}) does not match provided contract profile hash (${contract.profileHash}).`,\n {\n meta: {\n planProfileHash: destination.profileHash,\n contractProfileHash: contract.profileHash,\n },\n },\n );\n }\n return okVoid();\n }\n\n private async upsertMarker(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n existingMarker: ContractMarkerRecord | null,\n ): Promise<void> {\n const writeStatements = buildWriteMarkerStatements({\n coreHash: options.plan.destination.coreHash,\n profileHash:\n options.plan.destination.profileHash ??\n options.destinationContract.profileHash ??\n options.plan.destination.coreHash,\n contractJson: options.destinationContract,\n canonicalVersion: null,\n meta: {},\n });\n const statement = existingMarker ? writeStatements.update : writeStatements.insert;\n await this.executeStatement(driver, statement);\n }\n\n private async recordLedgerEntry(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n existingMarker: ContractMarkerRecord | null,\n executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],\n ): Promise<void> {\n const ledgerStatement = buildLedgerInsertStatement({\n originCoreHash: existingMarker?.coreHash ?? null,\n originProfileHash: existingMarker?.profileHash ?? null,\n destinationCoreHash: options.plan.destination.coreHash,\n destinationProfileHash:\n options.plan.destination.profileHash ??\n options.destinationContract.profileHash ??\n options.plan.destination.coreHash,\n contractJsonBefore: existingMarker?.contractJson ?? null,\n contractJsonAfter: options.destinationContract,\n operations: executedOperations,\n });\n await this.executeStatement(driver, ledgerStatement);\n }\n\n private async acquireLock(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n key: string,\n ): Promise<void> {\n await driver.query('select pg_advisory_xact_lock(hashtext($1))', [key]);\n }\n\n private async beginTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('BEGIN');\n }\n\n private async commitTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('COMMIT');\n }\n\n private async rollbackTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('ROLLBACK');\n }\n\n private async executeStatement(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n statement: SqlStatement,\n ): Promise<void> {\n if (statement.params.length > 0) {\n await driver.query(statement.sql, statement.params);\n return;\n }\n await driver.query(statement.sql);\n }\n}\n","export interface SqlStatement {\n readonly sql: string;\n readonly params: readonly unknown[];\n}\n\nexport const ensurePrismaContractSchemaStatement: SqlStatement = {\n sql: 'create schema if not exists prisma_contract',\n params: [],\n};\n\nexport const ensureMarkerTableStatement: SqlStatement = {\n sql: `create table if not exists prisma_contract.marker (\n id smallint primary key default 1,\n core_hash text not null,\n profile_hash text not null,\n contract_json jsonb,\n canonical_version int,\n updated_at timestamptz not null default now(),\n app_tag text,\n meta jsonb not null default '{}'\n )`,\n params: [],\n};\n\nexport const ensureLedgerTableStatement: SqlStatement = {\n sql: `create table if not exists prisma_contract.ledger (\n id bigserial primary key,\n created_at timestamptz not null default now(),\n origin_core_hash text,\n origin_profile_hash text,\n destination_core_hash text not null,\n destination_profile_hash text,\n contract_json_before jsonb,\n contract_json_after jsonb,\n operations jsonb not null\n )`,\n params: [],\n};\n\nexport interface WriteMarkerInput {\n readonly coreHash: string;\n readonly profileHash: string;\n readonly contractJson?: unknown;\n readonly canonicalVersion?: number | null;\n readonly appTag?: string | null;\n readonly meta?: Record<string, unknown>;\n}\n\nexport function buildWriteMarkerStatements(input: WriteMarkerInput): {\n readonly insert: SqlStatement;\n readonly update: SqlStatement;\n} {\n const params: readonly unknown[] = [\n 1,\n input.coreHash,\n input.profileHash,\n jsonParam(input.contractJson),\n input.canonicalVersion ?? null,\n input.appTag ?? null,\n jsonParam(input.meta ?? {}),\n ];\n\n return {\n insert: {\n sql: `insert into prisma_contract.marker (\n id,\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta\n ) values (\n $1,\n $2,\n $3,\n $4::jsonb,\n $5,\n now(),\n $6,\n $7::jsonb\n )`,\n params,\n },\n update: {\n sql: `update prisma_contract.marker set\n core_hash = $2,\n profile_hash = $3,\n contract_json = $4::jsonb,\n canonical_version = $5,\n updated_at = now(),\n app_tag = $6,\n meta = $7::jsonb\n where id = $1`,\n params,\n },\n };\n}\n\nexport interface LedgerInsertInput {\n readonly originCoreHash?: string | null;\n readonly originProfileHash?: string | null;\n readonly destinationCoreHash: string;\n readonly destinationProfileHash?: string | null;\n readonly contractJsonBefore?: unknown;\n readonly contractJsonAfter?: unknown;\n readonly operations: unknown;\n}\n\nexport function buildLedgerInsertStatement(input: LedgerInsertInput): SqlStatement {\n return {\n sql: `insert into prisma_contract.ledger (\n origin_core_hash,\n origin_profile_hash,\n destination_core_hash,\n destination_profile_hash,\n contract_json_before,\n contract_json_after,\n operations\n ) values (\n $1,\n $2,\n $3,\n $4,\n $5::jsonb,\n $6::jsonb,\n $7::jsonb\n )`,\n params: [\n input.originCoreHash ?? null,\n input.originProfileHash ?? null,\n input.destinationCoreHash,\n input.destinationProfileHash ?? null,\n jsonParam(input.contractJsonBefore),\n jsonParam(input.contractJsonAfter),\n jsonParam(input.operations),\n ],\n };\n}\n\nfunction jsonParam(value: unknown): string {\n return JSON.stringify(value ?? null);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/exports/control.ts","../../src/core/migrations/planner.ts","../../src/core/migrations/runner.ts","../../src/core/migrations/statement-builders.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { ExtensionPackManifest } from '@prisma-next/contract/pack-manifest-types';\nimport type {\n ControlTargetInstance,\n MigrationPlanner,\n MigrationRunner,\n} from '@prisma-next/core-control-plane/types';\nimport type {\n SqlControlFamilyInstance,\n SqlControlTargetDescriptor,\n} from '@prisma-next/family-sql/control';\nimport { type } from 'arktype';\nimport type { PostgresPlanTargetDetails } from '../core/migrations/planner';\nimport { createPostgresMigrationPlanner } from '../core/migrations/planner';\nimport { createPostgresMigrationRunner } from '../core/migrations/runner';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst TypesImportSpecSchema = type({\n package: 'string',\n named: 'string',\n alias: 'string',\n});\n\nconst ExtensionPackManifestSchema = type({\n id: 'string',\n version: 'string',\n 'targets?': type({ '[string]': type({ 'minVersion?': 'string' }) }),\n 'capabilities?': 'Record<string, unknown>',\n 'types?': type({\n 'codecTypes?': type({\n import: TypesImportSpecSchema,\n }),\n 'operationTypes?': type({\n import: TypesImportSpecSchema,\n }),\n }),\n 'operations?': 'unknown[]',\n});\n\n/**\n * Loads the target manifest from packs/manifest.json.\n */\nfunction loadTargetManifest(): ExtensionPackManifest {\n const manifestPath = join(__dirname, '../../packs/manifest.json');\n const manifestJson = JSON.parse(readFileSync(manifestPath, 'utf-8'));\n\n const result = ExtensionPackManifestSchema(manifestJson);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Invalid target manifest structure at ${manifestPath}: ${messages}`);\n }\n\n return result as ExtensionPackManifest;\n}\n\n/**\n * Postgres target descriptor for CLI config.\n */\nconst postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresPlanTargetDetails> =\n {\n kind: 'target',\n familyId: 'sql',\n targetId: 'postgres',\n id: 'postgres',\n manifest: loadTargetManifest(),\n /**\n * Migrations capability for CLI to access planner/runner via core types.\n * The SQL-specific planner/runner types are compatible with the generic\n * MigrationPlanner/MigrationRunner interfaces at runtime.\n */\n migrations: {\n createPlanner(_family: SqlControlFamilyInstance) {\n return createPostgresMigrationPlanner() as MigrationPlanner<'sql', 'postgres'>;\n },\n createRunner(family) {\n return createPostgresMigrationRunner(family) as MigrationRunner<'sql', 'postgres'>;\n },\n },\n create(): ControlTargetInstance<'sql', 'postgres'> {\n return {\n familyId: 'sql',\n targetId: 'postgres',\n };\n },\n /**\n * Direct method for SQL-specific usage.\n * @deprecated Use migrations.createPlanner() for CLI compatibility.\n */\n createPlanner(_family: SqlControlFamilyInstance) {\n return createPostgresMigrationPlanner();\n },\n /**\n * Direct method for SQL-specific usage.\n * @deprecated Use migrations.createRunner() for CLI compatibility.\n */\n createRunner(family) {\n return createPostgresMigrationRunner(family);\n },\n };\n\nexport default postgresTargetDescriptor;\n","import type { SchemaIssue } from '@prisma-next/core-control-plane/types';\nimport type {\n MigrationOperationPolicy,\n SqlMigrationPlanner,\n SqlMigrationPlannerPlanOptions,\n SqlMigrationPlanOperation,\n SqlPlannerConflict,\n} from '@prisma-next/family-sql/control';\nimport {\n createMigrationPlan,\n plannerFailure,\n plannerSuccess,\n} from '@prisma-next/family-sql/control';\nimport { arraysEqual, verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport type {\n ForeignKey,\n SqlContract,\n SqlStorage,\n StorageColumn,\n StorageTable,\n} from '@prisma-next/sql-contract/types';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\n\ntype OperationClass = 'extension' | 'table' | 'unique' | 'index' | 'foreignKey';\n\ntype PlannerFrameworkComponents = SqlMigrationPlannerPlanOptions extends {\n readonly frameworkComponents: infer T;\n}\n ? T\n : ReadonlyArray<unknown>;\n\ntype PlannerOptionsWithComponents = SqlMigrationPlannerPlanOptions & {\n readonly frameworkComponents: PlannerFrameworkComponents;\n};\n\ntype VerifySqlSchemaOptionsWithComponents = Parameters<typeof verifySqlSchema>[0] & {\n readonly frameworkComponents: PlannerFrameworkComponents;\n};\n\ntype PlannerDatabaseDependency = {\n readonly id: string;\n readonly label: string;\n readonly install: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[];\n readonly verifyDatabaseDependencyInstalled: (schema: SqlSchemaIR) => readonly SchemaIssue[];\n};\n\nexport interface PostgresPlanTargetDetails {\n readonly schema: string;\n readonly objectType: OperationClass;\n readonly name: string;\n readonly table?: string;\n}\n\ninterface PlannerConfig {\n readonly defaultSchema: string;\n}\n\nconst DEFAULT_PLANNER_CONFIG: PlannerConfig = {\n defaultSchema: 'public',\n};\n\nexport function createPostgresMigrationPlanner(\n config: Partial<PlannerConfig> = {},\n): SqlMigrationPlanner<PostgresPlanTargetDetails> {\n return new PostgresMigrationPlanner({\n ...DEFAULT_PLANNER_CONFIG,\n ...config,\n });\n}\n\nclass PostgresMigrationPlanner implements SqlMigrationPlanner<PostgresPlanTargetDetails> {\n constructor(private readonly config: PlannerConfig) {}\n\n plan(options: SqlMigrationPlannerPlanOptions) {\n const schemaName = options.schemaName ?? this.config.defaultSchema;\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) {\n return policyResult;\n }\n\n const classification = this.classifySchema(options);\n if (classification.kind === 'conflict') {\n return plannerFailure(classification.conflicts);\n }\n\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n\n // Build extension operations from component-owned database dependencies\n operations.push(\n ...this.buildDatabaseDependencyOperations(options),\n ...this.buildTableOperations(options.contract.storage.tables, options.schema, schemaName),\n ...this.buildColumnOperations(options.contract.storage.tables, options.schema, schemaName),\n ...this.buildPrimaryKeyOperations(\n options.contract.storage.tables,\n options.schema,\n schemaName,\n ),\n ...this.buildUniqueOperations(options.contract.storage.tables, options.schema, schemaName),\n ...this.buildIndexOperations(options.contract.storage.tables, options.schema, schemaName),\n ...this.buildForeignKeyOperations(\n options.contract.storage.tables,\n options.schema,\n schemaName,\n ),\n );\n\n const plan = createMigrationPlan<PostgresPlanTargetDetails>({\n targetId: 'postgres',\n origin: null,\n destination: {\n coreHash: options.contract.coreHash,\n ...(options.contract.profileHash ? { profileHash: options.contract.profileHash } : {}),\n },\n operations,\n });\n\n return plannerSuccess(plan);\n }\n\n private ensureAdditivePolicy(policy: MigrationOperationPolicy) {\n if (!policy.allowedOperationClasses.includes('additive')) {\n return plannerFailure([\n {\n kind: 'unsupportedOperation',\n summary: 'Init planner requires additive operations be allowed',\n why: 'The init planner only emits additive operations. Update the policy to include \"additive\".',\n },\n ]);\n }\n return null;\n }\n\n /**\n * Builds migration operations from component-owned database dependencies.\n * These operations install database-side persistence structures declared by components.\n */\n private buildDatabaseDependencyOperations(\n options: PlannerOptionsWithComponents,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const dependencies = this.collectDependencies(options);\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n const seenDependencyIds = new Set<string>();\n const seenOperationIds = new Set<string>();\n\n for (const dependency of dependencies) {\n if (seenDependencyIds.has(dependency.id)) {\n continue;\n }\n seenDependencyIds.add(dependency.id);\n\n const issues = dependency.verifyDatabaseDependencyInstalled(options.schema);\n if (issues.length === 0) {\n continue;\n }\n\n for (const installOp of dependency.install) {\n if (seenOperationIds.has(installOp.id)) {\n continue;\n }\n seenOperationIds.add(installOp.id);\n // SQL family components are expected to provide compatible target details. This would be better if\n // the type system could enforce it but it's not likely to occur in practice.\n operations.push(installOp as SqlMigrationPlanOperation<PostgresPlanTargetDetails>);\n }\n }\n\n return operations;\n }\n private collectDependencies(\n options: PlannerOptionsWithComponents,\n ): ReadonlyArray<PlannerDatabaseDependency> {\n const components = options.frameworkComponents;\n if (components.length === 0) {\n return [];\n }\n const deps: PlannerDatabaseDependency[] = [];\n for (const component of components) {\n if (!isSqlDependencyProvider(component)) {\n continue;\n }\n const initDeps = component.databaseDependencies?.init;\n if (initDeps && initDeps.length > 0) {\n deps.push(...initDeps);\n }\n }\n return sortDependencies(deps);\n }\n\n private buildTableOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: SqlSchemaIR,\n schemaName: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n if (schema.tables[tableName]) {\n continue;\n }\n const qualified = qualifyTableName(schemaName, tableName);\n operations.push({\n id: `table.${tableName}`,\n label: `Create table ${tableName}`,\n summary: `Creates table ${tableName} with required columns`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('table', tableName, schemaName),\n },\n precheck: [\n {\n description: `ensure table \"${tableName}\" does not exist`,\n sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NULL`,\n },\n ],\n execute: [\n {\n description: `create table \"${tableName}\"`,\n sql: buildCreateTableSql(qualified, table),\n },\n ],\n postcheck: [\n {\n description: `verify table \"${tableName}\" exists`,\n sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, tableName)}) IS NOT NULL`,\n },\n ],\n });\n }\n return operations;\n }\n\n private buildColumnOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: SqlSchemaIR,\n schemaName: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n const schemaTable = schema.tables[tableName];\n if (!schemaTable) {\n continue;\n }\n for (const [columnName, column] of sortedEntries(table.columns)) {\n if (schemaTable.columns[columnName]) {\n continue;\n }\n operations.push(this.buildAddColumnOperation(schemaName, tableName, columnName, column));\n }\n }\n return operations;\n }\n\n private buildAddColumnOperation(\n schema: string,\n tableName: string,\n columnName: string,\n column: StorageColumn,\n ): SqlMigrationPlanOperation<PostgresPlanTargetDetails> {\n const qualified = qualifyTableName(schema, tableName);\n const notNull = column.nullable === false;\n const precheck = [\n {\n description: `ensure column \"${columnName}\" is missing`,\n sql: columnExistsCheck({ schema, table: tableName, column: columnName, exists: false }),\n },\n ...(notNull\n ? [\n {\n description: `ensure table \"${tableName}\" is empty before adding NOT NULL column`,\n sql: tableIsEmptyCheck(qualified),\n },\n ]\n : []),\n ];\n const execute = [\n {\n description: `add column \"${columnName}\"`,\n sql: buildAddColumnSql(qualified, columnName, column),\n },\n ];\n const postcheck = [\n {\n description: `verify column \"${columnName}\" exists`,\n sql: columnExistsCheck({ schema, table: tableName, column: columnName }),\n },\n ...(notNull\n ? [\n {\n description: `verify column \"${columnName}\" is NOT NULL`,\n sql: columnIsNotNullCheck({ schema, table: tableName, column: columnName }),\n },\n ]\n : []),\n ];\n\n return {\n id: `column.${tableName}.${columnName}`,\n label: `Add column ${columnName} to ${tableName}`,\n summary: `Adds column ${columnName} to table ${tableName}`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('table', tableName, schema),\n },\n precheck,\n execute,\n postcheck,\n };\n }\n\n private buildPrimaryKeyOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: SqlSchemaIR,\n schemaName: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n if (!table.primaryKey) {\n continue;\n }\n const schemaTable = schema.tables[tableName];\n if (!schemaTable || schemaTable.primaryKey) {\n continue;\n }\n const constraintName = table.primaryKey.name ?? `${tableName}_pkey`;\n operations.push({\n id: `primaryKey.${tableName}.${constraintName}`,\n label: `Add primary key ${constraintName} on ${tableName}`,\n summary: `Adds primary key ${constraintName} on ${tableName}`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('table', tableName, schemaName),\n },\n precheck: [\n {\n description: `ensure primary key does not exist on \"${tableName}\"`,\n sql: tableHasPrimaryKeyCheck(schemaName, tableName, false),\n },\n ],\n execute: [\n {\n description: `add primary key \"${constraintName}\"`,\n sql: `ALTER TABLE ${qualifyTableName(schemaName, tableName)}\nADD CONSTRAINT ${quoteIdentifier(constraintName)}\nPRIMARY KEY (${table.primaryKey.columns.map(quoteIdentifier).join(', ')})`,\n },\n ],\n postcheck: [\n {\n description: `verify primary key \"${constraintName}\" exists`,\n sql: tableHasPrimaryKeyCheck(schemaName, tableName, true, constraintName),\n },\n ],\n });\n }\n return operations;\n }\n\n private buildUniqueOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: SqlSchemaIR,\n schemaName: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n const schemaTable = schema.tables[tableName];\n for (const unique of table.uniques) {\n if (schemaTable && hasUniqueConstraint(schemaTable, unique.columns)) {\n continue;\n }\n const constraintName = unique.name ?? `${tableName}_${unique.columns.join('_')}_key`;\n operations.push({\n id: `unique.${tableName}.${constraintName}`,\n label: `Add unique constraint ${constraintName} on ${tableName}`,\n summary: `Adds unique constraint ${constraintName} on ${tableName}`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('unique', constraintName, schemaName, tableName),\n },\n precheck: [\n {\n description: `ensure unique constraint \"${constraintName}\" is missing`,\n sql: constraintExistsCheck({ constraintName, schema: schemaName, exists: false }),\n },\n ],\n execute: [\n {\n description: `add unique constraint \"${constraintName}\"`,\n sql: `ALTER TABLE ${qualifyTableName(schemaName, tableName)}\nADD CONSTRAINT ${quoteIdentifier(constraintName)}\nUNIQUE (${unique.columns.map(quoteIdentifier).join(', ')})`,\n },\n ],\n postcheck: [\n {\n description: `verify unique constraint \"${constraintName}\" exists`,\n sql: constraintExistsCheck({ constraintName, schema: schemaName }),\n },\n ],\n });\n }\n }\n return operations;\n }\n\n private buildIndexOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: SqlSchemaIR,\n schemaName: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n const schemaTable = schema.tables[tableName];\n for (const index of table.indexes) {\n if (schemaTable && hasIndex(schemaTable, index.columns)) {\n continue;\n }\n const indexName = index.name ?? `${tableName}_${index.columns.join('_')}_idx`;\n operations.push({\n id: `index.${tableName}.${indexName}`,\n label: `Create index ${indexName} on ${tableName}`,\n summary: `Creates index ${indexName} on ${tableName}`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('index', indexName, schemaName, tableName),\n },\n precheck: [\n {\n description: `ensure index \"${indexName}\" is missing`,\n sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NULL`,\n },\n ],\n execute: [\n {\n description: `create index \"${indexName}\"`,\n sql: `CREATE INDEX ${quoteIdentifier(indexName)} ON ${qualifyTableName(\n schemaName,\n tableName,\n )} (${index.columns.map(quoteIdentifier).join(', ')})`,\n },\n ],\n postcheck: [\n {\n description: `verify index \"${indexName}\" exists`,\n sql: `SELECT to_regclass(${toRegclassLiteral(schemaName, indexName)}) IS NOT NULL`,\n },\n ],\n });\n }\n }\n return operations;\n }\n\n private buildForeignKeyOperations(\n tables: SqlContract<SqlStorage>['storage']['tables'],\n schema: SqlSchemaIR,\n schemaName: string,\n ): readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] {\n const operations: SqlMigrationPlanOperation<PostgresPlanTargetDetails>[] = [];\n for (const [tableName, table] of sortedEntries(tables)) {\n const schemaTable = schema.tables[tableName];\n for (const foreignKey of table.foreignKeys) {\n if (schemaTable && hasForeignKey(schemaTable, foreignKey)) {\n continue;\n }\n const fkName = foreignKey.name ?? `${tableName}_${foreignKey.columns.join('_')}_fkey`;\n operations.push({\n id: `foreignKey.${tableName}.${fkName}`,\n label: `Add foreign key ${fkName} on ${tableName}`,\n summary: `Adds foreign key ${fkName} referencing ${foreignKey.references.table}`,\n operationClass: 'additive',\n target: {\n id: 'postgres',\n details: this.buildTargetDetails('foreignKey', fkName, schemaName, tableName),\n },\n precheck: [\n {\n description: `ensure foreign key \"${fkName}\" is missing`,\n sql: constraintExistsCheck({\n constraintName: fkName,\n schema: schemaName,\n exists: false,\n }),\n },\n ],\n execute: [\n {\n description: `add foreign key \"${fkName}\"`,\n sql: `ALTER TABLE ${qualifyTableName(schemaName, tableName)}\nADD CONSTRAINT ${quoteIdentifier(fkName)}\nFOREIGN KEY (${foreignKey.columns.map(quoteIdentifier).join(', ')})\nREFERENCES ${qualifyTableName(schemaName, foreignKey.references.table)} (${foreignKey.references.columns\n .map(quoteIdentifier)\n .join(', ')})`,\n },\n ],\n postcheck: [\n {\n description: `verify foreign key \"${fkName}\" exists`,\n sql: constraintExistsCheck({ constraintName: fkName, schema: schemaName }),\n },\n ],\n });\n }\n }\n return operations;\n }\n\n private buildTargetDetails(\n objectType: OperationClass,\n name: string,\n schema: string,\n table?: string,\n ): PostgresPlanTargetDetails {\n return {\n schema,\n objectType,\n name,\n ...(table ? { table } : {}),\n };\n }\n\n private classifySchema(options: PlannerOptionsWithComponents):\n | { kind: 'ok' }\n | {\n kind: 'conflict';\n conflicts: SqlPlannerConflict[];\n } {\n const verifyOptions: VerifySqlSchemaOptionsWithComponents = {\n contract: options.contract,\n schema: options.schema,\n strict: false,\n typeMetadataRegistry: new Map(),\n frameworkComponents: options.frameworkComponents,\n };\n const verifyResult = verifySqlSchema(verifyOptions);\n\n const conflicts = this.extractConflicts(verifyResult.schema.issues);\n if (conflicts.length > 0) {\n return { kind: 'conflict', conflicts };\n }\n return { kind: 'ok' };\n }\n\n private extractConflicts(issues: readonly SchemaIssue[]): SqlPlannerConflict[] {\n const conflicts: SqlPlannerConflict[] = [];\n for (const issue of issues) {\n if (isAdditiveIssue(issue)) {\n continue;\n }\n const conflict = this.convertIssueToConflict(issue);\n if (conflict) {\n conflicts.push(conflict);\n }\n }\n return conflicts.sort(conflictComparator);\n }\n\n private convertIssueToConflict(issue: SchemaIssue): SqlPlannerConflict | null {\n switch (issue.kind) {\n case 'type_mismatch':\n return this.buildConflict('typeMismatch', issue);\n case 'nullability_mismatch':\n return this.buildConflict('nullabilityConflict', issue);\n case 'primary_key_mismatch':\n return this.buildConflict('indexIncompatible', issue);\n case 'unique_constraint_mismatch':\n return this.buildConflict('indexIncompatible', issue);\n case 'index_mismatch':\n return this.buildConflict('indexIncompatible', issue);\n case 'foreign_key_mismatch':\n return this.buildConflict('foreignKeyConflict', issue);\n default:\n return null;\n }\n }\n\n private buildConflict(kind: SqlPlannerConflict['kind'], issue: SchemaIssue): SqlPlannerConflict {\n const location = buildConflictLocation(issue);\n const meta =\n issue.expected || issue.actual\n ? Object.freeze({\n ...(issue.expected ? { expected: issue.expected } : {}),\n ...(issue.actual ? { actual: issue.actual } : {}),\n })\n : undefined;\n\n return {\n kind,\n summary: issue.message,\n ...(location ? { location } : {}),\n ...(meta ? { meta } : {}),\n };\n }\n}\n\nfunction isSqlDependencyProvider(component: unknown): component is {\n readonly databaseDependencies?: {\n readonly init?: readonly PlannerDatabaseDependency[];\n };\n} {\n if (typeof component !== 'object' || component === null) {\n return false;\n }\n const record = component as Record<string, unknown>;\n\n // If present, enforce familyId match to avoid mixing families at runtime.\n if (Object.hasOwn(record, 'familyId') && record['familyId'] !== 'sql') {\n return false;\n }\n\n if (!Object.hasOwn(record, 'databaseDependencies')) {\n return false;\n }\n const deps = record['databaseDependencies'];\n return deps === undefined || (typeof deps === 'object' && deps !== null);\n}\n\nfunction sortDependencies(\n dependencies: ReadonlyArray<PlannerDatabaseDependency>,\n): ReadonlyArray<PlannerDatabaseDependency> {\n if (dependencies.length <= 1) {\n return dependencies;\n }\n return [...dependencies].sort((a, b) => a.id.localeCompare(b.id));\n}\n\nfunction buildCreateTableSql(qualifiedTableName: string, table: StorageTable): string {\n const columnDefinitions = Object.entries(table.columns).map(\n ([columnName, column]: [string, StorageColumn]) => {\n const parts = [\n quoteIdentifier(columnName),\n column.nativeType,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n },\n );\n\n const constraintDefinitions: string[] = [];\n if (table.primaryKey) {\n constraintDefinitions.push(\n `PRIMARY KEY (${table.primaryKey.columns.map(quoteIdentifier).join(', ')})`,\n );\n }\n\n const allDefinitions = [...columnDefinitions, ...constraintDefinitions];\n return `CREATE TABLE ${qualifiedTableName} (\\n ${allDefinitions.join(',\\n ')}\\n)`;\n}\n\nfunction qualifyTableName(schema: string, table: string): string {\n return `${quoteIdentifier(schema)}.${quoteIdentifier(table)}`;\n}\n\nfunction toRegclassLiteral(schema: string, name: string): string {\n const regclass = `${quoteIdentifier(schema)}.${quoteIdentifier(name)}`;\n return `'${escapeLiteral(regclass)}'`;\n}\n\n/** Escapes and quotes a SQL identifier (table, column, schema name). */\nfunction quoteIdentifier(identifier: string): string {\n // TypeScript enforces string type - no runtime check needed for internal callers\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction escapeLiteral(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\nfunction sortedEntries<V>(record: Readonly<Record<string, V>>): Array<[string, V]> {\n return Object.entries(record).sort(([a], [b]) => a.localeCompare(b)) as Array<[string, V]>;\n}\n\nfunction constraintExistsCheck({\n constraintName,\n schema,\n exists = true,\n}: {\n constraintName: string;\n schema: string;\n exists?: boolean;\n}): string {\n const existsClause = exists ? 'EXISTS' : 'NOT EXISTS';\n return `SELECT ${existsClause} (\n SELECT 1 FROM pg_constraint c\n JOIN pg_namespace n ON c.connamespace = n.oid\n WHERE c.conname = '${escapeLiteral(constraintName)}'\n AND n.nspname = '${escapeLiteral(schema)}'\n)`;\n}\n\nfunction columnExistsCheck({\n schema,\n table,\n column,\n exists = true,\n}: {\n schema: string;\n table: string;\n column: string;\n exists?: boolean;\n}): string {\n const existsClause = exists ? '' : 'NOT ';\n return `SELECT ${existsClause}EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = '${escapeLiteral(schema)}'\n AND table_name = '${escapeLiteral(table)}'\n AND column_name = '${escapeLiteral(column)}'\n)`;\n}\n\nfunction columnIsNotNullCheck({\n schema,\n table,\n column,\n}: {\n schema: string;\n table: string;\n column: string;\n}): string {\n return `SELECT EXISTS (\n SELECT 1\n FROM information_schema.columns\n WHERE table_schema = '${escapeLiteral(schema)}'\n AND table_name = '${escapeLiteral(table)}'\n AND column_name = '${escapeLiteral(column)}'\n AND is_nullable = 'NO'\n)`;\n}\n\nfunction tableIsEmptyCheck(qualifiedTableName: string): string {\n return `SELECT NOT EXISTS (SELECT 1 FROM ${qualifiedTableName} LIMIT 1)`;\n}\n\nfunction buildAddColumnSql(\n qualifiedTableName: string,\n columnName: string,\n column: StorageColumn,\n): string {\n const parts = [\n `ALTER TABLE ${qualifiedTableName}`,\n `ADD COLUMN ${quoteIdentifier(columnName)} ${column.nativeType}`,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n}\n\nfunction tableHasPrimaryKeyCheck(\n schema: string,\n table: string,\n exists: boolean,\n constraintName?: string,\n): string {\n const comparison = exists ? '' : 'NOT ';\n const constraintFilter = constraintName\n ? `AND c2.relname = '${escapeLiteral(constraintName)}'`\n : '';\n return `SELECT ${comparison}EXISTS (\n SELECT 1\n FROM pg_index i\n JOIN pg_class c ON c.oid = i.indrelid\n JOIN pg_namespace n ON n.oid = c.relnamespace\n LEFT JOIN pg_class c2 ON c2.oid = i.indexrelid\n WHERE n.nspname = '${escapeLiteral(schema)}'\n AND c.relname = '${escapeLiteral(table)}'\n AND i.indisprimary\n ${constraintFilter}\n)`;\n}\n\nfunction hasUniqueConstraint(\n table: SqlSchemaIR['tables'][string],\n columns: readonly string[],\n): boolean {\n return table.uniques.some((unique) => arraysEqual(unique.columns, columns));\n}\n\nfunction hasIndex(table: SqlSchemaIR['tables'][string], columns: readonly string[]): boolean {\n return table.indexes.some((index) => !index.unique && arraysEqual(index.columns, columns));\n}\n\nfunction hasForeignKey(table: SqlSchemaIR['tables'][string], fk: ForeignKey): boolean {\n return table.foreignKeys.some(\n (candidate) =>\n arraysEqual(candidate.columns, fk.columns) &&\n candidate.referencedTable === fk.references.table &&\n arraysEqual(candidate.referencedColumns, fk.references.columns),\n );\n}\n\nfunction isAdditiveIssue(issue: SchemaIssue): boolean {\n switch (issue.kind) {\n case 'missing_table':\n case 'missing_column':\n case 'extension_missing':\n return true;\n case 'primary_key_mismatch':\n return issue.actual === undefined;\n case 'unique_constraint_mismatch':\n case 'index_mismatch':\n case 'foreign_key_mismatch':\n return issue.indexOrConstraint === undefined;\n default:\n return false;\n }\n}\n\nfunction buildConflictLocation(issue: SchemaIssue) {\n const location: {\n table?: string;\n column?: string;\n constraint?: string;\n } = {};\n if (issue.table) {\n location.table = issue.table;\n }\n if (issue.column) {\n location.column = issue.column;\n }\n if (issue.indexOrConstraint) {\n location.constraint = issue.indexOrConstraint;\n }\n return Object.keys(location).length > 0 ? location : undefined;\n}\n\nfunction conflictComparator(a: SqlPlannerConflict, b: SqlPlannerConflict): number {\n if (a.kind !== b.kind) {\n return a.kind < b.kind ? -1 : 1;\n }\n const aLocation = a.location ?? {};\n const bLocation = b.location ?? {};\n const tableCompare = compareStrings(aLocation.table, bLocation.table);\n if (tableCompare !== 0) {\n return tableCompare;\n }\n const columnCompare = compareStrings(aLocation.column, bLocation.column);\n if (columnCompare !== 0) {\n return columnCompare;\n }\n const constraintCompare = compareStrings(aLocation.constraint, bLocation.constraint);\n if (constraintCompare !== 0) {\n return constraintCompare;\n }\n return compareStrings(a.summary, b.summary);\n}\n\nfunction compareStrings(a?: string, b?: string): number {\n if (a === b) {\n return 0;\n }\n if (a === undefined) {\n return -1;\n }\n if (b === undefined) {\n return 1;\n }\n return a < b ? -1 : 1;\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlControlFamilyInstance,\n SqlMigrationPlanContractInfo,\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n SqlMigrationRunner,\n SqlMigrationRunnerExecuteOptions,\n SqlMigrationRunnerFailure,\n SqlMigrationRunnerResult,\n} from '@prisma-next/family-sql/control';\nimport { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport { readMarker } from '@prisma-next/family-sql/verify';\nimport type { Result } from '@prisma-next/utils/result';\nimport { ok, okVoid } from '@prisma-next/utils/result';\nimport type { PostgresPlanTargetDetails } from './planner';\nimport {\n buildLedgerInsertStatement,\n buildWriteMarkerStatements,\n ensureLedgerTableStatement,\n ensureMarkerTableStatement,\n ensurePrismaContractSchemaStatement,\n type SqlStatement,\n} from './statement-builders';\n\ninterface RunnerConfig {\n readonly defaultSchema: string;\n}\n\ninterface ApplyPlanSuccessValue {\n readonly operationsExecuted: number;\n readonly executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[];\n}\n\nconst DEFAULT_CONFIG: RunnerConfig = {\n defaultSchema: 'public',\n};\n\nconst LOCK_DOMAIN = 'prisma_next.contract.marker';\n\n/**\n * Deep clones and freezes a record object to prevent mutation.\n * Recursively clones nested objects and arrays to ensure complete isolation.\n */\nfunction cloneAndFreezeRecord<T extends Record<string, unknown>>(value: T): T {\n const cloned: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (val === null || val === undefined) {\n cloned[key] = val;\n } else if (Array.isArray(val)) {\n // Clone array (shallow clone of array elements)\n cloned[key] = Object.freeze([...val]);\n } else if (typeof val === 'object') {\n // Recursively clone nested objects\n cloned[key] = cloneAndFreezeRecord(val as Record<string, unknown>);\n } else {\n // Primitives are copied as-is\n cloned[key] = val;\n }\n }\n return Object.freeze(cloned) as T;\n}\n\nexport function createPostgresMigrationRunner(\n family: SqlControlFamilyInstance,\n config: Partial<RunnerConfig> = {},\n): SqlMigrationRunner<PostgresPlanTargetDetails> {\n return new PostgresMigrationRunner(family, { ...DEFAULT_CONFIG, ...config });\n}\n\nclass PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDetails> {\n constructor(\n private readonly family: SqlControlFamilyInstance,\n private readonly config: RunnerConfig,\n ) {}\n\n async execute(\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n ): Promise<SqlMigrationRunnerResult> {\n const schema = options.schemaName ?? this.config.defaultSchema;\n const driver = options.driver;\n const lockKey = `${LOCK_DOMAIN}:${schema}`;\n\n // Static checks - fail fast before transaction\n const destinationCheck = this.ensurePlanMatchesDestinationContract(\n options.plan.destination,\n options.destinationContract,\n );\n if (!destinationCheck.ok) {\n return destinationCheck;\n }\n\n const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);\n if (!policyCheck.ok) {\n return policyCheck;\n }\n\n // Begin transaction for DB operations\n await this.beginTransaction(driver);\n let committed = false;\n try {\n await this.acquireLock(driver, lockKey);\n await this.ensureControlTables(driver);\n const existingMarker = await readMarker(driver);\n\n // Validate plan origin matches existing marker (needs marker from DB)\n const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);\n if (!markerCheck.ok) {\n return markerCheck;\n }\n\n // Apply plan operations or skip if marker already at destination\n const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);\n let applyValue: ApplyPlanSuccessValue;\n\n if (markerAtDestination) {\n applyValue = { operationsExecuted: 0, executedOperations: [] };\n } else {\n const applyResult = await this.applyPlan(driver, options);\n if (!applyResult.ok) {\n return applyResult;\n }\n applyValue = applyResult.value;\n }\n\n // Verify resulting schema matches contract\n // Step 1: Introspect live schema (DB I/O, family-owned)\n const schemaIR = await this.family.introspect({\n driver,\n contractIR: options.destinationContract,\n });\n\n // Step 2: Pure verification (no DB I/O)\n const schemaVerifyResult = verifySqlSchema({\n contract: options.destinationContract,\n schema: schemaIR,\n strict: options.strictVerification ?? true,\n context: options.context ?? {},\n typeMetadataRegistry: this.family.typeMetadataRegistry,\n frameworkComponents: options.frameworkComponents,\n });\n if (!schemaVerifyResult.ok) {\n return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {\n why: 'The resulting database schema does not satisfy the destination contract.',\n meta: {\n issues: schemaVerifyResult.schema.issues,\n },\n });\n }\n\n // Record marker and ledger entries\n await this.upsertMarker(driver, options, existingMarker);\n await this.recordLedgerEntry(driver, options, existingMarker, applyValue.executedOperations);\n\n await this.commitTransaction(driver);\n committed = true;\n return runnerSuccess({\n operationsPlanned: options.plan.operations.length,\n operationsExecuted: applyValue.operationsExecuted,\n });\n } finally {\n if (!committed) {\n await this.rollbackTransaction(driver);\n }\n }\n }\n\n private async applyPlan(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n ): Promise<Result<ApplyPlanSuccessValue, SqlMigrationRunnerFailure>> {\n let operationsExecuted = 0;\n const executedOperations: Array<SqlMigrationPlanOperation<PostgresPlanTargetDetails>> = [];\n for (const operation of options.plan.operations) {\n options.callbacks?.onOperationStart?.(operation);\n try {\n const postcheckAlreadySatisfied = await this.expectationsAreSatisfied(\n driver,\n operation.postcheck,\n );\n if (postcheckAlreadySatisfied) {\n executedOperations.push(this.createPostcheckPreSatisfiedSkipRecord(operation));\n continue;\n }\n\n const precheckResult = await this.runExpectationSteps(\n driver,\n operation.precheck,\n operation,\n 'precheck',\n );\n if (!precheckResult.ok) {\n return precheckResult;\n }\n\n const executeResult = await this.runExecuteSteps(driver, operation.execute, operation);\n if (!executeResult.ok) {\n return executeResult;\n }\n\n const postcheckResult = await this.runExpectationSteps(\n driver,\n operation.postcheck,\n operation,\n 'postcheck',\n );\n if (!postcheckResult.ok) {\n return postcheckResult;\n }\n\n executedOperations.push(operation);\n operationsExecuted += 1;\n } finally {\n options.callbacks?.onOperationComplete?.(operation);\n }\n }\n return ok({ operationsExecuted, executedOperations });\n }\n\n private async ensureControlTables(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await this.executeStatement(driver, ensurePrismaContractSchemaStatement);\n await this.executeStatement(driver, ensureMarkerTableStatement);\n await this.executeStatement(driver, ensureLedgerTableStatement);\n }\n\n private async runExpectationSteps(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n phase: 'precheck' | 'postcheck',\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n for (const step of steps) {\n const result = await driver.query(step.sql);\n if (!this.stepResultIsTrue(result.rows)) {\n const code = phase === 'precheck' ? 'PRECHECK_FAILED' : 'POSTCHECK_FAILED';\n return runnerFailure(\n code,\n `Operation ${operation.id} failed during ${phase}: ${step.description}`,\n {\n meta: {\n operationId: operation.id,\n phase,\n stepDescription: step.description,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private async runExecuteSteps(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n ): Promise<Result<void, SqlMigrationRunnerFailure>> {\n for (const step of steps) {\n try {\n await driver.query(step.sql);\n } catch (error) {\n return runnerFailure(\n 'EXECUTION_FAILED',\n `Operation ${operation.id} failed during execution: ${step.description}`,\n {\n why: error instanceof Error ? error.message : String(error),\n meta: {\n operationId: operation.id,\n stepDescription: step.description,\n sql: step.sql,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private stepResultIsTrue(rows: readonly Record<string, unknown>[]): boolean {\n if (!rows || rows.length === 0) {\n return false;\n }\n const firstRow = rows[0];\n const firstValue = firstRow ? Object.values(firstRow)[0] : undefined;\n if (typeof firstValue === 'boolean') {\n return firstValue;\n }\n if (typeof firstValue === 'number') {\n return firstValue !== 0;\n }\n if (typeof firstValue === 'string') {\n const lower = firstValue.toLowerCase();\n // PostgreSQL boolean representations: 't'/'f', 'true'/'false', '1'/'0'\n if (lower === 't' || lower === 'true' || lower === '1') {\n return true;\n }\n if (lower === 'f' || lower === 'false' || lower === '0') {\n return false;\n }\n // For other strings, non-empty is truthy (though this case shouldn't occur for boolean checks)\n return firstValue.length > 0;\n }\n return Boolean(firstValue);\n }\n\n private async expectationsAreSatisfied(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n steps: readonly SqlMigrationPlanOperationStep[],\n ): Promise<boolean> {\n if (steps.length === 0) {\n return false;\n }\n for (const step of steps) {\n const result = await driver.query(step.sql);\n if (!this.stepResultIsTrue(result.rows)) {\n return false;\n }\n }\n return true;\n }\n\n private createPostcheckPreSatisfiedSkipRecord(\n operation: SqlMigrationPlanOperation<PostgresPlanTargetDetails>,\n ): SqlMigrationPlanOperation<PostgresPlanTargetDetails> {\n // Clone and freeze existing meta if present\n const clonedMeta = operation.meta ? cloneAndFreezeRecord(operation.meta) : undefined;\n\n // Create frozen runner metadata\n const runnerMeta = Object.freeze({\n skipped: true,\n reason: 'postcheck_pre_satisfied',\n });\n\n // Merge and freeze the combined meta\n const mergedMeta = Object.freeze({\n ...(clonedMeta ?? {}),\n runner: runnerMeta,\n });\n\n // Clone and freeze arrays to prevent mutation\n const frozenPostcheck = Object.freeze([...operation.postcheck]);\n\n return Object.freeze({\n id: operation.id,\n label: operation.label,\n ...(operation.summary ? { summary: operation.summary } : {}),\n operationClass: operation.operationClass,\n target: operation.target, // Already frozen from plan creation\n precheck: Object.freeze([]),\n execute: Object.freeze([]),\n postcheck: frozenPostcheck,\n ...(operation.meta || mergedMeta ? { meta: mergedMeta } : {}),\n });\n }\n\n private markerMatchesDestination(\n marker: ContractMarkerRecord | null,\n plan: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['plan'],\n ): boolean {\n if (!marker) {\n return false;\n }\n if (marker.coreHash !== plan.destination.coreHash) {\n return false;\n }\n if (plan.destination.profileHash && marker.profileHash !== plan.destination.profileHash) {\n return false;\n }\n return true;\n }\n\n private enforcePolicyCompatibility(\n policy: MigrationOperationPolicy,\n operations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],\n ): Result<void, SqlMigrationRunnerFailure> {\n const allowedClasses = new Set(policy.allowedOperationClasses);\n for (const operation of operations) {\n if (!allowedClasses.has(operation.operationClass)) {\n return runnerFailure(\n 'POLICY_VIOLATION',\n `Operation ${operation.id} has class \"${operation.operationClass}\" which is not allowed by policy.`,\n {\n why: `Policy only allows: ${policy.allowedOperationClasses.join(', ')}.`,\n meta: {\n operationId: operation.id,\n operationClass: operation.operationClass,\n allowedClasses: policy.allowedOperationClasses,\n },\n },\n );\n }\n }\n return okVoid();\n }\n\n private ensureMarkerCompatibility(\n marker: ContractMarkerRecord | null,\n plan: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['plan'],\n ): Result<void, SqlMigrationRunnerFailure> {\n const origin = plan.origin ?? null;\n if (!origin) {\n if (!marker) {\n return okVoid();\n }\n if (this.markerMatchesDestination(marker, plan)) {\n return okVoid();\n }\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.coreHash}) does not match plan origin (no marker expected).`,\n {\n meta: {\n markerCoreHash: marker.coreHash,\n expectedOrigin: null,\n },\n },\n );\n }\n\n if (!marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Missing contract marker: expected origin core hash ${origin.coreHash}.`,\n {\n meta: {\n expectedOriginCoreHash: origin.coreHash,\n },\n },\n );\n }\n if (marker.coreHash !== origin.coreHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.coreHash}) does not match plan origin (${origin.coreHash}).`,\n {\n meta: {\n markerCoreHash: marker.coreHash,\n expectedOriginCoreHash: origin.coreHash,\n },\n },\n );\n }\n if (origin.profileHash && marker.profileHash !== origin.profileHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker profile hash (${marker.profileHash}) does not match plan origin profile hash (${origin.profileHash}).`,\n {\n meta: {\n markerProfileHash: marker.profileHash,\n expectedOriginProfileHash: origin.profileHash,\n },\n },\n );\n }\n return okVoid();\n }\n\n private ensurePlanMatchesDestinationContract(\n destination: SqlMigrationPlanContractInfo,\n contract: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['destinationContract'],\n ): Result<void, SqlMigrationRunnerFailure> {\n if (destination.coreHash !== contract.coreHash) {\n return runnerFailure(\n 'DESTINATION_CONTRACT_MISMATCH',\n `Plan destination core hash (${destination.coreHash}) does not match provided contract core hash (${contract.coreHash}).`,\n {\n meta: {\n planCoreHash: destination.coreHash,\n contractCoreHash: contract.coreHash,\n },\n },\n );\n }\n if (\n destination.profileHash &&\n contract.profileHash &&\n destination.profileHash !== contract.profileHash\n ) {\n return runnerFailure(\n 'DESTINATION_CONTRACT_MISMATCH',\n `Plan destination profile hash (${destination.profileHash}) does not match provided contract profile hash (${contract.profileHash}).`,\n {\n meta: {\n planProfileHash: destination.profileHash,\n contractProfileHash: contract.profileHash,\n },\n },\n );\n }\n return okVoid();\n }\n\n private async upsertMarker(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n existingMarker: ContractMarkerRecord | null,\n ): Promise<void> {\n const writeStatements = buildWriteMarkerStatements({\n coreHash: options.plan.destination.coreHash,\n profileHash:\n options.plan.destination.profileHash ??\n options.destinationContract.profileHash ??\n options.plan.destination.coreHash,\n contractJson: options.destinationContract,\n canonicalVersion: null,\n meta: {},\n });\n const statement = existingMarker ? writeStatements.update : writeStatements.insert;\n await this.executeStatement(driver, statement);\n }\n\n private async recordLedgerEntry(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,\n existingMarker: ContractMarkerRecord | null,\n executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[],\n ): Promise<void> {\n const ledgerStatement = buildLedgerInsertStatement({\n originCoreHash: existingMarker?.coreHash ?? null,\n originProfileHash: existingMarker?.profileHash ?? null,\n destinationCoreHash: options.plan.destination.coreHash,\n destinationProfileHash:\n options.plan.destination.profileHash ??\n options.destinationContract.profileHash ??\n options.plan.destination.coreHash,\n contractJsonBefore: existingMarker?.contractJson ?? null,\n contractJsonAfter: options.destinationContract,\n operations: executedOperations,\n });\n await this.executeStatement(driver, ledgerStatement);\n }\n\n private async acquireLock(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n key: string,\n ): Promise<void> {\n await driver.query('select pg_advisory_xact_lock(hashtext($1))', [key]);\n }\n\n private async beginTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('BEGIN');\n }\n\n private async commitTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('COMMIT');\n }\n\n private async rollbackTransaction(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n ): Promise<void> {\n await driver.query('ROLLBACK');\n }\n\n private async executeStatement(\n driver: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>['driver'],\n statement: SqlStatement,\n ): Promise<void> {\n if (statement.params.length > 0) {\n await driver.query(statement.sql, statement.params);\n return;\n }\n await driver.query(statement.sql);\n }\n}\n","export interface SqlStatement {\n readonly sql: string;\n readonly params: readonly unknown[];\n}\n\nexport const ensurePrismaContractSchemaStatement: SqlStatement = {\n sql: 'create schema if not exists prisma_contract',\n params: [],\n};\n\nexport const ensureMarkerTableStatement: SqlStatement = {\n sql: `create table if not exists prisma_contract.marker (\n id smallint primary key default 1,\n core_hash text not null,\n profile_hash text not null,\n contract_json jsonb,\n canonical_version int,\n updated_at timestamptz not null default now(),\n app_tag text,\n meta jsonb not null default '{}'\n )`,\n params: [],\n};\n\nexport const ensureLedgerTableStatement: SqlStatement = {\n sql: `create table if not exists prisma_contract.ledger (\n id bigserial primary key,\n created_at timestamptz not null default now(),\n origin_core_hash text,\n origin_profile_hash text,\n destination_core_hash text not null,\n destination_profile_hash text,\n contract_json_before jsonb,\n contract_json_after jsonb,\n operations jsonb not null\n )`,\n params: [],\n};\n\nexport interface WriteMarkerInput {\n readonly coreHash: string;\n readonly profileHash: string;\n readonly contractJson?: unknown;\n readonly canonicalVersion?: number | null;\n readonly appTag?: string | null;\n readonly meta?: Record<string, unknown>;\n}\n\nexport function buildWriteMarkerStatements(input: WriteMarkerInput): {\n readonly insert: SqlStatement;\n readonly update: SqlStatement;\n} {\n const params: readonly unknown[] = [\n 1,\n input.coreHash,\n input.profileHash,\n jsonParam(input.contractJson),\n input.canonicalVersion ?? null,\n input.appTag ?? null,\n jsonParam(input.meta ?? {}),\n ];\n\n return {\n insert: {\n sql: `insert into prisma_contract.marker (\n id,\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta\n ) values (\n $1,\n $2,\n $3,\n $4::jsonb,\n $5,\n now(),\n $6,\n $7::jsonb\n )`,\n params,\n },\n update: {\n sql: `update prisma_contract.marker set\n core_hash = $2,\n profile_hash = $3,\n contract_json = $4::jsonb,\n canonical_version = $5,\n updated_at = now(),\n app_tag = $6,\n meta = $7::jsonb\n where id = $1`,\n params,\n },\n };\n}\n\nexport interface LedgerInsertInput {\n readonly originCoreHash?: string | null;\n readonly originProfileHash?: string | null;\n readonly destinationCoreHash: string;\n readonly destinationProfileHash?: string | null;\n readonly contractJsonBefore?: unknown;\n readonly contractJsonAfter?: unknown;\n readonly operations: unknown;\n}\n\nexport function buildLedgerInsertStatement(input: LedgerInsertInput): SqlStatement {\n return {\n sql: `insert into prisma_contract.ledger (\n origin_core_hash,\n origin_profile_hash,\n destination_core_hash,\n destination_profile_hash,\n contract_json_before,\n contract_json_after,\n operations\n ) values (\n $1,\n $2,\n $3,\n $4,\n $5::jsonb,\n $6::jsonb,\n $7::jsonb\n )`,\n params: [\n input.originCoreHash ?? null,\n input.originProfileHash ?? null,\n input.destinationCoreHash,\n input.destinationProfileHash ?? null,\n jsonParam(input.contractJsonBefore),\n jsonParam(input.contractJsonAfter),\n jsonParam(input.operations),\n ],\n };\n}\n\nfunction jsonParam(value: unknown): string {\n return JSON.stringify(value ?? null);\n}\n"],"mappings":"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","names":["verifySqlSchema","verifySqlSchema"]}
package/package.json CHANGED
@@ -1,27 +1,27 @@
1
1
  {
2
2
  "name": "@prisma-next/target-postgres",
3
- "version": "0.1.0-dev.19",
3
+ "version": "0.1.0-dev.21",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Postgres target pack for Prisma Next",
7
7
  "dependencies": {
8
8
  "arktype": "^2.0.0",
9
- "@prisma-next/family-sql": "0.1.0-dev.19",
10
- "@prisma-next/contract": "0.1.0-dev.19",
11
- "@prisma-next/cli": "0.1.0-dev.19",
12
- "@prisma-next/sql-contract": "0.1.0-dev.19",
13
- "@prisma-next/sql-schema-ir": "0.1.0-dev.19",
14
- "@prisma-next/core-control-plane": "0.1.0-dev.19",
15
- "@prisma-next/core-execution-plane": "0.1.0-dev.19",
16
- "@prisma-next/utils": "0.1.0-dev.19"
9
+ "@prisma-next/family-sql": "0.1.0-dev.21",
10
+ "@prisma-next/cli": "0.1.0-dev.21",
11
+ "@prisma-next/contract": "0.1.0-dev.21",
12
+ "@prisma-next/sql-contract": "0.1.0-dev.21",
13
+ "@prisma-next/sql-schema-ir": "0.1.0-dev.21",
14
+ "@prisma-next/core-control-plane": "0.1.0-dev.21",
15
+ "@prisma-next/core-execution-plane": "0.1.0-dev.21",
16
+ "@prisma-next/utils": "0.1.0-dev.21"
17
17
  },
18
18
  "devDependencies": {
19
19
  "vite-tsconfig-paths": "^5.1.4",
20
20
  "tsup": "^8.3.0",
21
21
  "typescript": "^5.9.3",
22
22
  "vitest": "^4.0.16",
23
- "@prisma-next/adapter-postgres": "0.1.0-dev.19",
24
- "@prisma-next/driver-postgres": "0.1.0-dev.19",
23
+ "@prisma-next/adapter-postgres": "0.1.0-dev.21",
24
+ "@prisma-next/driver-postgres": "0.1.0-dev.21",
25
25
  "@prisma-next/test-utils": "0.0.1"
26
26
  },
27
27
  "files": [