@prisma-next/family-sql 0.9.0 → 0.10.0-dev.2
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/dist/control.d.mts +1 -1
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +99 -55
- package/dist/control.mjs.map +1 -1
- package/dist/ir.d.mts +5 -41
- package/dist/ir.d.mts.map +1 -1
- package/dist/ir.mjs +1 -1
- package/dist/migration.d.mts +1 -1
- package/dist/schema-verify.d.mts.map +1 -1
- package/dist/schema-verify.mjs +1 -1
- package/dist/{sql-contract-serializer-qUQCnP-k.mjs → sql-contract-serializer-C6ypWJYR.mjs} +22 -43
- package/dist/sql-contract-serializer-C6ypWJYR.mjs.map +1 -0
- package/dist/{types-DMINfGUO.d.mts → types-hQoMXr54.d.mts} +4 -3
- package/dist/types-hQoMXr54.d.mts.map +1 -0
- package/dist/verify-sql-schema-Bfvz07Ik.d.mts.map +1 -1
- package/dist/{verify-sql-schema-BXw7yx6L.mjs → verify-sql-schema-Bj4Wqe2c.mjs} +99 -63
- package/dist/verify-sql-schema-Bj4Wqe2c.mjs.map +1 -0
- package/package.json +21 -21
- package/src/core/control-instance.ts +11 -4
- package/src/core/ir/sql-contract-serializer-base.ts +58 -47
- package/src/core/migrations/contract-to-schema-ir.ts +82 -33
- package/src/core/migrations/field-event-planner.ts +53 -29
- package/src/core/migrations/types.ts +2 -1
- package/src/core/psl-contract-infer/sql-schema-ir-to-psl-ast.ts +17 -3
- package/src/core/schema-verify/verify-helpers.ts +44 -14
- package/src/core/schema-verify/verify-sql-schema.ts +106 -47
- package/dist/sql-contract-serializer-qUQCnP-k.mjs.map +0 -1
- package/dist/types-DMINfGUO.d.mts.map +0 -1
- package/dist/verify-sql-schema-BXw7yx6L.mjs.map +0 -1
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
SchemaIssue,
|
|
8
8
|
SchemaVerificationNode,
|
|
9
9
|
} from '@prisma-next/framework-components/control';
|
|
10
|
+
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
10
11
|
import type {
|
|
11
12
|
ForeignKey,
|
|
12
13
|
Index,
|
|
@@ -133,12 +134,14 @@ export function verifyPrimaryKey(
|
|
|
133
134
|
contractPK: PrimaryKey,
|
|
134
135
|
schemaPK: PrimaryKey | undefined,
|
|
135
136
|
tableName: string,
|
|
137
|
+
namespaceId: string,
|
|
136
138
|
issues: SchemaIssue[],
|
|
137
139
|
): 'pass' | 'fail' {
|
|
138
140
|
if (!schemaPK) {
|
|
139
141
|
issues.push({
|
|
140
142
|
kind: 'primary_key_mismatch',
|
|
141
143
|
table: tableName,
|
|
144
|
+
namespaceId,
|
|
142
145
|
expected: contractPK.columns.join(', '),
|
|
143
146
|
message: `Table "${tableName}" is missing primary key`,
|
|
144
147
|
});
|
|
@@ -149,6 +152,7 @@ export function verifyPrimaryKey(
|
|
|
149
152
|
issues.push({
|
|
150
153
|
kind: 'primary_key_mismatch',
|
|
151
154
|
table: tableName,
|
|
155
|
+
namespaceId,
|
|
152
156
|
expected: contractPK.columns.join(', '),
|
|
153
157
|
actual: schemaPK.columns.join(', '),
|
|
154
158
|
message: `Table "${tableName}" has primary key mismatch: expected columns [${contractPK.columns.join(', ')}], got [${schemaPK.columns.join(', ')}]`,
|
|
@@ -173,6 +177,7 @@ export function verifyForeignKeys(
|
|
|
173
177
|
contractFKs: readonly ForeignKey[],
|
|
174
178
|
schemaFKs: readonly SqlForeignKeyIR[],
|
|
175
179
|
tableName: string,
|
|
180
|
+
namespaceId: string,
|
|
176
181
|
tablePath: string,
|
|
177
182
|
issues: SchemaIssue[],
|
|
178
183
|
strict: boolean,
|
|
@@ -181,12 +186,23 @@ export function verifyForeignKeys(
|
|
|
181
186
|
|
|
182
187
|
// Check each contract FK exists in schema
|
|
183
188
|
for (const contractFK of contractFKs) {
|
|
184
|
-
const fkPath = `${tablePath}.foreignKeys[${contractFK.columns.join(',')}]`;
|
|
189
|
+
const fkPath = `${tablePath}.foreignKeys[${contractFK.source.columns.join(',')}]`;
|
|
185
190
|
const matchingFK = schemaFKs.find((fk) => {
|
|
191
|
+
// When the schema FK carries referencedSchema (populated by the Postgres
|
|
192
|
+
// adapter for cross-schema FKs), compare the full (namespace, table) pair
|
|
193
|
+
// against the contract FK's target coordinate. When referencedSchema is
|
|
194
|
+
// absent (same-schema FKs, older introspection, or hand-crafted test
|
|
195
|
+
// fixtures), fall back to table-name-only comparison so same-namespace
|
|
196
|
+
// contracts continue to verify correctly.
|
|
197
|
+
const tablesMatch =
|
|
198
|
+
fk.referencedSchema !== undefined && contractFK.target.namespaceId !== UNBOUND_NAMESPACE_ID
|
|
199
|
+
? fk.referencedSchema === contractFK.target.namespaceId &&
|
|
200
|
+
fk.referencedTable === contractFK.target.tableName
|
|
201
|
+
: fk.referencedTable === contractFK.target.tableName;
|
|
186
202
|
return (
|
|
187
|
-
arraysEqual(fk.columns, contractFK.columns) &&
|
|
188
|
-
|
|
189
|
-
arraysEqual(fk.referencedColumns, contractFK.
|
|
203
|
+
arraysEqual(fk.columns, contractFK.source.columns) &&
|
|
204
|
+
tablesMatch &&
|
|
205
|
+
arraysEqual(fk.referencedColumns, contractFK.target.columns)
|
|
190
206
|
);
|
|
191
207
|
});
|
|
192
208
|
|
|
@@ -194,13 +210,14 @@ export function verifyForeignKeys(
|
|
|
194
210
|
issues.push({
|
|
195
211
|
kind: 'foreign_key_mismatch',
|
|
196
212
|
table: tableName,
|
|
197
|
-
|
|
198
|
-
|
|
213
|
+
namespaceId,
|
|
214
|
+
expected: `${contractFK.source.columns.join(', ')} -> ${contractFK.target.tableName}(${contractFK.target.columns.join(', ')})`,
|
|
215
|
+
message: `Table "${tableName}" is missing foreign key: ${contractFK.source.columns.join(', ')} -> ${contractFK.target.tableName}(${contractFK.target.columns.join(', ')})`,
|
|
199
216
|
});
|
|
200
217
|
nodes.push({
|
|
201
218
|
status: 'fail',
|
|
202
219
|
kind: 'foreignKey',
|
|
203
|
-
name: `foreignKey(${contractFK.columns.join(', ')})`,
|
|
220
|
+
name: `foreignKey(${contractFK.source.columns.join(', ')})`,
|
|
204
221
|
contractPath: fkPath,
|
|
205
222
|
code: 'foreign_key_mismatch',
|
|
206
223
|
message: 'Foreign key missing',
|
|
@@ -217,17 +234,18 @@ export function verifyForeignKeys(
|
|
|
217
234
|
issues.push({
|
|
218
235
|
kind: 'foreign_key_mismatch',
|
|
219
236
|
table: tableName,
|
|
237
|
+
namespaceId,
|
|
220
238
|
// Set indexOrConstraint so the planner classifies this as a non-additive
|
|
221
239
|
// conflict (existing FK with wrong actions cannot be fixed additively).
|
|
222
|
-
indexOrConstraint: matchingFK.name ?? `fk(${contractFK.columns.join(',')})`,
|
|
240
|
+
indexOrConstraint: matchingFK.name ?? `fk(${contractFK.source.columns.join(',')})`,
|
|
223
241
|
expected: combinedExpected,
|
|
224
242
|
actual: combinedActual,
|
|
225
|
-
message: `Table "${tableName}" foreign key ${contractFK.columns.join(', ')} -> ${contractFK.
|
|
243
|
+
message: `Table "${tableName}" foreign key ${contractFK.source.columns.join(', ')} -> ${contractFK.target.tableName}: ${combinedMessage}`,
|
|
226
244
|
});
|
|
227
245
|
nodes.push({
|
|
228
246
|
status: 'fail',
|
|
229
247
|
kind: 'foreignKey',
|
|
230
|
-
name: `foreignKey(${contractFK.columns.join(', ')})`,
|
|
248
|
+
name: `foreignKey(${contractFK.source.columns.join(', ')})`,
|
|
231
249
|
contractPath: fkPath,
|
|
232
250
|
code: 'foreign_key_mismatch',
|
|
233
251
|
message: combinedMessage,
|
|
@@ -239,7 +257,7 @@ export function verifyForeignKeys(
|
|
|
239
257
|
nodes.push({
|
|
240
258
|
status: 'pass',
|
|
241
259
|
kind: 'foreignKey',
|
|
242
|
-
name: `foreignKey(${contractFK.columns.join(', ')})`,
|
|
260
|
+
name: `foreignKey(${contractFK.source.columns.join(', ')})`,
|
|
243
261
|
contractPath: fkPath,
|
|
244
262
|
code: '',
|
|
245
263
|
message: '',
|
|
@@ -255,10 +273,15 @@ export function verifyForeignKeys(
|
|
|
255
273
|
if (strict) {
|
|
256
274
|
for (const schemaFK of schemaFKs) {
|
|
257
275
|
const matchingFK = contractFKs.find((fk) => {
|
|
276
|
+
const tablesMatch =
|
|
277
|
+
schemaFK.referencedSchema !== undefined && fk.target.namespaceId !== UNBOUND_NAMESPACE_ID
|
|
278
|
+
? schemaFK.referencedSchema === fk.target.namespaceId &&
|
|
279
|
+
schemaFK.referencedTable === fk.target.tableName
|
|
280
|
+
: schemaFK.referencedTable === fk.target.tableName;
|
|
258
281
|
return (
|
|
259
|
-
arraysEqual(fk.columns, schemaFK.columns) &&
|
|
260
|
-
|
|
261
|
-
arraysEqual(fk.
|
|
282
|
+
arraysEqual(fk.source.columns, schemaFK.columns) &&
|
|
283
|
+
tablesMatch &&
|
|
284
|
+
arraysEqual(fk.target.columns, schemaFK.referencedColumns)
|
|
262
285
|
);
|
|
263
286
|
});
|
|
264
287
|
|
|
@@ -266,6 +289,7 @@ export function verifyForeignKeys(
|
|
|
266
289
|
issues.push({
|
|
267
290
|
kind: 'extra_foreign_key',
|
|
268
291
|
table: tableName,
|
|
292
|
+
namespaceId,
|
|
269
293
|
indexOrConstraint: schemaFK.name ?? `fk(${schemaFK.columns.join(',')})`,
|
|
270
294
|
message: `Extra foreign key found in database (not in contract): ${schemaFK.columns.join(', ')} -> ${schemaFK.referencedTable}(${schemaFK.referencedColumns.join(', ')})`,
|
|
271
295
|
});
|
|
@@ -303,6 +327,7 @@ export function verifyUniqueConstraints(
|
|
|
303
327
|
schemaUniques: readonly SqlUniqueIR[],
|
|
304
328
|
schemaIndexes: readonly SqlIndexIR[],
|
|
305
329
|
tableName: string,
|
|
330
|
+
namespaceId: string,
|
|
306
331
|
tablePath: string,
|
|
307
332
|
issues: SchemaIssue[],
|
|
308
333
|
strict: boolean,
|
|
@@ -327,6 +352,7 @@ export function verifyUniqueConstraints(
|
|
|
327
352
|
issues.push({
|
|
328
353
|
kind: 'unique_constraint_mismatch',
|
|
329
354
|
table: tableName,
|
|
355
|
+
namespaceId,
|
|
330
356
|
expected: contractUnique.columns.join(', '),
|
|
331
357
|
message: `Table "${tableName}" is missing unique constraint: ${contractUnique.columns.join(', ')}`,
|
|
332
358
|
});
|
|
@@ -369,6 +395,7 @@ export function verifyUniqueConstraints(
|
|
|
369
395
|
issues.push({
|
|
370
396
|
kind: 'extra_unique_constraint',
|
|
371
397
|
table: tableName,
|
|
398
|
+
namespaceId,
|
|
372
399
|
indexOrConstraint: schemaUnique.name ?? `unique(${schemaUnique.columns.join(',')})`,
|
|
373
400
|
message: `Extra unique constraint found in database (not in contract): ${schemaUnique.columns.join(', ')}`,
|
|
374
401
|
});
|
|
@@ -406,6 +433,7 @@ export function verifyIndexes(
|
|
|
406
433
|
schemaIndexes: readonly SqlIndexIR[],
|
|
407
434
|
schemaUniques: readonly SqlUniqueIR[],
|
|
408
435
|
tableName: string,
|
|
436
|
+
namespaceId: string,
|
|
409
437
|
tablePath: string,
|
|
410
438
|
issues: SchemaIssue[],
|
|
411
439
|
strict: boolean,
|
|
@@ -436,6 +464,7 @@ export function verifyIndexes(
|
|
|
436
464
|
issues.push({
|
|
437
465
|
kind: 'index_mismatch',
|
|
438
466
|
table: tableName,
|
|
467
|
+
namespaceId,
|
|
439
468
|
expected: contractIndex.columns.join(', '),
|
|
440
469
|
message: `Table "${tableName}" is missing index: ${contractIndex.columns.join(', ')}`,
|
|
441
470
|
});
|
|
@@ -484,6 +513,7 @@ export function verifyIndexes(
|
|
|
484
513
|
issues.push({
|
|
485
514
|
kind: 'extra_index',
|
|
486
515
|
table: tableName,
|
|
516
|
+
namespaceId,
|
|
487
517
|
indexOrConstraint: schemaIndex.name ?? `idx(${schemaIndex.columns.join(',')})`,
|
|
488
518
|
message: `Extra index found in database (not in contract): ${schemaIndex.columns.join(', ')}`,
|
|
489
519
|
});
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type PostgresEnumStorageEntry,
|
|
21
21
|
type SqlStorage,
|
|
22
22
|
type StorageColumn,
|
|
23
|
+
StorageTable,
|
|
23
24
|
type StorageTypeInstance,
|
|
24
25
|
} from '@prisma-next/sql-contract/types';
|
|
25
26
|
import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
@@ -128,7 +129,21 @@ export function verifySqlSchema(options: VerifySqlSchemaOptions): VerifyDatabase
|
|
|
128
129
|
|
|
129
130
|
const { contractStorageHash, contractProfileHash, contractTarget } =
|
|
130
131
|
extractContractMetadata(contract);
|
|
131
|
-
const
|
|
132
|
+
const allStorageTypesMap: Record<string, PostgresEnumStorageEntry | StorageTypeInstance> = {
|
|
133
|
+
...((contract.storage.types ?? {}) as Record<
|
|
134
|
+
string,
|
|
135
|
+
PostgresEnumStorageEntry | StorageTypeInstance
|
|
136
|
+
>),
|
|
137
|
+
};
|
|
138
|
+
for (const ns of Object.values(contract.storage.namespaces)) {
|
|
139
|
+
const nsTypes = (ns as { types?: Record<string, PostgresEnumStorageEntry> }).types;
|
|
140
|
+
if (nsTypes) {
|
|
141
|
+
for (const [k, v] of Object.entries(nsTypes)) {
|
|
142
|
+
allStorageTypesMap[k] = v;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const storageTypes = allStorageTypesMap as Readonly<
|
|
132
147
|
Record<string, PostgresEnumStorageEntry | StorageTypeInstance>
|
|
133
148
|
>;
|
|
134
149
|
const { issues, rootChildren } = verifySchemaTables({
|
|
@@ -335,52 +350,73 @@ function verifySchemaTables(options: {
|
|
|
335
350
|
} = options;
|
|
336
351
|
const issues: SchemaIssue[] = [];
|
|
337
352
|
const rootChildren: SchemaVerificationNode[] = [];
|
|
338
|
-
const contractTables = contract.storage.tables;
|
|
339
353
|
const schemaTables = schema.tables;
|
|
354
|
+
const namespaceIds = Object.keys(contract.storage.namespaces).sort((a, b) =>
|
|
355
|
+
a < b ? -1 : a > b ? 1 : 0,
|
|
356
|
+
);
|
|
340
357
|
|
|
341
|
-
for (const
|
|
342
|
-
const
|
|
343
|
-
|
|
358
|
+
for (const namespaceId of namespaceIds) {
|
|
359
|
+
const ns = contract.storage.namespaces[namespaceId];
|
|
360
|
+
if (!ns) continue;
|
|
361
|
+
for (const [tableName, contractTableRaw] of Object.entries(ns.tables)) {
|
|
362
|
+
if (!(contractTableRaw instanceof StorageTable)) {
|
|
363
|
+
throw new Error(
|
|
364
|
+
`verifySqlSchema: expected StorageTable at storage.namespaces.${namespaceId}.tables.${tableName}`,
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
const contractTable = contractTableRaw;
|
|
368
|
+
const schemaTable = schemaTables[tableName];
|
|
369
|
+
const tablePath = `storage.namespaces.${namespaceId}.tables.${tableName}`;
|
|
344
370
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
371
|
+
if (!schemaTable) {
|
|
372
|
+
issues.push({
|
|
373
|
+
kind: 'missing_table',
|
|
374
|
+
table: tableName,
|
|
375
|
+
namespaceId,
|
|
376
|
+
message: `Table "${tableName}" is missing from database`,
|
|
377
|
+
});
|
|
378
|
+
rootChildren.push({
|
|
379
|
+
status: 'fail',
|
|
380
|
+
kind: 'table',
|
|
381
|
+
name: `table ${tableName}`,
|
|
382
|
+
contractPath: tablePath,
|
|
383
|
+
code: 'missing_table',
|
|
384
|
+
message: `Table "${tableName}" is missing`,
|
|
385
|
+
expected: undefined,
|
|
386
|
+
actual: undefined,
|
|
387
|
+
children: [],
|
|
388
|
+
});
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const tableChildren = verifyTableChildren({
|
|
393
|
+
contractTable,
|
|
394
|
+
schemaTable,
|
|
395
|
+
tableName,
|
|
396
|
+
namespaceId,
|
|
397
|
+
tablePath,
|
|
398
|
+
issues,
|
|
399
|
+
strict,
|
|
400
|
+
typeMetadataRegistry,
|
|
401
|
+
codecHooks,
|
|
402
|
+
storageTypes,
|
|
403
|
+
...ifDefined('normalizeDefault', normalizeDefault),
|
|
404
|
+
...ifDefined('normalizeNativeType', normalizeNativeType),
|
|
361
405
|
});
|
|
362
|
-
|
|
406
|
+
rootChildren.push(buildTableNode(tableName, tablePath, tableChildren));
|
|
363
407
|
}
|
|
364
|
-
|
|
365
|
-
const tableChildren = verifyTableChildren({
|
|
366
|
-
contractTable,
|
|
367
|
-
schemaTable,
|
|
368
|
-
tableName,
|
|
369
|
-
tablePath,
|
|
370
|
-
issues,
|
|
371
|
-
strict,
|
|
372
|
-
typeMetadataRegistry,
|
|
373
|
-
codecHooks,
|
|
374
|
-
storageTypes,
|
|
375
|
-
...ifDefined('normalizeDefault', normalizeDefault),
|
|
376
|
-
...ifDefined('normalizeNativeType', normalizeNativeType),
|
|
377
|
-
});
|
|
378
|
-
rootChildren.push(buildTableNode(tableName, tablePath, tableChildren));
|
|
379
408
|
}
|
|
380
409
|
|
|
381
410
|
if (strict) {
|
|
382
411
|
for (const tableName of Object.keys(schemaTables)) {
|
|
383
|
-
|
|
412
|
+
const claimed = namespaceIds.some(
|
|
413
|
+
(namespaceId) => contract.storage.namespaces[namespaceId]?.tables[tableName] !== undefined,
|
|
414
|
+
);
|
|
415
|
+
if (!claimed) {
|
|
416
|
+
// `namespaceId` is intentionally absent: an extra table exists in the
|
|
417
|
+
// live database but is not claimed by any contract namespace, so there
|
|
418
|
+
// is no contract coordinate to stamp here. Planners that consume this
|
|
419
|
+
// issue must handle the unstamped case (drop / quarantine by name).
|
|
384
420
|
issues.push({
|
|
385
421
|
kind: 'extra_table',
|
|
386
422
|
table: tableName,
|
|
@@ -390,7 +426,7 @@ function verifySchemaTables(options: {
|
|
|
390
426
|
status: 'fail',
|
|
391
427
|
kind: 'table',
|
|
392
428
|
name: `table ${tableName}`,
|
|
393
|
-
contractPath: `storage.tables.${tableName}`,
|
|
429
|
+
contractPath: `storage.namespaces.*.tables.${tableName}`,
|
|
394
430
|
code: 'extra_table',
|
|
395
431
|
message: `Extra table "${tableName}" found`,
|
|
396
432
|
expected: undefined,
|
|
@@ -405,9 +441,10 @@ function verifySchemaTables(options: {
|
|
|
405
441
|
}
|
|
406
442
|
|
|
407
443
|
function verifyTableChildren(options: {
|
|
408
|
-
contractTable:
|
|
444
|
+
contractTable: StorageTable;
|
|
409
445
|
schemaTable: SqlSchemaIR['tables'][string];
|
|
410
446
|
tableName: string;
|
|
447
|
+
namespaceId: string;
|
|
411
448
|
tablePath: string;
|
|
412
449
|
issues: SchemaIssue[];
|
|
413
450
|
strict: boolean;
|
|
@@ -421,6 +458,7 @@ function verifyTableChildren(options: {
|
|
|
421
458
|
contractTable,
|
|
422
459
|
schemaTable,
|
|
423
460
|
tableName,
|
|
461
|
+
namespaceId,
|
|
424
462
|
tablePath,
|
|
425
463
|
issues,
|
|
426
464
|
strict,
|
|
@@ -435,6 +473,7 @@ function verifyTableChildren(options: {
|
|
|
435
473
|
contractTable,
|
|
436
474
|
schemaTable,
|
|
437
475
|
tableName,
|
|
476
|
+
namespaceId,
|
|
438
477
|
tablePath,
|
|
439
478
|
issues,
|
|
440
479
|
strict,
|
|
@@ -452,6 +491,7 @@ function verifyTableChildren(options: {
|
|
|
452
491
|
contractTable,
|
|
453
492
|
schemaTable,
|
|
454
493
|
tableName,
|
|
494
|
+
namespaceId,
|
|
455
495
|
tablePath,
|
|
456
496
|
issues,
|
|
457
497
|
columnNodes,
|
|
@@ -463,6 +503,7 @@ function verifyTableChildren(options: {
|
|
|
463
503
|
contractTable.primaryKey,
|
|
464
504
|
schemaTable.primaryKey,
|
|
465
505
|
tableName,
|
|
506
|
+
namespaceId,
|
|
466
507
|
issues,
|
|
467
508
|
);
|
|
468
509
|
if (pkStatus === 'fail') {
|
|
@@ -494,6 +535,7 @@ function verifyTableChildren(options: {
|
|
|
494
535
|
issues.push({
|
|
495
536
|
kind: 'extra_primary_key',
|
|
496
537
|
table: tableName,
|
|
538
|
+
namespaceId,
|
|
497
539
|
message: 'Extra primary key found in database (not in contract)',
|
|
498
540
|
});
|
|
499
541
|
tableChildren.push({
|
|
@@ -518,6 +560,7 @@ function verifyTableChildren(options: {
|
|
|
518
560
|
constraintFks,
|
|
519
561
|
schemaTable.foreignKeys,
|
|
520
562
|
tableName,
|
|
563
|
+
namespaceId,
|
|
521
564
|
tablePath,
|
|
522
565
|
issues,
|
|
523
566
|
strict,
|
|
@@ -530,6 +573,7 @@ function verifyTableChildren(options: {
|
|
|
530
573
|
schemaTable.uniques,
|
|
531
574
|
schemaTable.indexes,
|
|
532
575
|
tableName,
|
|
576
|
+
namespaceId,
|
|
533
577
|
tablePath,
|
|
534
578
|
issues,
|
|
535
579
|
strict,
|
|
@@ -543,9 +587,9 @@ function verifyTableChildren(options: {
|
|
|
543
587
|
.filter(
|
|
544
588
|
(fk) =>
|
|
545
589
|
fk.index === true &&
|
|
546
|
-
!contractTable.indexes.some((idx) => arraysEqual(idx.columns, fk.columns)),
|
|
590
|
+
!contractTable.indexes.some((idx) => arraysEqual(idx.columns, fk.source.columns)),
|
|
547
591
|
)
|
|
548
|
-
.map((fk) => ({ columns: fk.columns }));
|
|
592
|
+
.map((fk) => ({ columns: fk.source.columns }));
|
|
549
593
|
const allExpectedIndexes = [...contractTable.indexes, ...fkBackingIndexes];
|
|
550
594
|
|
|
551
595
|
const indexStatuses = verifyIndexes(
|
|
@@ -553,6 +597,7 @@ function verifyTableChildren(options: {
|
|
|
553
597
|
schemaTable.indexes,
|
|
554
598
|
schemaTable.uniques,
|
|
555
599
|
tableName,
|
|
600
|
+
namespaceId,
|
|
556
601
|
tablePath,
|
|
557
602
|
issues,
|
|
558
603
|
strict,
|
|
@@ -563,9 +608,10 @@ function verifyTableChildren(options: {
|
|
|
563
608
|
}
|
|
564
609
|
|
|
565
610
|
function collectContractColumnNodes(options: {
|
|
566
|
-
contractTable:
|
|
611
|
+
contractTable: StorageTable;
|
|
567
612
|
schemaTable: SqlSchemaIR['tables'][string];
|
|
568
613
|
tableName: string;
|
|
614
|
+
namespaceId: string;
|
|
569
615
|
tablePath: string;
|
|
570
616
|
issues: SchemaIssue[];
|
|
571
617
|
strict: boolean;
|
|
@@ -579,6 +625,7 @@ function collectContractColumnNodes(options: {
|
|
|
579
625
|
contractTable,
|
|
580
626
|
schemaTable,
|
|
581
627
|
tableName,
|
|
628
|
+
namespaceId,
|
|
582
629
|
tablePath,
|
|
583
630
|
issues,
|
|
584
631
|
strict,
|
|
@@ -598,6 +645,7 @@ function collectContractColumnNodes(options: {
|
|
|
598
645
|
issues.push({
|
|
599
646
|
kind: 'missing_column',
|
|
600
647
|
table: tableName,
|
|
648
|
+
namespaceId,
|
|
601
649
|
column: columnName,
|
|
602
650
|
message: `Column "${tableName}"."${columnName}" is missing from database`,
|
|
603
651
|
});
|
|
@@ -618,6 +666,7 @@ function collectContractColumnNodes(options: {
|
|
|
618
666
|
columnNodes.push(
|
|
619
667
|
verifyColumn({
|
|
620
668
|
tableName,
|
|
669
|
+
namespaceId,
|
|
621
670
|
columnName,
|
|
622
671
|
contractColumn,
|
|
623
672
|
schemaColumn,
|
|
@@ -637,19 +686,22 @@ function collectContractColumnNodes(options: {
|
|
|
637
686
|
}
|
|
638
687
|
|
|
639
688
|
function appendExtraColumnNodes(options: {
|
|
640
|
-
contractTable:
|
|
689
|
+
contractTable: StorageTable;
|
|
641
690
|
schemaTable: SqlSchemaIR['tables'][string];
|
|
642
691
|
tableName: string;
|
|
692
|
+
namespaceId: string;
|
|
643
693
|
tablePath: string;
|
|
644
694
|
issues: SchemaIssue[];
|
|
645
695
|
columnNodes: SchemaVerificationNode[];
|
|
646
696
|
}): void {
|
|
647
|
-
const { contractTable, schemaTable, tableName, tablePath, issues, columnNodes } =
|
|
697
|
+
const { contractTable, schemaTable, tableName, namespaceId, tablePath, issues, columnNodes } =
|
|
698
|
+
options;
|
|
648
699
|
for (const [columnName, { nativeType }] of Object.entries(schemaTable.columns)) {
|
|
649
700
|
if (!contractTable.columns[columnName]) {
|
|
650
701
|
issues.push({
|
|
651
702
|
kind: 'extra_column',
|
|
652
703
|
table: tableName,
|
|
704
|
+
namespaceId,
|
|
653
705
|
column: columnName,
|
|
654
706
|
message: `Extra column "${tableName}"."${columnName}" found in database (not in contract)`,
|
|
655
707
|
});
|
|
@@ -670,8 +722,9 @@ function appendExtraColumnNodes(options: {
|
|
|
670
722
|
|
|
671
723
|
function verifyColumn(options: {
|
|
672
724
|
tableName: string;
|
|
725
|
+
namespaceId: string;
|
|
673
726
|
columnName: string;
|
|
674
|
-
contractColumn:
|
|
727
|
+
contractColumn: StorageTable['columns'][string];
|
|
675
728
|
schemaColumn: SqlSchemaIR['tables'][string]['columns'][string];
|
|
676
729
|
columnPath: string;
|
|
677
730
|
issues: SchemaIssue[];
|
|
@@ -684,6 +737,7 @@ function verifyColumn(options: {
|
|
|
684
737
|
}): SchemaVerificationNode {
|
|
685
738
|
const {
|
|
686
739
|
tableName,
|
|
740
|
+
namespaceId,
|
|
687
741
|
columnName,
|
|
688
742
|
contractColumn,
|
|
689
743
|
schemaColumn,
|
|
@@ -713,6 +767,7 @@ function verifyColumn(options: {
|
|
|
713
767
|
issues.push({
|
|
714
768
|
kind: 'type_mismatch',
|
|
715
769
|
table: tableName,
|
|
770
|
+
namespaceId,
|
|
716
771
|
column: columnName,
|
|
717
772
|
expected: contractNativeType,
|
|
718
773
|
actual: schemaNativeType,
|
|
@@ -768,6 +823,7 @@ function verifyColumn(options: {
|
|
|
768
823
|
issues.push({
|
|
769
824
|
kind: 'nullability_mismatch',
|
|
770
825
|
table: tableName,
|
|
826
|
+
namespaceId,
|
|
771
827
|
column: columnName,
|
|
772
828
|
expected: String(contractColumn.nullable),
|
|
773
829
|
actual: String(schemaColumn.nullable),
|
|
@@ -793,6 +849,7 @@ function verifyColumn(options: {
|
|
|
793
849
|
issues.push({
|
|
794
850
|
kind: 'default_missing',
|
|
795
851
|
table: tableName,
|
|
852
|
+
namespaceId,
|
|
796
853
|
column: columnName,
|
|
797
854
|
expected: defaultDescription,
|
|
798
855
|
message: `Column "${tableName}"."${columnName}" should have default ${defaultDescription} but database has no default`,
|
|
@@ -823,6 +880,7 @@ function verifyColumn(options: {
|
|
|
823
880
|
issues.push({
|
|
824
881
|
kind: 'default_mismatch',
|
|
825
882
|
table: tableName,
|
|
883
|
+
namespaceId,
|
|
826
884
|
column: columnName,
|
|
827
885
|
expected: expectedDescription,
|
|
828
886
|
actual: actualDescription,
|
|
@@ -845,6 +903,7 @@ function verifyColumn(options: {
|
|
|
845
903
|
issues.push({
|
|
846
904
|
kind: 'extra_default',
|
|
847
905
|
table: tableName,
|
|
906
|
+
namespaceId,
|
|
848
907
|
column: columnName,
|
|
849
908
|
actual: schemaColumn.default,
|
|
850
909
|
message: `Column "${tableName}"."${columnName}" has default ${schemaColumn.default} in database but contract specifies no default`,
|
|
@@ -1020,7 +1079,7 @@ function validateFrameworkComponentsForExtensions(
|
|
|
1020
1079
|
* target-specific adapters (like Postgres) to provide their own expansion logic.
|
|
1021
1080
|
*/
|
|
1022
1081
|
function renderExpectedNativeType(
|
|
1023
|
-
contractColumn:
|
|
1082
|
+
contractColumn: StorageColumn,
|
|
1024
1083
|
storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,
|
|
1025
1084
|
codecHooks: Map<string, CodecControlHooks>,
|
|
1026
1085
|
context?: {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sql-contract-serializer-qUQCnP-k.mjs","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { ContractSerializer } from '@prisma-next/framework-components/control';\nimport { SqlStorage, type SqlStorageTypeEntry } from '@prisma-next/sql-contract/types';\nimport { validateSqlContractFully } from '@prisma-next/sql-contract/validators';\nimport type { JsonObject } from '@prisma-next/utils/json';\n\nexport type SqlEntityHydrationFactory = (entry: unknown) => SqlStorageTypeEntry;\n\n/**\n * SQL family `ContractSerializer` abstract base. Carries the SQL-shared\n * deserialization pipeline:\n *\n * 1. `parseSqlContractStructure` validates the on-disk JSON envelope\n * against the SQL contract arktype schema (`validateSqlContractFully`)\n * and returns the validated flat-data shape.\n * 2. `hydrateSqlStorage` walks the validated `storage` subtree and\n * constructs the family-shared SQL Contract IR class hierarchy\n * (`SqlStorage` -> `StorageTable` -> `StorageColumn` / `PrimaryKey`\n * / …). The rest of the contract envelope is JSON-clean primitive\n * data and passes through unchanged.\n * 3. `constructTargetContract` is the target-specific extension hook;\n * defaults to identity. Targets that need to attach target-only\n * fields (e.g. target-specific derived storage fields) override it.\n *\n * Default `serializeContract` is identity over the contract — concrete\n * SQL targets ship JSON-clean class instances, so the contract value\n * can be stringified directly. The non-enumerable family-level `kind`\n * discriminator on `SqlNode` instances stays out of the persisted\n * envelope automatically. Targets that need to canonicalize on the way\n * out (key ordering, dropping computed-only fields) override\n * `serializeContract` directly.\n */\nexport abstract class SqlContractSerializerBase<TContract extends Contract<SqlStorage>>\n implements ContractSerializer<TContract>\n{\n constructor(\n private readonly entityTypeRegistry: ReadonlyMap<string, SqlEntityHydrationFactory>,\n ) {}\n\n deserializeContract(json: unknown): TContract {\n const validated = this.parseSqlContractStructure(json);\n const hydrated = this.hydrateSqlStorage(validated);\n return this.constructTargetContract(hydrated);\n }\n\n serializeContract(contract: TContract): JsonObject {\n // Targets that ship enumerable runtime-only fields must override\n // this method (mirroring `MongoTargetContractSerializer.serializeContract`)\n // to construct the persisted envelope explicitly; the default identity\n // works only when every enumerable own property belongs in the JSON.\n return contract as unknown as JsonObject;\n }\n\n /**\n * Family-shared validation pipeline (delegates to\n * `validateSqlContractFully` in `@prisma-next/sql-contract/validators`):\n * structural arktype + framework-shared domain + SQL storage\n * logical-consistency + SQL storage semantic + model ↔ storage\n * reference checks. Subclasses override to add target-specific\n * structural checks before hydration; the family default suffices\n * for targets whose contract shape is the SQL-shared shape\n * (Postgres, SQLite today).\n */\n protected parseSqlContractStructure(json: unknown): Contract<SqlStorage> {\n return validateSqlContractFully<Contract<SqlStorage>>(json);\n }\n\n /**\n * Family-shared hydration walker. Lifts the validated flat-data\n * `storage` subtree into the SQL Contract IR class hierarchy by\n * constructing a single `SqlStorage` instance — its constructor\n * cascades nested instantiation of `StorageTable`, `StorageColumn`,\n * `PrimaryKey`, `UniqueConstraint`, `Index`, `ForeignKey`,\n * `ForeignKeyReferences`, and `StorageTypeInstance`. The rest of the\n * contract envelope (target identity, hashes, capabilities, models,\n * meta, …) is JSON-clean primitive data and passes through unchanged.\n *\n * Polymorphic `storage.types` entries are normalised before the\n * `SqlStorage` constructor runs: when an entry carries an enumerable\n * string `kind`, the serializer looks up a pack-registered hydration\n * factory for that discriminator and delegates reconstruction. Entries\n * with no registered factory pass through unchanged (codec-typed JSON\n * stays codec-typed until `SqlStorage` normalises it).\n */\n protected hydrateSqlStorage(validated: Contract<SqlStorage>): Contract<SqlStorage> {\n const types = validated.storage.types;\n const hydratedTypes =\n types !== undefined\n ? Object.fromEntries(\n Object.entries(types).map(([name, entry]) => [\n name,\n this.hydrateStorageTypeEntry(entry),\n ]),\n )\n : undefined;\n\n return {\n ...validated,\n storage: new SqlStorage({\n ...validated.storage,\n ...(hydratedTypes !== undefined ? { types: hydratedTypes } : {}),\n }),\n };\n }\n\n /**\n * Per-entry hydration dispatcher for `storage.types`. When `kind` is a\n * string and the constructor registry supplies a factory for that key,\n * the factory returns the hydrated `SqlStorageTypeEntry`. Otherwise the\n * entry passes through unchanged for `SqlStorage` to normalise.\n */\n protected hydrateStorageTypeEntry(entry: SqlStorageTypeEntry): SqlStorageTypeEntry {\n if (typeof entry !== 'object' || entry === null) {\n return entry;\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind !== 'string') {\n return entry;\n }\n const factory = this.entityTypeRegistry.get(kind);\n if (factory === undefined) {\n return entry;\n }\n return factory(entry);\n }\n\n /**\n * Target-specific construction hook. Defaults to identity; targets\n * that need to wrap the hydrated contract (e.g. attach target-only\n * derived fields, narrow the contract type to a target-specific\n * subtype) override.\n */\n protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract {\n return hydrated as TContract;\n }\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { SqlContractSerializerBase } from './sql-contract-serializer-base';\n\n/**\n * Default SQL family `ContractSerializer` concretion. Inherits the\n * full SQL-shared deserialization pipeline (structural validation +\n * IR-class hydration) without pack-registered `storage.types`\n * hydration factories — targets that emit polymorphic JSON outside the\n * codec-typed envelope wire a target-specific subclass with a populated\n * registry (see Postgres). Family-level call sites instantiate this\n * default directly when no target serializer is supplied.\n */\nexport class SqlContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {\n constructor() {\n super(new Map());\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAsB,4BAAtB,MAEA;CAEqB;CADnB,YACE,oBACA;EADiB,KAAA,qBAAA;;CAGnB,oBAAoB,MAA0B;EAC5C,MAAM,YAAY,KAAK,0BAA0B,KAAK;EACtD,MAAM,WAAW,KAAK,kBAAkB,UAAU;EAClD,OAAO,KAAK,wBAAwB,SAAS;;CAG/C,kBAAkB,UAAiC;EAKjD,OAAO;;;;;;;;;;;;CAaT,0BAAoC,MAAqC;EACvE,OAAO,yBAA+C,KAAK;;;;;;;;;;;;;;;;;;;CAoB7D,kBAA4B,WAAuD;EACjF,MAAM,QAAQ,UAAU,QAAQ;EAChC,MAAM,gBACJ,UAAU,KAAA,IACN,OAAO,YACL,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,WAAW,CAC3C,MACA,KAAK,wBAAwB,MAAM,CACpC,CAAC,CACH,GACD,KAAA;EAEN,OAAO;GACL,GAAG;GACH,SAAS,IAAI,WAAW;IACtB,GAAG,UAAU;IACb,GAAI,kBAAkB,KAAA,IAAY,EAAE,OAAO,eAAe,GAAG,EAAE;IAChE,CAAC;GACH;;;;;;;;CASH,wBAAkC,OAAiD;EACjF,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,OAAO;EAET,MAAM,OAAQ,MAA6B;EAC3C,IAAI,OAAO,SAAS,UAClB,OAAO;EAET,MAAM,UAAU,KAAK,mBAAmB,IAAI,KAAK;EACjD,IAAI,YAAY,KAAA,GACd,OAAO;EAET,OAAO,QAAQ,MAAM;;;;;;;;CASvB,wBAAkC,UAA2C;EAC3E,OAAO;;;;;;;;;;;;;;ACxHX,IAAa,wBAAb,cAA2C,0BAAgD;CACzF,cAAc;EACZ,sBAAM,IAAI,KAAK,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types-DMINfGUO.d.mts","names":[],"sources":["../src/core/control-instance.ts","../src/core/migrations/types.ts"],"mappings":"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"}
|