@prisma-next/family-sql 0.12.0-dev.40 → 0.12.0-dev.41

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.
@@ -29,16 +29,16 @@ import { type Type, type } from 'arktype';
29
29
  const NamespaceRawSchema = type({
30
30
  id: 'string',
31
31
  'kind?': 'string',
32
- // Undeclared keys (`tables`, `enum`, and any pack-contributed slot maps)
33
- // intentionally pass through; the slot loop below iterates them by name.
34
- '+': 'ignore',
32
+ entries: type({
33
+ '+': 'ignore',
34
+ }),
35
35
  });
36
36
 
37
37
  function isPlainRecord(value: unknown): value is Record<string, unknown> {
38
38
  return typeof value === 'object' && value !== null && !Array.isArray(value);
39
39
  }
40
40
 
41
- export type SqlEntityHydrationFactory = (entry: unknown) => SqlStorageTypeEntry;
41
+ export type SqlEntityHydrationFactory = (entry: unknown) => unknown;
42
42
 
43
43
  /**
44
44
  * SQL family `ContractSerializer` abstract base. Carries the SQL-shared
@@ -70,7 +70,10 @@ export abstract class SqlContractSerializerBase<TContract extends Contract<SqlSt
70
70
  private readonly contractSchema: Type<unknown> | undefined;
71
71
 
72
72
  constructor(
73
- private readonly entityTypeRegistry: ReadonlyMap<string, SqlEntityHydrationFactory> = new Map(),
73
+ protected readonly entityTypeRegistry: ReadonlyMap<
74
+ string,
75
+ SqlEntityHydrationFactory
76
+ > = new Map(),
74
77
  validatorFragments?: ReadonlyMap<string, Type<unknown>>,
75
78
  ) {
76
79
  // Only build a fragments-aware contract schema when pack contributions
@@ -158,7 +161,12 @@ export abstract class SqlContractSerializerBase<TContract extends Contract<SqlSt
158
161
  const namespaceMaterialised =
159
162
  namespaceHydrated instanceof NamespaceBase
160
163
  ? namespaceHydrated
161
- : buildSqlNamespace(namespaceHydrated);
164
+ : buildSqlNamespace(
165
+ blindCast<
166
+ SqlNamespaceTablesInput,
167
+ 'hydrateSqlNamespaceEntry returns SqlNamespaceTablesInput when raw is not a NamespaceBase'
168
+ >(namespaceHydrated),
169
+ );
162
170
  return [nsId, namespaceMaterialised];
163
171
  }),
164
172
  );
@@ -172,69 +180,43 @@ export abstract class SqlContractSerializerBase<TContract extends Contract<SqlSt
172
180
  return raw;
173
181
  }
174
182
  const rawRecord = isPlainRecord(raw) ? raw : {};
183
+ if (
184
+ Object.hasOwn(rawRecord, 'tables') ||
185
+ Object.hasOwn(rawRecord, 'enum') ||
186
+ Object.hasOwn(rawRecord, 'collections')
187
+ ) {
188
+ throw new ContractValidationError(
189
+ 'Namespace envelope uses deprecated flat slot keys; expected `entries: { table? }`',
190
+ 'structural',
191
+ );
192
+ }
175
193
  const id = typeof rawRecord['id'] === 'string' ? rawRecord['id'] : nsId;
176
194
  const parsed = NamespaceRawSchema({ ...rawRecord, id });
177
195
  if (parsed instanceof type.errors) {
178
196
  const messages = parsed.map((p: { message: string }) => p.message).join('; ');
179
197
  throw new ContractValidationError(`Namespace hydration failed: ${messages}`, 'structural');
180
198
  }
181
- const result: Record<string, unknown> = { id };
182
-
183
- for (const [propertyKey, slotValue] of Object.entries(parsed)) {
184
- if (propertyKey === 'id') continue;
185
- if (slotValue === null || typeof slotValue !== 'object') continue;
186
-
187
- if (propertyKey === 'tables') {
188
- result['tables'] = Object.fromEntries(
189
- Object.entries(slotValue as Record<string, unknown>).map(([tableName, table]) => [
199
+ // Default to empty table; overwritten below if raw entries carry a table slot.
200
+ const entriesInput: { table: Record<string, StorageTable> } = { table: {} };
201
+ const entriesRaw = parsed.entries;
202
+ if (entriesRaw !== undefined && typeof entriesRaw === 'object' && entriesRaw !== null) {
203
+ const tableSlot = (entriesRaw as Record<string, unknown>)['table'];
204
+ if (tableSlot !== null && typeof tableSlot === 'object' && !Array.isArray(tableSlot)) {
205
+ entriesInput.table = Object.fromEntries(
206
+ Object.entries(tableSlot as Record<string, unknown>).map(([tableName, table]) => [
190
207
  tableName,
191
208
  table instanceof StorageTable ? table : new StorageTable(table as StorageTableInput),
192
209
  ]),
193
210
  );
194
- continue;
195
- }
196
-
197
- const hydratedSlot = Object.fromEntries(
198
- Object.entries(slotValue as Record<string, unknown>).map(([entryName, entry]) => {
199
- if (typeof entry !== 'object' || entry === null) {
200
- return [entryName, entry];
201
- }
202
- const kind = (entry as { kind?: unknown }).kind;
203
- if (typeof kind === 'string') {
204
- const factory = this.entityTypeRegistry.get(kind);
205
- if (factory !== undefined) {
206
- return [entryName, factory(entry)];
207
- }
208
- }
209
- return [entryName, entry];
210
- }),
211
- );
212
- if (Object.keys(hydratedSlot).length > 0) {
213
- result[propertyKey] = hydratedSlot;
214
- }
215
- }
216
-
217
- const enumRaw = rawRecord['enum'];
218
- if (enumRaw !== undefined && typeof enumRaw === 'object' && enumRaw !== null) {
219
- for (const entry of Object.values(enumRaw as Record<string, unknown>)) {
220
- if (typeof entry !== 'object' || entry === null) continue;
221
- const kind = (entry as { kind?: unknown }).kind;
222
- if (typeof kind === 'string' && this.entityTypeRegistry.get(kind) === undefined) {
223
- throw new ContractValidationError(
224
- `Entry kind '${kind}' has no registered hydration factory.`,
225
- 'structural',
226
- );
227
- }
228
211
  }
212
+ // Target-specific slots (e.g. postgres `type`) are left for target
213
+ // overrides to extract from the original `raw` parameter.
229
214
  }
230
215
 
231
- const tables = (result['tables'] ?? {}) as Record<string, StorageTable>;
232
- const enumSlot = result['enum'] as NonNullable<SqlNamespaceTablesInput['enum']> | undefined;
233
- return {
234
- ...result,
235
- tables,
236
- ...(enumSlot !== undefined ? { enum: enumSlot } : {}),
237
- } as SqlNamespaceTablesInput;
216
+ return blindCast<SqlNamespaceTablesInput, 'hydrated namespace tables input'>({
217
+ id,
218
+ entries: entriesInput,
219
+ });
238
220
  }
239
221
 
240
222
  protected hydrateStorageTypeEntry(entry: SqlStorageTypeEntry): SqlStorageTypeEntry {
@@ -249,7 +231,10 @@ export abstract class SqlContractSerializerBase<TContract extends Contract<SqlSt
249
231
  if (factory === undefined) {
250
232
  return entry;
251
233
  }
252
- return factory(entry);
234
+ return blindCast<
235
+ SqlStorageTypeEntry,
236
+ 'entity registry factory returns SqlStorageTypeEntry for storage.types entries'
237
+ >(factory(entry));
253
238
  }
254
239
 
255
240
  protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract {
@@ -24,6 +24,7 @@ import type {
24
24
  SqlTableIR,
25
25
  SqlUniqueIR,
26
26
  } from '@prisma-next/sql-schema-ir/types';
27
+ import { blindCast } from '@prisma-next/utils/casts';
27
28
  import { ifDefined } from '@prisma-next/utils/defined';
28
29
 
29
30
  /**
@@ -250,11 +251,11 @@ export function detectDestructiveChanges(
250
251
  for (const namespaceId of namespaceIds) {
251
252
  const fromNs = from.namespaces[namespaceId];
252
253
  const toNs = to.namespaces[namespaceId];
253
- const fromTables = fromNs?.tables;
254
+ const fromTables = fromNs?.entries.table;
254
255
  if (!fromTables) continue;
255
256
 
256
257
  for (const tableName of Object.keys(fromTables)) {
257
- const toTableRaw = toNs?.tables[tableName];
258
+ const toTableRaw = toNs?.entries.table[tableName];
258
259
  if (!(toTableRaw instanceof StorageTable)) {
259
260
  conflicts.push({
260
261
  kind: 'tableRemoved',
@@ -327,20 +328,23 @@ export function contractToSchemaIR(
327
328
  ...((storage.types ?? {}) as ResolvedStorageTypes),
328
329
  };
329
330
  for (const ns of Object.values(storage.namespaces)) {
330
- const nsEnums = (ns as { enum?: Record<string, PostgresEnumStorageEntry> }).enum;
331
+ const nsEnums = ns.entries['type'];
331
332
  if (nsEnums) {
332
333
  for (const [k, v] of Object.entries(nsEnums)) {
333
- allTypes[k] = v;
334
+ allTypes[k] = blindCast<
335
+ PostgresEnumStorageEntry | StorageTypeInstance,
336
+ 'entries.type holds postgres-specific enum entries at runtime'
337
+ >(v);
334
338
  }
335
339
  }
336
340
  }
337
341
  const storageTypes = allTypes as ResolvedStorageTypes;
338
342
  const tables: Record<string, SqlTableIR> = {};
339
343
  for (const ns of Object.values(storage.namespaces)) {
340
- for (const [tableName, tableDefRaw] of Object.entries(ns.tables)) {
344
+ for (const [tableName, tableDefRaw] of Object.entries(ns.entries.table)) {
341
345
  if (!(tableDefRaw instanceof StorageTable)) {
342
346
  throw new Error(
343
- `contractToSchemaIR: expected StorageTable at namespaces.${ns.id}.tables.${tableName}`,
347
+ `contractToSchemaIR: expected StorageTable at namespaces.${ns.id}.entries.table.${tableName}`,
344
348
  );
345
349
  }
346
350
  const tableDef = tableDefRaw;
@@ -395,7 +399,7 @@ function deriveAnnotations(
395
399
 
396
400
  // Top-level `storage.types`: codec-typed entries (vector, decimal, …) keyed
397
401
  // by bare `nativeType` (unchanged). Post-S1.B enums live in
398
- // `namespaces[*].enum`, not here; a defensive top-level enum is still
402
+ // `namespaces[*].entries.type`, not here; a defensive top-level enum is still
399
403
  // namespace/schema-qualified via the resolver under the unbound coordinate
400
404
  // so it never collides on a bare name.
401
405
  for (const typeInstance of Object.values((storage.types ?? {}) as ResolvedStorageTypes)) {
@@ -415,7 +419,7 @@ function deriveAnnotations(
415
419
  // `readExistingEnumValues` read side, so two namespaces sharing an enum name
416
420
  // (or native type) resolve to distinct live-database types.
417
421
  for (const [namespaceId, ns] of Object.entries(storage.namespaces)) {
418
- const nsEnums = (ns as { enum?: Record<string, PostgresEnumStorageEntry> }).enum;
422
+ const nsEnums = ns.entries['type'];
419
423
  if (!nsEnums) continue;
420
424
  for (const entry of Object.values(nsEnums)) {
421
425
  if (!isPostgresEnumStorageEntry(entry)) continue;
@@ -77,8 +77,8 @@ export function planFieldEventOperations(
77
77
  for (const namespaceId of namespaceIds) {
78
78
  const priorNs = priorContract?.storage.namespaces[namespaceId];
79
79
  const newNs = newContract.storage.namespaces[namespaceId];
80
- const priorTables = priorNs?.tables;
81
- const newTables = newNs?.tables;
80
+ const priorTables = priorNs?.entries.table;
81
+ const newTables = newNs?.entries.table;
82
82
 
83
83
  const tableNames = unionSorted(
84
84
  priorTables ? Object.keys(priorTables) : [],
@@ -16,7 +16,7 @@ import type {
16
16
  VerificationStatus,
17
17
  VerifyDatabaseSchemaResult,
18
18
  } from '@prisma-next/framework-components/control';
19
- import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
19
+
20
20
  import {
21
21
  isPostgresEnumStorageEntry,
22
22
  isStorageTypeInstance,
@@ -28,6 +28,7 @@ import {
28
28
  } from '@prisma-next/sql-contract/types';
29
29
  import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
30
30
  import { canonicalStringify } from '@prisma-next/utils/canonical-stringify';
31
+ import { blindCast } from '@prisma-next/utils/casts';
31
32
  import { ifDefined } from '@prisma-next/utils/defined';
32
33
  import { extractCodecControlHooks } from '../assembly';
33
34
  import type { CodecControlHooks } from '../migrations/types';
@@ -152,7 +153,10 @@ export function verifySqlSchema(options: VerifySqlSchemaOptions): VerifyDatabase
152
153
  >),
153
154
  };
154
155
  for (const ns of Object.values(contract.storage.namespaces)) {
155
- const nsEnums = (ns as { enum?: Record<string, PostgresEnumStorageEntry> }).enum;
156
+ const nsEnums = blindCast<
157
+ { readonly type?: Readonly<Record<string, PostgresEnumStorageEntry | StorageTypeInstance>> },
158
+ 'postgres target namespace entries carry a type slot beyond the family-shared SqlNamespace.entries type'
159
+ >(ns.entries).type;
156
160
  if (nsEnums) {
157
161
  for (const [k, v] of Object.entries(nsEnums)) {
158
162
  allStorageTypesMap[k] = v;
@@ -223,23 +227,9 @@ export function verifySqlSchema(options: VerifySqlSchemaOptions): VerifyDatabase
223
227
  });
224
228
  };
225
229
 
226
- // Top-level `storage.types`: codec-typed entries via codec hooks; a
227
- // defensive top-level enum is verified under the unbound coordinate.
230
+ // Top-level `storage.types`: codec-typed entries via codec hooks.
228
231
  for (const [typeName, typeInstance] of Object.entries(contract.storage.types ?? {})) {
229
- if (isPostgresEnumStorageEntry(typeInstance)) {
230
- pushTypeNode(
231
- typeName,
232
- `storage.types.${typeName}`,
233
- verifyEnumType({
234
- typeName,
235
- typeInstance,
236
- schema,
237
- resolveExistingEnumValues,
238
- namespaceId: UNBOUND_NAMESPACE_ID,
239
- }),
240
- effectiveControlPolicy(typeInstance.control, contract.defaultControlPolicy),
241
- );
242
- } else if (isStorageTypeInstance(typeInstance)) {
232
+ if (isStorageTypeInstance(typeInstance)) {
243
233
  const hook = codecHooks.get(typeInstance.codecId);
244
234
  pushTypeNode(
245
235
  typeName,
@@ -254,13 +244,13 @@ export function verifySqlSchema(options: VerifySqlSchemaOptions): VerifyDatabase
254
244
  for (const nsId of Object.keys(contract.storage.namespaces)) {
255
245
  const ns = contract.storage.namespaces[nsId];
256
246
  if (!ns) continue;
257
- const nsEnums = ns.enum;
247
+ const nsEnums = ns.entries['type'];
258
248
  if (!nsEnums) continue;
259
249
  for (const [typeName, entry] of Object.entries(nsEnums)) {
260
250
  if (!isPostgresEnumStorageEntry(entry)) continue;
261
251
  pushTypeNode(
262
252
  typeName,
263
- `storage.namespaces.${nsId}.enum.${typeName}`,
253
+ `storage.namespaces.${nsId}.entries.type.${typeName}`,
264
254
  verifyEnumType({
265
255
  typeName,
266
256
  typeInstance: entry,
@@ -443,10 +433,10 @@ function verifySchemaTables(options: {
443
433
  for (const namespaceId of namespaceIds) {
444
434
  const ns = contract.storage.namespaces[namespaceId];
445
435
  if (!ns) continue;
446
- for (const [tableName, contractTableRaw] of Object.entries(ns.tables)) {
436
+ for (const [tableName, contractTableRaw] of Object.entries(ns.entries.table)) {
447
437
  if (!(contractTableRaw instanceof StorageTable)) {
448
438
  throw new Error(
449
- `verifySqlSchema: expected StorageTable at storage.namespaces.${namespaceId}.tables.${tableName}`,
439
+ `verifySqlSchema: expected StorageTable at storage.namespaces.${namespaceId}.entries.table.${tableName}`,
450
440
  );
451
441
  }
452
442
  const contractTable = contractTableRaw;
@@ -455,7 +445,7 @@ function verifySchemaTables(options: {
455
445
  contractDefaultControl,
456
446
  );
457
447
  const schemaTable = schemaTables[tableName];
458
- const tablePath = `storage.namespaces.${namespaceId}.tables.${tableName}`;
448
+ const tablePath = `storage.namespaces.${namespaceId}.entries.table.${tableName}`;
459
449
 
460
450
  if (!schemaTable) {
461
451
  const issue: SchemaIssue = {
@@ -507,7 +497,8 @@ function verifySchemaTables(options: {
507
497
  if (strict) {
508
498
  for (const tableName of Object.keys(schemaTables)) {
509
499
  const claimed = namespaceIds.some(
510
- (namespaceId) => contract.storage.namespaces[namespaceId]?.tables[tableName] !== undefined,
500
+ (namespaceId) =>
501
+ contract.storage.namespaces[namespaceId]?.entries.table[tableName] !== undefined,
511
502
  );
512
503
  if (!claimed) {
513
504
  const extraTableControlPolicy = effectiveControlPolicy(undefined, contractDefaultControl);
@@ -523,7 +514,7 @@ function verifySchemaTables(options: {
523
514
  status: 'fail',
524
515
  kind: 'table',
525
516
  name: `table ${tableName}`,
526
- contractPath: `storage.namespaces.*.tables.${tableName}`,
517
+ contractPath: `storage.namespaces.*.entries.table.${tableName}`,
527
518
  code: 'extra_table',
528
519
  message: `Extra table "${tableName}" found`,
529
520
  expected: undefined,
@@ -1 +0,0 @@
1
- {"version":3,"file":"sql-contract-serializer-8axtK4lg.mjs","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts"],"sourcesContent":["import { ContractValidationError } from '@prisma-next/contract/contract-validation-error';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { ContractSerializer } from '@prisma-next/framework-components/control';\nimport {\n type Namespace,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport { sqlContractCanonicalizationHooks } from '@prisma-next/sql-contract/canonicalization-hooks';\nimport {\n buildSqlNamespace,\n type SqlNamespaceTablesInput,\n SqlStorage,\n type SqlStorageInput,\n type SqlStorageTypeEntry,\n SqlUnboundNamespace,\n StorageTable,\n type StorageTableInput,\n} from '@prisma-next/sql-contract/types';\nimport {\n createSqlContractSchema,\n validateSqlContractFully,\n} from '@prisma-next/sql-contract/validators';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { type Type, type } from 'arktype';\n\nconst NamespaceRawSchema = type({\n id: 'string',\n 'kind?': 'string',\n // Undeclared keys (`tables`, `enum`, and any pack-contributed slot maps)\n // intentionally pass through; the slot loop below iterates them by name.\n '+': 'ignore',\n});\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\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 private readonly contractSchema: Type<unknown> | undefined;\n\n constructor(\n private readonly entityTypeRegistry: ReadonlyMap<string, SqlEntityHydrationFactory> = new Map(),\n validatorFragments?: ReadonlyMap<string, Type<unknown>>,\n ) {\n // Only build a fragments-aware contract schema when pack contributions\n // exist. The cached module-level default in `validators.ts` covers the\n // no-contributions case and avoids per-instance schema compilation.\n this.contractSchema =\n validatorFragments !== undefined && validatorFragments.size > 0\n ? createSqlContractSchema(validatorFragments)\n : undefined;\n }\n\n deserializeContract<T extends TContract = TContract>(json: unknown): T {\n const validated = this.parseSqlContractStructure(json);\n const hydrated = this.hydrateSqlStorage(validated);\n return this.constructTargetContract(hydrated) as T;\n }\n\n serializeContract(contract: TContract): JsonObject {\n return contract as unknown as JsonObject;\n }\n\n shouldPreserveEmpty = sqlContractCanonicalizationHooks.shouldPreserveEmpty;\n\n sortStorage = sqlContractCanonicalizationHooks.sortStorage;\n\n protected parseSqlContractStructure(json: unknown): Contract<SqlStorage> {\n return validateSqlContractFully<Contract<SqlStorage>>(\n json,\n this.contractSchema !== undefined ? { contractSchema: this.contractSchema } : undefined,\n );\n }\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 const rawNamespaces = validated.storage.namespaces;\n if (rawNamespaces === undefined) {\n throw new ContractValidationError(\n 'Contract storage.namespaces is required after structural validation',\n 'structural',\n );\n }\n const hydratedNamespaces = this.hydrateSqlNamespaceMap(rawNamespaces);\n // Compatibility shim: production code that addresses `__unbound__` for table\n // metadata lookups (collection-contract, query-plan-mutations, model-accessor,\n // query-plan-meta, where-binding) uses optional chaining and tolerates absence,\n // but runtime-qualification (TML-2605) has not yet landed cross-namespace table\n // routing. Injecting the empty singleton here keeps helpers that augment the\n // deserialized JSON (e.g. buildMixedPolyContract) working by providing a slot to\n // write into. Once runtime-qualification routes table lookups by namespace, this\n // shim should be removed.\n const unbound = hydratedNamespaces[UNBOUND_NAMESPACE_ID] ?? SqlUnboundNamespace.instance;\n\n return {\n ...validated,\n storage: new SqlStorage({\n storageHash: validated.storage.storageHash,\n ...ifDefined('types', hydratedTypes),\n // Cast narrows the result of hydrateSqlNamespaceMap from the wider\n // framework `Namespace` to the SQL-family `SqlNamespace`.\n namespaces: blindCast<\n SqlStorageInput['namespaces'],\n 'hydrated SQL namespaces are SqlNamespace instances (family hydration guarantees this)'\n >({ ...hydratedNamespaces, [UNBOUND_NAMESPACE_ID]: unbound }),\n }),\n };\n }\n\n protected hydrateSqlNamespaceMap(\n namespaces: Readonly<Record<string, Namespace | Record<string, unknown>>>,\n ): Readonly<Record<string, Namespace>> {\n return Object.fromEntries(\n Object.entries(namespaces).map(([nsId, namespaceEntryRaw]) => {\n // Raw entries passed structural validation; hydrate materialises family IR class instances.\n const namespaceHydrated = this.hydrateSqlNamespaceEntry(nsId, namespaceEntryRaw);\n const namespaceMaterialised =\n namespaceHydrated instanceof NamespaceBase\n ? namespaceHydrated\n : buildSqlNamespace(namespaceHydrated);\n return [nsId, namespaceMaterialised];\n }),\n );\n }\n\n protected hydrateSqlNamespaceEntry(\n nsId: string,\n raw: Namespace | Record<string, unknown>,\n ): Namespace | SqlNamespaceTablesInput {\n if (raw instanceof NamespaceBase) {\n return raw;\n }\n const rawRecord = isPlainRecord(raw) ? raw : {};\n const id = typeof rawRecord['id'] === 'string' ? rawRecord['id'] : nsId;\n const parsed = NamespaceRawSchema({ ...rawRecord, id });\n if (parsed instanceof type.errors) {\n const messages = parsed.map((p: { message: string }) => p.message).join('; ');\n throw new ContractValidationError(`Namespace hydration failed: ${messages}`, 'structural');\n }\n const result: Record<string, unknown> = { id };\n\n for (const [propertyKey, slotValue] of Object.entries(parsed)) {\n if (propertyKey === 'id') continue;\n if (slotValue === null || typeof slotValue !== 'object') continue;\n\n if (propertyKey === 'tables') {\n result['tables'] = Object.fromEntries(\n Object.entries(slotValue as Record<string, unknown>).map(([tableName, table]) => [\n tableName,\n table instanceof StorageTable ? table : new StorageTable(table as StorageTableInput),\n ]),\n );\n continue;\n }\n\n const hydratedSlot = Object.fromEntries(\n Object.entries(slotValue as Record<string, unknown>).map(([entryName, entry]) => {\n if (typeof entry !== 'object' || entry === null) {\n return [entryName, entry];\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind === 'string') {\n const factory = this.entityTypeRegistry.get(kind);\n if (factory !== undefined) {\n return [entryName, factory(entry)];\n }\n }\n return [entryName, entry];\n }),\n );\n if (Object.keys(hydratedSlot).length > 0) {\n result[propertyKey] = hydratedSlot;\n }\n }\n\n const enumRaw = rawRecord['enum'];\n if (enumRaw !== undefined && typeof enumRaw === 'object' && enumRaw !== null) {\n for (const entry of Object.values(enumRaw as Record<string, unknown>)) {\n if (typeof entry !== 'object' || entry === null) continue;\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind === 'string' && this.entityTypeRegistry.get(kind) === undefined) {\n throw new ContractValidationError(\n `Entry kind '${kind}' has no registered hydration factory.`,\n 'structural',\n );\n }\n }\n }\n\n const tables = (result['tables'] ?? {}) as Record<string, StorageTable>;\n const enumSlot = result['enum'] as NonNullable<SqlNamespaceTablesInput['enum']> | undefined;\n return {\n ...result,\n tables,\n ...(enumSlot !== undefined ? { enum: enumSlot } : {}),\n } as SqlNamespaceTablesInput;\n }\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 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":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"verify-sql-schema-fljAiO-C.mjs","names":["d"],"sources":["../src/core/assembly.ts","../src/core/schema-verify/verifier-disposition.ts","../src/core/schema-verify/control-verify-emit.ts","../src/core/schema-verify/verify-helpers.ts","../src/core/schema-verify/verify-sql-schema.ts"],"sourcesContent":["import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport { assertUniqueCodecOwner } from '@prisma-next/framework-components/control';\nimport type { CodecControlHooks } from './migrations/types';\n\ntype CodecControlHooksMap = Record<string, CodecControlHooks>;\n\nfunction hasCodecControlHooks(descriptor: unknown): descriptor is {\n readonly id: string;\n readonly types: {\n readonly codecTypes: {\n readonly controlPlaneHooks: CodecControlHooksMap;\n };\n };\n} {\n if (typeof descriptor !== 'object' || descriptor === null) {\n return false;\n }\n const d = descriptor as { types?: { codecTypes?: { controlPlaneHooks?: unknown } } };\n const hooks = d.types?.codecTypes?.controlPlaneHooks;\n return hooks !== null && hooks !== undefined && typeof hooks === 'object';\n}\n\nexport function extractCodecControlHooks(\n descriptors: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n): Map<string, CodecControlHooks> {\n const hooks = new Map<string, CodecControlHooks>();\n const owners = new Map<string, string>();\n\n for (const descriptor of descriptors) {\n if (typeof descriptor !== 'object' || descriptor === null) {\n continue;\n }\n if (!hasCodecControlHooks(descriptor)) {\n continue;\n }\n const controlPlaneHooks = descriptor.types.codecTypes.controlPlaneHooks;\n for (const [codecId, hook] of Object.entries(controlPlaneHooks)) {\n assertUniqueCodecOwner({\n codecId,\n owners,\n descriptorId: descriptor.id,\n entityLabel: 'control hooks',\n entityOwnershipLabel: 'owner',\n });\n hooks.set(codecId, hook);\n owners.set(codecId, descriptor.id);\n }\n }\n\n return hooks;\n}\n","import type { ControlPolicy } from '@prisma-next/contract/types';\nimport type {\n SchemaIssue,\n VerifierIssueCategory,\n VerifierOutcome,\n} from '@prisma-next/framework-components/control';\nimport { dispositionForCategory } from '@prisma-next/framework-components/control';\n\n/**\n * Classifies the relational verifier issue kinds the SQL family emits (tables,\n * columns, constraints, indexes, defaults, enum types) into the target-neutral\n * categories the framework grades. The relational vocabulary lives here, in the\n * SQL domain — the framework never switches over `extra_foreign_key` and friends.\n */\nexport function classifySqlVerifierIssueKind(kind: SchemaIssue['kind']): VerifierIssueCategory {\n switch (kind) {\n case 'extra_column':\n return 'extraNestedElement';\n case 'extra_primary_key':\n case 'extra_foreign_key':\n case 'extra_unique_constraint':\n case 'extra_index':\n case 'extra_validator':\n case 'extra_default':\n return 'extraAuxiliary';\n case 'extra_table':\n return 'extraTopLevelObject';\n case 'missing_schema':\n case 'missing_table':\n case 'missing_column':\n case 'type_missing':\n case 'default_missing':\n return 'declaredMissing';\n case 'type_values_mismatch':\n case 'enum_values_changed':\n return 'valueDrift';\n case 'type_mismatch':\n case 'nullability_mismatch':\n case 'primary_key_mismatch':\n case 'foreign_key_mismatch':\n case 'unique_constraint_mismatch':\n case 'index_mismatch':\n case 'default_mismatch':\n return 'declaredIncompatible';\n }\n}\n\nexport function verifierDisposition(\n controlPolicy: ControlPolicy,\n issueKind: SchemaIssue['kind'],\n): VerifierOutcome {\n return dispositionForCategory(controlPolicy, classifySqlVerifierIssueKind(issueKind));\n}\n","import type { ControlPolicy } from '@prisma-next/contract/types';\nimport type {\n SchemaIssue,\n SchemaVerificationNode,\n VerifierOutcome,\n} from '@prisma-next/framework-components/control';\nimport { verifierDisposition } from './verifier-disposition';\n\n/**\n * Grades `issue` under `controlPolicy` and, unless suppressed, pushes both the\n * issue and a status-stamped verification node. Returns the resolved outcome so\n * the caller never re-grades the same issue.\n */\nexport function emitIssueAndNodeUnderControlPolicy(\n controlPolicy: ControlPolicy,\n issue: SchemaIssue,\n node: SchemaVerificationNode,\n issues: SchemaIssue[],\n nodes: SchemaVerificationNode[],\n): VerifierOutcome {\n const disposition = verifierDisposition(controlPolicy, issue.kind);\n if (disposition === 'suppress') {\n return disposition;\n }\n issues.push(issue);\n nodes.push({ ...node, status: disposition });\n return disposition;\n}\n\n/**\n * Grades `issue` under `controlPolicy` and, unless suppressed, pushes the issue\n * (no verification node). Returns the resolved outcome so the caller maps it to\n * a node status itself without re-grading.\n */\nexport function emitIssueUnderControlPolicy(\n controlPolicy: ControlPolicy,\n issue: SchemaIssue,\n issues: SchemaIssue[],\n): VerifierOutcome {\n const disposition = verifierDisposition(controlPolicy, issue.kind);\n if (disposition === 'suppress') {\n return disposition;\n }\n issues.push(issue);\n return disposition;\n}\n","/**\n * Pure verification helper functions for SQL schema verification.\n * These functions verify schema IR against contract requirements.\n */\n\nimport type { ControlPolicy } from '@prisma-next/contract/types';\nimport type {\n SchemaIssue,\n SchemaVerificationNode,\n} from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type {\n ForeignKey,\n Index,\n PrimaryKey,\n UniqueConstraint,\n} from '@prisma-next/sql-contract/types';\nimport type { SqlForeignKeyIR, SqlIndexIR, SqlUniqueIR } from '@prisma-next/sql-schema-ir/types';\nimport {\n emitIssueAndNodeUnderControlPolicy,\n emitIssueUnderControlPolicy,\n} from './control-verify-emit';\n\nfunction indexOptionsLooselyEqual(\n a: Record<string, unknown> | undefined,\n b: Record<string, unknown> | undefined,\n): boolean {\n const aKeys = a ? Object.keys(a).sort() : [];\n const bKeys = b ? Object.keys(b).sort() : [];\n if (aKeys.length !== bKeys.length) return false;\n for (let i = 0; i < aKeys.length; i += 1) {\n if (aKeys[i] !== bKeys[i]) return false;\n }\n if (aKeys.length === 0) return true;\n for (const key of aKeys) {\n // Postgres introspection returns reloptions values as raw strings (e.g.\n // `'70'`, `'false'`), while contract option leaves are typed (number,\n // boolean, string). Compare via String() so a contract `fillfactor: 70`\n // matches an introspected `fillfactor: '70'` without a spurious mismatch.\n if (\n String((a as Record<string, unknown>)[key]) !== String((b as Record<string, unknown>)[key])\n ) {\n return false;\n }\n }\n return true;\n}\n\nfunction indexExtrasMatch(\n contractIndex: Index,\n schemaIndex: { readonly type?: string; readonly options?: Record<string, unknown> },\n): boolean {\n if ((contractIndex.type ?? null) !== (schemaIndex.type ?? null)) return false;\n return indexOptionsLooselyEqual(contractIndex.options, schemaIndex.options);\n}\n\n/**\n * Compares two arrays of strings for equality (order-sensitive).\n */\nexport function arraysEqual(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n// ============================================================================\n// Semantic Satisfaction Predicates\n// ============================================================================\n// These predicates implement the \"stronger satisfies weaker\" logic for storage\n// objects. They are used by both verification and migration planning to ensure\n// consistent behavior across the control plane.\n\n/**\n * Checks if a unique constraint requirement is satisfied by the given columns.\n *\n * Semantic satisfaction: a unique constraint requirement can be satisfied by:\n * - A unique constraint with the same columns, OR\n * - A unique index with the same columns\n *\n * @param uniques - The unique constraints in the schema table\n * @param indexes - The indexes in the schema table\n * @param columns - The columns required by the unique constraint\n * @returns true if the requirement is satisfied\n */\nexport function isUniqueConstraintSatisfied(\n uniques: readonly SqlUniqueIR[],\n indexes: readonly SqlIndexIR[],\n columns: readonly string[],\n): boolean {\n // Check for matching unique constraint\n const hasConstraint = uniques.some((unique) => arraysEqual(unique.columns, columns));\n if (hasConstraint) {\n return true;\n }\n // Check for matching unique index (semantic satisfaction)\n return indexes.some((index) => index.unique && arraysEqual(index.columns, columns));\n}\n\n/**\n * Checks if an index requirement is satisfied by the given columns.\n *\n * Semantic satisfaction: a non-unique index requirement can be satisfied by:\n * - Any index (unique or non-unique) with the same columns, OR\n * - A unique constraint with the same columns (stronger satisfies weaker)\n *\n * @param indexes - The indexes in the schema table\n * @param uniques - The unique constraints in the schema table\n * @param columns - The columns required by the index\n * @returns true if the requirement is satisfied\n */\nexport function isIndexSatisfied(\n indexes: readonly SqlIndexIR[],\n uniques: readonly SqlUniqueIR[],\n columns: readonly string[],\n): boolean {\n // Check for any matching index (unique or non-unique)\n const hasMatchingIndex = indexes.some((index) => arraysEqual(index.columns, columns));\n if (hasMatchingIndex) {\n return true;\n }\n // Check for matching unique constraint (semantic satisfaction)\n return uniques.some((unique) => arraysEqual(unique.columns, columns));\n}\n\n/**\n * Verifies primary key matches between contract and schema.\n * Returns 'pass' or 'fail'.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyPrimaryKey(\n contractPK: PrimaryKey,\n schemaPK: PrimaryKey | undefined,\n tableName: string,\n namespaceId: string,\n tableControlPolicy: ControlPolicy,\n issues: SchemaIssue[],\n): 'pass' | 'warn' | 'fail' {\n if (!schemaPK) {\n const issue: SchemaIssue = {\n kind: 'primary_key_mismatch',\n table: tableName,\n namespaceId,\n expected: contractPK.columns.join(', '),\n message: `Table \"${tableName}\" is missing primary key`,\n };\n const outcome = emitIssueUnderControlPolicy(tableControlPolicy, issue, issues);\n return outcome === 'suppress' ? 'pass' : outcome;\n }\n\n if (!arraysEqual(contractPK.columns, schemaPK.columns)) {\n const issue: SchemaIssue = {\n kind: 'primary_key_mismatch',\n table: tableName,\n namespaceId,\n expected: contractPK.columns.join(', '),\n actual: schemaPK.columns.join(', '),\n message: `Table \"${tableName}\" has primary key mismatch: expected columns [${contractPK.columns.join(', ')}], got [${schemaPK.columns.join(', ')}]`,\n };\n const outcome = emitIssueUnderControlPolicy(tableControlPolicy, issue, issues);\n return outcome === 'suppress' ? 'pass' : outcome;\n }\n\n return 'pass';\n}\n\n/**\n * Verifies foreign keys match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + columns + referenced table + referenced columns).\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyForeignKeys(\n contractFKs: readonly ForeignKey[],\n schemaFKs: readonly SqlForeignKeyIR[],\n tableName: string,\n namespaceId: string,\n tablePath: string,\n tableControlPolicy: ControlPolicy,\n issues: SchemaIssue[],\n strict: boolean,\n): SchemaVerificationNode[] {\n const nodes: SchemaVerificationNode[] = [];\n\n // Check each contract FK exists in schema\n for (const contractFK of contractFKs) {\n const fkPath = `${tablePath}.foreignKeys[${contractFK.source.columns.join(',')}]`;\n const matchingFK = schemaFKs.find((fk) => {\n // When the schema FK carries referencedSchema (populated by the Postgres\n // adapter for cross-schema FKs), compare the full (namespace, table) pair\n // against the contract FK's target coordinate. When referencedSchema is\n // absent (same-schema FKs, older introspection, or hand-crafted test\n // fixtures), fall back to table-name-only comparison so same-namespace\n // contracts continue to verify correctly.\n const tablesMatch =\n fk.referencedSchema !== undefined && contractFK.target.namespaceId !== UNBOUND_NAMESPACE_ID\n ? fk.referencedSchema === contractFK.target.namespaceId &&\n fk.referencedTable === contractFK.target.tableName\n : fk.referencedTable === contractFK.target.tableName;\n return (\n arraysEqual(fk.columns, contractFK.source.columns) &&\n tablesMatch &&\n arraysEqual(fk.referencedColumns, contractFK.target.columns)\n );\n });\n\n if (!matchingFK) {\n const issue: SchemaIssue = {\n kind: 'foreign_key_mismatch',\n table: tableName,\n namespaceId,\n expected: `${contractFK.source.columns.join(', ')} -> ${contractFK.target.tableName}(${contractFK.target.columns.join(', ')})`,\n message: `Table \"${tableName}\" is missing foreign key: ${contractFK.source.columns.join(', ')} -> ${contractFK.target.tableName}(${contractFK.target.columns.join(', ')})`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.source.columns.join(', ')})`,\n contractPath: fkPath,\n code: 'foreign_key_mismatch',\n message: 'Foreign key missing',\n expected: contractFK,\n actual: undefined,\n children: [],\n },\n issues,\n nodes,\n );\n } else {\n const actionMismatches = getReferentialActionMismatches(contractFK, matchingFK);\n if (actionMismatches.length > 0) {\n const combinedMessage = actionMismatches.map((m) => m.message).join('; ');\n const combinedExpected = actionMismatches.map((m) => m.expected).join(', ');\n const combinedActual = actionMismatches.map((m) => m.actual).join(', ');\n const issue: SchemaIssue = {\n kind: 'foreign_key_mismatch',\n table: tableName,\n namespaceId,\n indexOrConstraint: matchingFK.name ?? `fk(${contractFK.source.columns.join(',')})`,\n expected: combinedExpected,\n actual: combinedActual,\n message: `Table \"${tableName}\" foreign key ${contractFK.source.columns.join(', ')} -> ${contractFK.target.tableName}: ${combinedMessage}`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.source.columns.join(', ')})`,\n contractPath: fkPath,\n code: 'foreign_key_mismatch',\n message: combinedMessage,\n expected: contractFK,\n actual: matchingFK,\n children: [],\n },\n issues,\n nodes,\n );\n } else {\n nodes.push({\n status: 'pass',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.source.columns.join(', ')})`,\n contractPath: fkPath,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n }\n\n // Check for extra FKs in strict mode\n if (strict) {\n for (const schemaFK of schemaFKs) {\n const matchingFK = contractFKs.find((fk) => {\n const tablesMatch =\n schemaFK.referencedSchema !== undefined && fk.target.namespaceId !== UNBOUND_NAMESPACE_ID\n ? schemaFK.referencedSchema === fk.target.namespaceId &&\n schemaFK.referencedTable === fk.target.tableName\n : schemaFK.referencedTable === fk.target.tableName;\n return (\n arraysEqual(fk.source.columns, schemaFK.columns) &&\n tablesMatch &&\n arraysEqual(fk.target.columns, schemaFK.referencedColumns)\n );\n });\n\n if (!matchingFK) {\n const issue: SchemaIssue = {\n kind: 'extra_foreign_key',\n table: tableName,\n namespaceId,\n indexOrConstraint: schemaFK.name ?? `fk(${schemaFK.columns.join(',')})`,\n message: `Extra foreign key found in database (not in contract): ${schemaFK.columns.join(', ')} -> ${schemaFK.referencedTable}(${schemaFK.referencedColumns.join(', ')})`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'foreignKey',\n name: `foreignKey(${schemaFK.columns.join(', ')})`,\n contractPath: `${tablePath}.foreignKeys[${schemaFK.columns.join(',')}]`,\n code: 'extra_foreign_key',\n message: 'Extra foreign key found',\n expected: undefined,\n actual: schemaFK,\n children: [],\n },\n issues,\n nodes,\n );\n }\n }\n }\n\n return nodes;\n}\n\n/**\n * Verifies unique constraints match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * A unique constraint requirement can be satisfied by either:\n * - A unique constraint with the same columns, or\n * - A unique index with the same columns\n *\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyUniqueConstraints(\n contractUniques: readonly UniqueConstraint[],\n schemaUniques: readonly SqlUniqueIR[],\n schemaIndexes: readonly SqlIndexIR[],\n tableName: string,\n namespaceId: string,\n tablePath: string,\n tableControlPolicy: ControlPolicy,\n issues: SchemaIssue[],\n strict: boolean,\n): SchemaVerificationNode[] {\n const nodes: SchemaVerificationNode[] = [];\n\n // Check each contract unique exists in schema\n for (const contractUnique of contractUniques) {\n const uniquePath = `${tablePath}.uniques[${contractUnique.columns.join(',')}]`;\n\n // First check for a matching unique constraint\n const matchingUnique = schemaUniques.find((u) =>\n arraysEqual(u.columns, contractUnique.columns),\n );\n\n // If no matching constraint, check for a unique index with the same columns\n const matchingUniqueIndex =\n !matchingUnique &&\n schemaIndexes.find((idx) => idx.unique && arraysEqual(idx.columns, contractUnique.columns));\n\n if (!matchingUnique && !matchingUniqueIndex) {\n const issue: SchemaIssue = {\n kind: 'unique_constraint_mismatch',\n table: tableName,\n namespaceId,\n expected: contractUnique.columns.join(', '),\n message: `Table \"${tableName}\" is missing unique constraint: ${contractUnique.columns.join(', ')}`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'unique',\n name: `unique(${contractUnique.columns.join(', ')})`,\n contractPath: uniquePath,\n code: 'unique_constraint_mismatch',\n message: 'Unique constraint missing',\n expected: contractUnique,\n actual: undefined,\n children: [],\n },\n issues,\n nodes,\n );\n } else {\n nodes.push({\n status: 'pass',\n kind: 'unique',\n name: `unique(${contractUnique.columns.join(', ')})`,\n contractPath: uniquePath,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n\n if (strict) {\n for (const schemaUnique of schemaUniques) {\n const matchingUnique = contractUniques.find((u) =>\n arraysEqual(u.columns, schemaUnique.columns),\n );\n\n if (!matchingUnique) {\n const issue: SchemaIssue = {\n kind: 'extra_unique_constraint',\n table: tableName,\n namespaceId,\n indexOrConstraint: schemaUnique.name ?? `unique(${schemaUnique.columns.join(',')})`,\n message: `Extra unique constraint found in database (not in contract): ${schemaUnique.columns.join(', ')}`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'unique',\n name: `unique(${schemaUnique.columns.join(', ')})`,\n contractPath: `${tablePath}.uniques[${schemaUnique.columns.join(',')}]`,\n code: 'extra_unique_constraint',\n message: 'Extra unique constraint found',\n expected: undefined,\n actual: schemaUnique,\n children: [],\n },\n issues,\n nodes,\n );\n }\n }\n }\n\n return nodes;\n}\n\n/**\n * Verifies indexes match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * A non-unique index requirement can be satisfied by either:\n * - A non-unique index with the same columns, or\n * - A unique index with the same columns (stronger satisfies weaker)\n *\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyIndexes(\n contractIndexes: readonly Index[],\n schemaIndexes: readonly SqlIndexIR[],\n schemaUniques: readonly SqlUniqueIR[],\n tableName: string,\n namespaceId: string,\n tablePath: string,\n tableControlPolicy: ControlPolicy,\n issues: SchemaIssue[],\n strict: boolean,\n): SchemaVerificationNode[] {\n const nodes: SchemaVerificationNode[] = [];\n\n // Check each contract index exists in schema\n for (const contractIndex of contractIndexes) {\n const indexPath = `${tablePath}.indexes[${contractIndex.columns.join(',')}]`;\n\n // Check for any matching index (unique or non-unique)\n // A unique index can satisfy a non-unique index requirement (stronger satisfies weaker)\n const matchingIndex = schemaIndexes.find(\n (idx) =>\n arraysEqual(idx.columns, contractIndex.columns) && indexExtrasMatch(contractIndex, idx),\n );\n\n // Also check if a unique constraint satisfies the index requirement.\n // Unique constraints carry no type/options of their own, so they can only\n // satisfy a contract index that doesn't request a specific type/options.\n const matchingUniqueConstraint =\n !matchingIndex &&\n contractIndex.type === undefined &&\n contractIndex.options === undefined &&\n schemaUniques.find((u) => arraysEqual(u.columns, contractIndex.columns));\n\n if (!matchingIndex && !matchingUniqueConstraint) {\n const issue: SchemaIssue = {\n kind: 'index_mismatch',\n table: tableName,\n namespaceId,\n expected: contractIndex.columns.join(', '),\n message: `Table \"${tableName}\" is missing index: ${contractIndex.columns.join(', ')}`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'index',\n name: `index(${contractIndex.columns.join(', ')})`,\n contractPath: indexPath,\n code: 'index_mismatch',\n message: 'Index missing',\n expected: contractIndex,\n actual: undefined,\n children: [],\n },\n issues,\n nodes,\n );\n } else {\n nodes.push({\n status: 'pass',\n kind: 'index',\n name: `index(${contractIndex.columns.join(', ')})`,\n contractPath: indexPath,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n\n if (strict) {\n for (const schemaIndex of schemaIndexes) {\n if (schemaIndex.unique) {\n continue;\n }\n\n const matchingIndex = contractIndexes.find(\n (idx) =>\n arraysEqual(idx.columns, schemaIndex.columns) && indexExtrasMatch(idx, schemaIndex),\n );\n\n if (!matchingIndex) {\n const issue: SchemaIssue = {\n kind: 'extra_index',\n table: tableName,\n namespaceId,\n indexOrConstraint: schemaIndex.name ?? `idx(${schemaIndex.columns.join(',')})`,\n message: `Extra index found in database (not in contract): ${schemaIndex.columns.join(', ')}`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'index',\n name: `index(${schemaIndex.columns.join(', ')})`,\n contractPath: `${tablePath}.indexes[${schemaIndex.columns.join(',')}]`,\n code: 'extra_index',\n message: 'Extra index found',\n expected: undefined,\n actual: schemaIndex,\n children: [],\n },\n issues,\n nodes,\n );\n }\n }\n }\n\n return nodes;\n}\n\n/**\n * Computes counts of pass/warn/fail nodes by traversing the tree.\n */\nexport function computeCounts(node: SchemaVerificationNode): {\n pass: number;\n warn: number;\n fail: number;\n totalNodes: number;\n} {\n let pass = 0;\n let warn = 0;\n let fail = 0;\n\n function traverse(n: SchemaVerificationNode): void {\n if (n.status === 'pass') {\n pass++;\n } else if (n.status === 'warn') {\n warn++;\n } else if (n.status === 'fail') {\n fail++;\n }\n\n if (n.children) {\n for (const child of n.children) {\n traverse(child);\n }\n }\n }\n\n traverse(node);\n\n return {\n pass,\n warn,\n fail,\n totalNodes: pass + warn + fail,\n };\n}\n\n/**\n * Compares referential actions between a contract FK and a schema FK.\n * Only compares when the contract FK explicitly specifies onDelete or onUpdate.\n * Returns all mismatches (both onDelete and onUpdate) so both are reported at once.\n *\n * Note: 'noAction' in the contract is semantically equivalent to undefined in the\n * schema IR, because the introspection adapter omits 'NO ACTION' (the database default)\n * to keep the IR sparse. We normalize both sides before comparing.\n */\nfunction getReferentialActionMismatches(\n contractFK: ForeignKey,\n schemaFK: SqlForeignKeyIR,\n): ReadonlyArray<{ expected: string; actual: string; message: string }> {\n const mismatches: Array<{ expected: string; actual: string; message: string }> = [];\n\n const contractOnDelete = normalizeReferentialAction(contractFK.onDelete);\n const schemaOnDelete = normalizeReferentialAction(schemaFK.onDelete);\n if (contractOnDelete !== undefined && contractOnDelete !== schemaOnDelete) {\n mismatches.push({\n expected: `onDelete: ${contractFK.onDelete}`,\n actual: `onDelete: ${schemaFK.onDelete ?? 'noAction (default)'}`,\n message: `onDelete mismatch: expected ${contractFK.onDelete}, got ${schemaFK.onDelete ?? 'noAction (default)'}`,\n });\n }\n\n const contractOnUpdate = normalizeReferentialAction(contractFK.onUpdate);\n const schemaOnUpdate = normalizeReferentialAction(schemaFK.onUpdate);\n if (contractOnUpdate !== undefined && contractOnUpdate !== schemaOnUpdate) {\n mismatches.push({\n expected: `onUpdate: ${contractFK.onUpdate}`,\n actual: `onUpdate: ${schemaFK.onUpdate ?? 'noAction (default)'}`,\n message: `onUpdate mismatch: expected ${contractFK.onUpdate}, got ${schemaFK.onUpdate ?? 'noAction (default)'}`,\n });\n }\n\n return mismatches;\n}\n\n/**\n * Normalizes a referential action value for comparison.\n * 'noAction' is the database default and equivalent to undefined (omitted) in the sparse IR.\n */\nfunction normalizeReferentialAction(action: string | undefined): string | undefined {\n return action === 'noAction' ? undefined : action;\n}\n","/**\n * Pure SQL schema verification function.\n *\n * This module provides a pure function that verifies a SqlSchemaIR against\n * a Contract without requiring a database connection. It can be reused\n * by migration planners and other tools that need to compare schema states.\n */\n\nimport type { ColumnDefault, Contract, ControlPolicy } from '@prisma-next/contract/types';\nimport { effectiveControlPolicy } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n OperationContext,\n SchemaIssue,\n SchemaVerificationNode,\n VerificationStatus,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport {\n isPostgresEnumStorageEntry,\n isStorageTypeInstance,\n type PostgresEnumStorageEntry,\n type SqlStorage,\n type StorageColumn,\n StorageTable,\n type StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { canonicalStringify } from '@prisma-next/utils/canonical-stringify';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { extractCodecControlHooks } from '../assembly';\nimport type { CodecControlHooks } from '../migrations/types';\nimport { emitIssueAndNodeUnderControlPolicy } from './control-verify-emit';\nimport { verifierDisposition } from './verifier-disposition';\nimport {\n arraysEqual,\n computeCounts,\n verifyForeignKeys,\n verifyIndexes,\n verifyPrimaryKey,\n verifyUniqueConstraints,\n} from './verify-helpers';\n\nexport type ColumnsCompatible = (declared: string, live: string) => boolean;\n\n/**\n * Function type for normalizing raw database default expressions into ColumnDefault.\n * Target-specific implementations handle database dialect differences.\n */\nexport type DefaultNormalizer = (\n rawDefault: string,\n nativeType: string,\n) => ColumnDefault | undefined;\n\n/**\n * Function type for normalizing schema native types to canonical form for comparison.\n * Target-specific implementations handle dialect-specific type name variations\n * (e.g., Postgres 'varchar' → 'character varying', 'timestamptz' normalization).\n */\nexport type NativeTypeNormalizer = (nativeType: string) => string;\n\n/**\n * Options for the pure schema verification function.\n */\nexport interface VerifySqlSchemaOptions {\n /** The validated SQL contract to verify against */\n readonly contract: Contract<SqlStorage>;\n /** The schema IR from introspection (or another source) */\n readonly schema: SqlSchemaIR;\n /** Whether to run in strict mode (detects extra tables/columns) */\n readonly strict: boolean;\n /** Optional operation context for metadata */\n readonly context?: OperationContext;\n /** Type metadata registry for codec consistency warnings */\n readonly typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n /**\n * Active framework components participating in this composition.\n * All components must have matching familyId ('sql') and targetId.\n */\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Optional target-specific normalizer for raw database default expressions.\n * When provided, schema defaults (raw strings) are normalized before comparison\n * with contract defaults (ColumnDefault objects).\n */\n readonly normalizeDefault?: DefaultNormalizer;\n /**\n * Optional target-specific normalizer for schema native type names.\n * When provided, schema native types are normalized before comparison\n * with contract native types (e.g., Postgres 'varchar' → 'character varying').\n */\n readonly normalizeNativeType?: NativeTypeNormalizer;\n /**\n * Bridging adapter that resolves the existing values for a `PostgresEnumStorageEntry`\n * (looked up by its native type) from the introspected schema IR. Targets\n * supply this so the family-level verifier can walk `PostgresEnumStorageEntry` instances\n * natively without reaching into target-specific `schema.annotations`\n * shapes itself.\n *\n * Returning `null` indicates the type is missing from the database; the\n * verifier emits a `type_missing` issue. A non-null array triggers a\n * value-set comparison against the contract's `PostgresEnumStorageEntry.values`.\n */\n readonly resolveExistingEnumValues?: (\n schema: SqlSchemaIR,\n enumType: PostgresEnumStorageEntry,\n namespaceId: string,\n ) => readonly string[] | null;\n /**\n * Target-supplied compatible-shape relation for `external` column type checks.\n * Defaults to exact string equality when omitted.\n */\n readonly columnsCompatible?: ColumnsCompatible;\n}\n\n/**\n * Verifies that a SqlSchemaIR matches a Contract.\n *\n * This is a pure function that does NOT perform any database I/O.\n * It takes an already-introspected schema IR and compares it against\n * the contract requirements.\n *\n * @param options - Verification options\n * @returns VerifyDatabaseSchemaResult with verification tree and issues\n */\nexport function verifySqlSchema(options: VerifySqlSchemaOptions): VerifyDatabaseSchemaResult {\n const {\n contract,\n schema,\n strict,\n context,\n typeMetadataRegistry,\n normalizeDefault,\n normalizeNativeType,\n resolveExistingEnumValues,\n columnsCompatible,\n } = options;\n const startTime = Date.now();\n\n // Extract codec control hooks once at entry point for reuse\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n\n const { contractStorageHash, contractProfileHash, contractTarget } =\n extractContractMetadata(contract);\n // Column `typeRef` resolution map: keyed by the bare contract type name\n // (columns carry bare `typeRef`s). Used by `verifySchemaTables` only.\n const allStorageTypesMap: Record<string, PostgresEnumStorageEntry | StorageTypeInstance> = {\n ...((contract.storage.types ?? {}) as Record<\n string,\n PostgresEnumStorageEntry | StorageTypeInstance\n >),\n };\n for (const ns of Object.values(contract.storage.namespaces)) {\n const nsEnums = (ns as { enum?: Record<string, PostgresEnumStorageEntry> }).enum;\n if (nsEnums) {\n for (const [k, v] of Object.entries(nsEnums)) {\n allStorageTypesMap[k] = v;\n }\n }\n }\n const storageTypes = allStorageTypesMap as Readonly<\n Record<string, PostgresEnumStorageEntry | StorageTypeInstance>\n >;\n const { issues, rootChildren } = verifySchemaTables({\n contract,\n schema,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n ...ifDefined('columnsCompatible', columnsCompatible),\n });\n\n validateFrameworkComponentsForExtensions(contract, options.frameworkComponents);\n\n // Verify storage type instances. Codec-typed `storage.types` entries dispatch\n // through the generic codec-hook `verifyType` path (keyed by bare name).\n // `PostgresEnumStorageEntry` enums are walked natively *per namespace* (using\n // the bridging adapter `resolveExistingEnumValues`) so two namespaces that\n // declare an enum with the same name are each verified with their own\n // namespace coordinate — a bare-name aggregation would collapse them\n // (last-write-wins) and verify only one.\n const typeNodes: SchemaVerificationNode[] = [];\n // Storage-type findings dispatch through the same control policy as tables\n // and columns: each issue's disposition (fail / warn / suppress) is resolved\n // from the type's effective control so an `external`/`observed` enum no longer\n // hard-fails on value drift. `suppress` drops the issue entirely; the node\n // status is the worst surviving disposition.\n const pushTypeNode = (\n typeName: string,\n contractPath: string,\n typeIssues: readonly SchemaIssue[],\n controlPolicy: ControlPolicy,\n ): void => {\n let status: VerificationStatus = 'pass';\n let code = '';\n let emitted = 0;\n for (const issue of typeIssues) {\n const disposition = verifierDisposition(controlPolicy, issue.kind);\n if (disposition === 'suppress') continue;\n issues.push(issue);\n emitted += 1;\n if (code === '') code = issue.kind;\n if (disposition === 'fail') {\n status = 'fail';\n } else if (disposition === 'warn' && status !== 'fail') {\n status = 'warn';\n }\n }\n typeNodes.push({\n status,\n kind: 'storageType',\n name: `type ${typeName}`,\n contractPath,\n code: status === 'pass' ? '' : code,\n message: emitted > 0 ? `${emitted} issue${emitted === 1 ? '' : 's'}` : '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n };\n\n // Top-level `storage.types`: codec-typed entries via codec hooks; a\n // defensive top-level enum is verified under the unbound coordinate.\n for (const [typeName, typeInstance] of Object.entries(contract.storage.types ?? {})) {\n if (isPostgresEnumStorageEntry(typeInstance)) {\n pushTypeNode(\n typeName,\n `storage.types.${typeName}`,\n verifyEnumType({\n typeName,\n typeInstance,\n schema,\n resolveExistingEnumValues,\n namespaceId: UNBOUND_NAMESPACE_ID,\n }),\n effectiveControlPolicy(typeInstance.control, contract.defaultControlPolicy),\n );\n } else if (isStorageTypeInstance(typeInstance)) {\n const hook = codecHooks.get(typeInstance.codecId);\n pushTypeNode(\n typeName,\n `storage.types.${typeName}`,\n hook?.verifyType ? hook.verifyType({ typeName, typeInstance, schema }) : [],\n effectiveControlPolicy(undefined, contract.defaultControlPolicy),\n );\n }\n }\n\n // Namespace-scoped enums, verified per `(namespaceId, typeName)`.\n for (const nsId of Object.keys(contract.storage.namespaces)) {\n const ns = contract.storage.namespaces[nsId];\n if (!ns) continue;\n const nsEnums = ns.enum;\n if (!nsEnums) continue;\n for (const [typeName, entry] of Object.entries(nsEnums)) {\n if (!isPostgresEnumStorageEntry(entry)) continue;\n pushTypeNode(\n typeName,\n `storage.namespaces.${nsId}.enum.${typeName}`,\n verifyEnumType({\n typeName,\n typeInstance: entry,\n schema,\n resolveExistingEnumValues,\n namespaceId: nsId,\n }),\n effectiveControlPolicy(entry.control, contract.defaultControlPolicy),\n );\n }\n }\n\n if (typeNodes.length > 0) {\n const typesStatus: VerificationStatus = typeNodes.some((n) => n.status === 'fail')\n ? 'fail'\n : typeNodes.some((n) => n.status === 'warn')\n ? 'warn'\n : 'pass';\n rootChildren.push({\n status: typesStatus,\n kind: 'storageTypes',\n name: 'types',\n contractPath: 'storage.types',\n code: typesStatus === 'fail' ? 'type_mismatch' : '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: typeNodes,\n });\n }\n\n const root = buildRootNode(rootChildren);\n\n // Compute counts\n const counts = computeCounts(root);\n\n // Set ok flag\n const ok = counts.fail === 0;\n\n // Set code\n const code = ok ? undefined : 'PN-SCHEMA-0001';\n\n // Set summary\n const summary = ok\n ? 'Database schema satisfies contract'\n : `Database schema does not satisfy contract (${counts.fail} failure${counts.fail === 1 ? '' : 's'})`;\n\n const totalTime = Date.now() - startTime;\n\n return {\n ok,\n ...ifDefined('code', code),\n summary,\n contract: {\n storageHash: contractStorageHash,\n ...ifDefined('profileHash', contractProfileHash),\n },\n target: {\n expected: contractTarget,\n actual: contractTarget,\n },\n schema: {\n issues,\n root,\n counts,\n },\n meta: {\n strict,\n ...ifDefined('contractPath', context?.contractPath),\n ...ifDefined('configPath', context?.configPath),\n },\n timings: {\n total: totalTime,\n },\n };\n}\n\n/**\n * Native verification walk for `PostgresEnumStorageEntry` instances (no codec hook).\n *\n * Bridges the native `PostgresEnumStorageEntry.values` against the introspected schema\n * IR via the target-supplied `resolveExistingEnumValues` adapter. Without an\n * adapter, the verifier conservatively reports the enum as missing — there\n * is no other way for the family layer to learn about live enum types.\n */\nfunction verifyEnumType(options: {\n readonly typeName: string;\n readonly typeInstance: PostgresEnumStorageEntry;\n readonly schema: SqlSchemaIR;\n readonly namespaceId: string;\n readonly resolveExistingEnumValues?:\n | ((\n schema: SqlSchemaIR,\n enumType: PostgresEnumStorageEntry,\n namespaceId: string,\n ) => readonly string[] | null)\n | undefined;\n}): readonly SchemaIssue[] {\n const { typeName, typeInstance, schema, namespaceId, resolveExistingEnumValues } = options;\n const desired = typeInstance.values;\n const existing = resolveExistingEnumValues?.(schema, typeInstance, namespaceId) ?? null;\n if (!existing) {\n return [\n {\n kind: 'type_missing',\n typeName,\n namespaceId,\n message: `Type \"${typeName}\" is missing from database`,\n },\n ];\n }\n if (arraysEqual(existing, desired)) {\n return [];\n }\n const existingSet = new Set(existing);\n const desiredSet = new Set(desired);\n const addedValues = desired.filter((v) => !existingSet.has(v));\n const removedValues = existing.filter((v) => !desiredSet.has(v));\n const message =\n removedValues.length === 0\n ? `Enum type \"${typeName}\" needs new values: ${addedValues.join(', ')}`\n : `Enum type \"${typeName}\" values changed (requires rebuild): +[${addedValues.join(', ')}] -[${removedValues.join(', ')}]`;\n return [\n {\n kind: 'enum_values_changed' as const,\n namespaceId,\n typeName,\n addedValues,\n removedValues,\n message,\n },\n ];\n}\n\nfunction extractContractMetadata(contract: Contract<SqlStorage>): {\n contractStorageHash: SqlStorage['storageHash'];\n contractProfileHash?: Contract<SqlStorage>['profileHash'] | undefined;\n contractTarget: Contract<SqlStorage>['target'];\n} {\n return {\n contractStorageHash: contract.storage.storageHash,\n contractProfileHash:\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : undefined,\n contractTarget: contract.target,\n };\n}\n\nfunction verifySchemaTables(options: {\n contract: Contract<SqlStorage>;\n schema: SqlSchemaIR;\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n columnsCompatible?: ColumnsCompatible;\n}): { issues: SchemaIssue[]; rootChildren: SchemaVerificationNode[] } {\n const {\n contract,\n schema,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n columnsCompatible,\n } = options;\n const contractDefaultControl = contract.defaultControlPolicy;\n const issues: SchemaIssue[] = [];\n const rootChildren: SchemaVerificationNode[] = [];\n const schemaTables = schema.tables;\n const namespaceIds = Object.keys(contract.storage.namespaces).sort((a, b) =>\n a < b ? -1 : a > b ? 1 : 0,\n );\n\n for (const namespaceId of namespaceIds) {\n const ns = contract.storage.namespaces[namespaceId];\n if (!ns) continue;\n for (const [tableName, contractTableRaw] of Object.entries(ns.tables)) {\n if (!(contractTableRaw instanceof StorageTable)) {\n throw new Error(\n `verifySqlSchema: expected StorageTable at storage.namespaces.${namespaceId}.tables.${tableName}`,\n );\n }\n const contractTable = contractTableRaw;\n const tableControlPolicy = effectiveControlPolicy(\n contractTable.control,\n contractDefaultControl,\n );\n const schemaTable = schemaTables[tableName];\n const tablePath = `storage.namespaces.${namespaceId}.tables.${tableName}`;\n\n if (!schemaTable) {\n const issue: SchemaIssue = {\n kind: 'missing_table',\n table: tableName,\n namespaceId,\n message: `Table \"${tableName}\" is missing from database`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'table',\n name: `table ${tableName}`,\n contractPath: tablePath,\n code: 'missing_table',\n message: `Table \"${tableName}\" is missing`,\n expected: undefined,\n actual: undefined,\n children: [],\n },\n issues,\n rootChildren,\n );\n continue;\n }\n\n const tableChildren = verifyTableChildren({\n contractTable,\n schemaTable,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n ...ifDefined('columnsCompatible', columnsCompatible),\n });\n rootChildren.push(buildTableNode(tableName, tablePath, tableChildren));\n }\n }\n\n if (strict) {\n for (const tableName of Object.keys(schemaTables)) {\n const claimed = namespaceIds.some(\n (namespaceId) => contract.storage.namespaces[namespaceId]?.tables[tableName] !== undefined,\n );\n if (!claimed) {\n const extraTableControlPolicy = effectiveControlPolicy(undefined, contractDefaultControl);\n const issue: SchemaIssue = {\n kind: 'extra_table',\n table: tableName,\n message: `Extra table \"${tableName}\" found in database (not in contract)`,\n };\n emitIssueAndNodeUnderControlPolicy(\n extraTableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'table',\n name: `table ${tableName}`,\n contractPath: `storage.namespaces.*.tables.${tableName}`,\n code: 'extra_table',\n message: `Extra table \"${tableName}\" found`,\n expected: undefined,\n actual: undefined,\n children: [],\n },\n issues,\n rootChildren,\n );\n }\n }\n }\n\n return { issues, rootChildren };\n}\n\nfunction verifyTableChildren(options: {\n contractTable: StorageTable;\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n namespaceId: string;\n tablePath: string;\n tableControlPolicy: ControlPolicy;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n columnsCompatible?: ColumnsCompatible;\n}): SchemaVerificationNode[] {\n const {\n contractTable,\n schemaTable,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n columnsCompatible,\n } = options;\n const tableChildren: SchemaVerificationNode[] = [];\n const columnNodes = collectContractColumnNodes({\n contractTable,\n schemaTable,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n ...ifDefined('columnsCompatible', columnsCompatible),\n });\n if (columnNodes.length > 0) {\n tableChildren.push(buildColumnsNode(tablePath, columnNodes));\n }\n if (strict) {\n appendExtraColumnNodes({\n contractTable,\n schemaTable,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n columnNodes,\n });\n }\n\n if (contractTable.primaryKey) {\n const pkStatus = verifyPrimaryKey(\n contractTable.primaryKey,\n schemaTable.primaryKey,\n tableName,\n namespaceId,\n tableControlPolicy,\n issues,\n );\n if (pkStatus === 'fail') {\n tableChildren.push({\n status: 'fail',\n kind: 'primaryKey',\n name: `primary key: ${contractTable.primaryKey.columns.join(', ')}`,\n contractPath: `${tablePath}.primaryKey`,\n code: 'primary_key_mismatch',\n message: 'Primary key mismatch',\n expected: contractTable.primaryKey,\n actual: schemaTable.primaryKey,\n children: [],\n });\n } else if (pkStatus === 'warn') {\n tableChildren.push({\n status: 'warn',\n kind: 'primaryKey',\n name: `primary key: ${contractTable.primaryKey.columns.join(', ')}`,\n contractPath: `${tablePath}.primaryKey`,\n code: 'primary_key_mismatch',\n message: 'Primary key mismatch',\n expected: contractTable.primaryKey,\n actual: schemaTable.primaryKey,\n children: [],\n });\n } else {\n tableChildren.push({\n status: 'pass',\n kind: 'primaryKey',\n name: `primary key: ${contractTable.primaryKey.columns.join(', ')}`,\n contractPath: `${tablePath}.primaryKey`,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n } else if (schemaTable.primaryKey && strict) {\n const issue: SchemaIssue = {\n kind: 'extra_primary_key',\n table: tableName,\n namespaceId,\n message: 'Extra primary key found in database (not in contract)',\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'primaryKey',\n name: `primary key: ${schemaTable.primaryKey.columns.join(', ')}`,\n contractPath: `${tablePath}.primaryKey`,\n code: 'extra_primary_key',\n message: 'Extra primary key found',\n expected: undefined,\n actual: schemaTable.primaryKey,\n children: [],\n },\n issues,\n tableChildren,\n );\n }\n\n // Verify FK constraints only for FKs with constraint: true.\n // Always call when strict mode is on so extra-FK detection runs even if\n // the contract has no FKs for this table.\n const constraintFks = contractTable.foreignKeys.filter((fk) => fk.constraint === true);\n if (constraintFks.length > 0 || strict) {\n const fkStatuses = verifyForeignKeys(\n constraintFks,\n schemaTable.foreignKeys,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n strict,\n );\n tableChildren.push(...fkStatuses);\n }\n\n const uniqueStatuses = verifyUniqueConstraints(\n contractTable.uniques,\n schemaTable.uniques,\n schemaTable.indexes,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n strict,\n );\n tableChildren.push(...uniqueStatuses);\n\n // Combine user-declared indexes with FK-backing indexes (from FKs with index: true)\n // so the verifier treats FK-backing indexes as expected, not \"extra\".\n // Deduplicate: skip FK-backing indexes already covered by a user-declared index.\n const fkBackingIndexes = contractTable.foreignKeys\n .filter(\n (fk) =>\n fk.index === true &&\n !contractTable.indexes.some((idx) => arraysEqual(idx.columns, fk.source.columns)),\n )\n .map((fk) => ({ columns: fk.source.columns }));\n const allExpectedIndexes = [...contractTable.indexes, ...fkBackingIndexes];\n\n const indexStatuses = verifyIndexes(\n allExpectedIndexes,\n schemaTable.indexes,\n schemaTable.uniques,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n strict,\n );\n tableChildren.push(...indexStatuses);\n\n return tableChildren;\n}\n\nfunction collectContractColumnNodes(options: {\n contractTable: StorageTable;\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n namespaceId: string;\n tablePath: string;\n tableControlPolicy: ControlPolicy;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n columnsCompatible?: ColumnsCompatible;\n}): SchemaVerificationNode[] {\n const {\n contractTable,\n schemaTable,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n columnsCompatible,\n } = options;\n const columnNodes: SchemaVerificationNode[] = [];\n\n for (const [columnName, contractColumn] of Object.entries(contractTable.columns)) {\n const schemaColumn = schemaTable.columns[columnName];\n const columnPath = `${tablePath}.columns.${columnName}`;\n\n if (!schemaColumn) {\n const issue: SchemaIssue = {\n kind: 'missing_column',\n table: tableName,\n namespaceId,\n column: columnName,\n message: `Column \"${tableName}\".\"${columnName}\" is missing from database`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'column',\n name: `${columnName}: missing`,\n contractPath: columnPath,\n code: 'missing_column',\n message: `Column \"${columnName}\" is missing`,\n expected: undefined,\n actual: undefined,\n children: [],\n },\n issues,\n columnNodes,\n );\n continue;\n }\n\n columnNodes.push(\n verifyColumn({\n tableName,\n namespaceId,\n columnName,\n contractColumn,\n schemaColumn,\n columnPath,\n tableControlPolicy,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n ...ifDefined('columnsCompatible', columnsCompatible),\n }),\n );\n }\n\n return columnNodes;\n}\n\nfunction appendExtraColumnNodes(options: {\n contractTable: StorageTable;\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n namespaceId: string;\n tablePath: string;\n tableControlPolicy: ControlPolicy;\n issues: SchemaIssue[];\n columnNodes: SchemaVerificationNode[];\n}): void {\n const {\n contractTable,\n schemaTable,\n tableName,\n namespaceId,\n tablePath,\n tableControlPolicy,\n issues,\n columnNodes,\n } = options;\n for (const [columnName, { nativeType }] of Object.entries(schemaTable.columns)) {\n if (!contractTable.columns[columnName]) {\n const issue: SchemaIssue = {\n kind: 'extra_column',\n table: tableName,\n namespaceId,\n column: columnName,\n message: `Extra column \"${tableName}\".\"${columnName}\" found in database (not in contract)`,\n };\n emitIssueAndNodeUnderControlPolicy(\n tableControlPolicy,\n issue,\n {\n status: 'fail',\n kind: 'column',\n name: `${columnName}: extra`,\n contractPath: `${tablePath}.columns.${columnName}`,\n code: 'extra_column',\n message: `Extra column \"${columnName}\" found`,\n expected: undefined,\n actual: nativeType,\n children: [],\n },\n issues,\n columnNodes,\n );\n }\n }\n}\n\nfunction verifyColumn(options: {\n tableName: string;\n namespaceId: string;\n columnName: string;\n contractColumn: StorageTable['columns'][string];\n schemaColumn: SqlSchemaIR['tables'][string]['columns'][string];\n columnPath: string;\n tableControlPolicy: ControlPolicy;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n columnsCompatible?: ColumnsCompatible;\n}): SchemaVerificationNode {\n const {\n tableName,\n namespaceId,\n columnName,\n contractColumn,\n schemaColumn,\n columnPath,\n tableControlPolicy,\n issues,\n strict,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n columnsCompatible,\n } = options;\n const columnChildren: SchemaVerificationNode[] = [];\n let columnStatus: VerificationStatus = 'pass';\n\n const resolvedContractColumn = resolveContractColumnTypeMetadata(contractColumn, storageTypes, {\n tableName,\n columnName,\n });\n const contractNativeType = renderExpectedNativeType(contractColumn, storageTypes, codecHooks, {\n tableName,\n columnName,\n });\n const schemaNativeType =\n normalizeNativeType?.(schemaColumn.nativeType) ?? schemaColumn.nativeType;\n\n const typesMatch =\n contractNativeType === schemaNativeType ||\n (tableControlPolicy === 'external' &&\n (columnsCompatible?.(contractNativeType, schemaNativeType) ??\n contractNativeType === schemaNativeType));\n\n if (!typesMatch) {\n const issue: SchemaIssue = {\n kind: 'type_mismatch',\n table: tableName,\n namespaceId,\n column: columnName,\n expected: contractNativeType,\n actual: schemaNativeType,\n message: `Column \"${tableName}\".\"${columnName}\" has type mismatch: expected \"${contractNativeType}\", got \"${schemaNativeType}\"`,\n };\n const disposition = verifierDisposition(tableControlPolicy, issue.kind);\n if (disposition !== 'suppress') {\n issues.push(issue);\n columnChildren.push({\n status: disposition,\n kind: 'type',\n name: 'type',\n contractPath: `${columnPath}.nativeType`,\n code: 'type_mismatch',\n message: `Type mismatch: expected ${contractNativeType}, got ${schemaNativeType}`,\n expected: contractNativeType,\n actual: schemaNativeType,\n children: [],\n });\n columnStatus = disposition;\n }\n }\n\n if (resolvedContractColumn.codecId) {\n const typeMetadata = options.typeMetadataRegistry.get(resolvedContractColumn.codecId);\n if (!typeMetadata) {\n columnChildren.push({\n status: 'warn',\n kind: 'type',\n name: 'type_metadata_missing',\n contractPath: `${columnPath}.codecId`,\n code: 'type_metadata_missing',\n message: `codecId \"${resolvedContractColumn.codecId}\" not found in type metadata registry`,\n expected: resolvedContractColumn.codecId,\n actual: undefined,\n children: [],\n });\n } else if (\n typeMetadata.nativeType &&\n typeMetadata.nativeType !== resolvedContractColumn.nativeType\n ) {\n columnChildren.push({\n status: 'warn',\n kind: 'type',\n name: 'type_consistency',\n contractPath: `${columnPath}.codecId`,\n code: 'type_consistency_warning',\n message: `codecId \"${resolvedContractColumn.codecId}\" maps to nativeType \"${typeMetadata.nativeType}\" in registry, but contract has \"${resolvedContractColumn.nativeType}\"`,\n expected: typeMetadata.nativeType,\n actual: resolvedContractColumn.nativeType,\n children: [],\n });\n }\n }\n\n if (contractColumn.nullable !== schemaColumn.nullable) {\n const issue: SchemaIssue = {\n kind: 'nullability_mismatch',\n table: tableName,\n namespaceId,\n column: columnName,\n expected: String(contractColumn.nullable),\n actual: String(schemaColumn.nullable),\n message: `Column \"${tableName}\".\"${columnName}\" has nullability mismatch: expected ${contractColumn.nullable ? 'nullable' : 'not null'}, got ${schemaColumn.nullable ? 'nullable' : 'not null'}`,\n };\n const disposition = verifierDisposition(tableControlPolicy, issue.kind);\n if (disposition !== 'suppress') {\n issues.push(issue);\n columnChildren.push({\n status: disposition,\n kind: 'nullability',\n name: 'nullability',\n contractPath: `${columnPath}.nullable`,\n code: 'nullability_mismatch',\n message: `Nullability mismatch: expected ${contractColumn.nullable ? 'nullable' : 'not null'}, got ${schemaColumn.nullable ? 'nullable' : 'not null'}`,\n expected: contractColumn.nullable,\n actual: schemaColumn.nullable,\n children: [],\n });\n columnStatus = disposition;\n }\n }\n\n if (contractColumn.default) {\n if (!schemaColumn.default) {\n const defaultDescription = describeColumnDefault(contractColumn.default);\n const issue: SchemaIssue = {\n kind: 'default_missing',\n table: tableName,\n namespaceId,\n column: columnName,\n expected: defaultDescription,\n message: `Column \"${tableName}\".\"${columnName}\" should have default ${defaultDescription} but database has no default`,\n };\n const disposition = verifierDisposition(tableControlPolicy, issue.kind);\n if (disposition !== 'suppress') {\n issues.push(issue);\n columnChildren.push({\n status: disposition,\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'default_missing',\n message: `Default missing: expected ${defaultDescription}`,\n expected: defaultDescription,\n actual: undefined,\n children: [],\n });\n columnStatus = disposition;\n }\n } else if (\n !columnDefaultsEqual(\n contractColumn.default,\n schemaColumn.default,\n normalizeDefault,\n schemaNativeType,\n )\n ) {\n const expectedDescription = describeColumnDefault(contractColumn.default);\n const actualDescription = schemaColumn.default;\n const issue: SchemaIssue = {\n kind: 'default_mismatch',\n table: tableName,\n namespaceId,\n column: columnName,\n expected: expectedDescription,\n actual: actualDescription,\n message: `Column \"${tableName}\".\"${columnName}\" has default mismatch: expected ${expectedDescription}, got ${actualDescription}`,\n };\n const disposition = verifierDisposition(tableControlPolicy, issue.kind);\n if (disposition !== 'suppress') {\n issues.push(issue);\n columnChildren.push({\n status: disposition,\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'default_mismatch',\n message: `Default mismatch: expected ${expectedDescription}, got ${actualDescription}`,\n expected: expectedDescription,\n actual: actualDescription,\n children: [],\n });\n columnStatus = disposition;\n }\n }\n } else if (strict && schemaColumn.default) {\n const issue: SchemaIssue = {\n kind: 'extra_default',\n table: tableName,\n namespaceId,\n column: columnName,\n actual: schemaColumn.default,\n message: `Column \"${tableName}\".\"${columnName}\" has default ${schemaColumn.default} in database but contract specifies no default`,\n };\n const disposition = verifierDisposition(tableControlPolicy, issue.kind);\n if (disposition !== 'suppress') {\n issues.push(issue);\n columnChildren.push({\n status: disposition,\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'extra_default',\n message: `Extra default: ${schemaColumn.default}`,\n expected: undefined,\n actual: schemaColumn.default,\n children: [],\n });\n columnStatus = disposition;\n }\n }\n\n // Single-pass aggregation for better performance\n const aggregated = aggregateChildState(columnChildren, columnStatus);\n const nullableText = contractColumn.nullable ? 'nullable' : 'not nullable';\n const columnTypeDisplay = resolvedContractColumn.codecId\n ? `${contractNativeType} (${resolvedContractColumn.codecId})`\n : contractNativeType;\n const columnMessage = aggregated.failureMessages.join('; ');\n\n return {\n status: aggregated.status,\n kind: 'column',\n name: `${columnName}: ${columnTypeDisplay} (${nullableText})`,\n contractPath: columnPath,\n code: aggregated.firstCode,\n message: columnMessage,\n expected: undefined,\n actual: undefined,\n children: columnChildren,\n };\n}\n\nfunction buildColumnsNode(\n tablePath: string,\n columnNodes: SchemaVerificationNode[],\n): SchemaVerificationNode {\n return {\n status: aggregateChildState(columnNodes, 'pass').status,\n kind: 'columns',\n name: 'columns',\n contractPath: `${tablePath}.columns`,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: columnNodes,\n };\n}\n\nfunction buildTableNode(\n tableName: string,\n tablePath: string,\n tableChildren: SchemaVerificationNode[],\n): SchemaVerificationNode {\n const tableStatus = aggregateChildState(tableChildren, 'pass').status;\n const tableFailureMessages = tableChildren\n .filter((child) => child.status === 'fail' && child.message)\n .map((child) => child.message)\n .filter((msg): msg is string => typeof msg === 'string' && msg.length > 0);\n const tableMessage =\n tableStatus === 'fail' && tableFailureMessages.length > 0\n ? `${tableFailureMessages.length} issue${tableFailureMessages.length === 1 ? '' : 's'}`\n : '';\n const tableCode =\n tableStatus === 'fail' && tableChildren.length > 0 && tableChildren[0]\n ? tableChildren[0].code\n : '';\n\n return {\n status: tableStatus,\n kind: 'table',\n name: `table ${tableName}`,\n contractPath: tablePath,\n code: tableCode,\n message: tableMessage,\n expected: undefined,\n actual: undefined,\n children: tableChildren,\n };\n}\n\nfunction buildRootNode(rootChildren: SchemaVerificationNode[]): SchemaVerificationNode {\n return {\n status: aggregateChildState(rootChildren, 'pass').status,\n kind: 'contract',\n name: 'contract',\n contractPath: '',\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: rootChildren,\n };\n}\n\n/**\n * Aggregated state from child nodes, computed in a single pass.\n */\ninterface AggregatedChildState {\n readonly status: VerificationStatus;\n readonly failureMessages: readonly string[];\n readonly firstCode: string;\n}\n\n/**\n * Aggregates status, failure messages, and code from children in a single pass.\n * This is more efficient than calling separate functions that each iterate the array.\n */\nfunction aggregateChildState(\n children: SchemaVerificationNode[],\n fallback: VerificationStatus,\n): AggregatedChildState {\n let status: VerificationStatus = fallback;\n const failureMessages: string[] = [];\n let firstCode = '';\n\n for (const child of children) {\n if (child.status === 'fail') {\n status = 'fail';\n if (!firstCode) {\n firstCode = child.code;\n }\n if (child.message && typeof child.message === 'string' && child.message.length > 0) {\n failureMessages.push(child.message);\n }\n } else if (child.status === 'warn' && status !== 'fail') {\n status = 'warn';\n if (!firstCode) {\n firstCode = child.code;\n }\n }\n }\n\n return { status, failureMessages, firstCode };\n}\n\nfunction validateFrameworkComponentsForExtensions(\n contract: Contract<SqlStorage>,\n frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n): void {\n const contractExtensionPacks = contract.extensionPacks ?? {};\n for (const extensionNamespace of Object.keys(contractExtensionPacks)) {\n const hasComponent = frameworkComponents.some(\n (component) =>\n component.id === extensionNamespace &&\n (component.kind === 'extension' ||\n component.kind === 'adapter' ||\n component.kind === 'target'),\n );\n if (!hasComponent) {\n throw new Error(\n `Extension pack '${extensionNamespace}' is declared in the contract but not found in framework components. ` +\n 'This indicates a configuration mismatch - the contract was emitted with this extension pack, ' +\n 'but it is not provided in the current configuration.',\n );\n }\n }\n}\n\n/**\n * Renders the expected native type for a contract column, expanding parameterized types\n * using codec control hooks when available.\n *\n * This function delegates to the `expandNativeType` hook if the codec provides one,\n * ensuring that the SQL family layer remains dialect-agnostic while allowing\n * target-specific adapters (like Postgres) to provide their own expansion logic.\n */\nfunction renderExpectedNativeType(\n contractColumn: StorageColumn,\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,\n codecHooks: Map<string, CodecControlHooks>,\n context?: {\n readonly tableName: string;\n readonly columnName: string;\n },\n): string {\n const { codecId, nativeType, typeParams } = resolveContractColumnTypeMetadata(\n contractColumn,\n storageTypes,\n context,\n );\n\n // If no typeParams or codecId, return the base native type\n if (!typeParams || !codecId) {\n return nativeType;\n }\n\n // Try to use the codec's expandNativeType hook if available\n const hooks = codecHooks.get(codecId);\n if (hooks?.expandNativeType) {\n return hooks.expandNativeType({ nativeType, codecId, typeParams });\n }\n\n // Fallback: return base native type if no hook is available\n return nativeType;\n}\n\nfunction resolveContractColumnTypeMetadata(\n contractColumn: StorageColumn,\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,\n context?: {\n readonly tableName: string;\n readonly columnName: string;\n },\n): Pick<StorageColumn, 'codecId' | 'nativeType' | 'typeParams'> {\n if (!contractColumn.typeRef) {\n return contractColumn;\n }\n\n const referencedType = storageTypes[contractColumn.typeRef];\n if (!referencedType) {\n const columnLabel = context\n ? `Column \"${context.tableName}\".\"${context.columnName}\"`\n : 'Column';\n throw new Error(\n `${columnLabel} references storage type \"${contractColumn.typeRef}\" but it is not defined in storage.types.`,\n );\n }\n\n if (isPostgresEnumStorageEntry(referencedType)) {\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: { values: referencedType.values } as Record<string, unknown>,\n };\n }\n if (isStorageTypeInstance(referencedType)) {\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: referencedType.typeParams,\n };\n }\n throw new Error(\n `Storage type \"${contractColumn.typeRef}\" has an unknown polymorphic kind; expected codec-instance or postgres-enum.`,\n );\n}\n\n/**\n * Describes a column default for display purposes.\n */\nfunction describeColumnDefault(columnDefault: ColumnDefault): string {\n switch (columnDefault.kind) {\n case 'literal':\n return `literal(${formatLiteralValue(columnDefault.value)})`;\n case 'function':\n return columnDefault.expression;\n }\n}\n\n/**\n * Compares a contract ColumnDefault against a schema raw default string for semantic equality.\n *\n * When a normalizer is provided, the raw schema default is first normalized to a ColumnDefault\n * before comparison. Without a normalizer, falls back to direct string comparison against\n * the contract expression.\n *\n * @param contractDefault - The expected default from the contract (normalized ColumnDefault)\n * @param schemaDefault - The raw default expression from the database (string)\n * @param normalizer - Optional target-specific normalizer to convert raw defaults\n * @param nativeType - The column's native type, passed to normalizer for context\n */\nfunction columnDefaultsEqual(\n contractDefault: ColumnDefault,\n schemaDefault: string,\n normalizer?: DefaultNormalizer,\n nativeType?: string,\n): boolean {\n // If no normalizer provided, fall back to direct string comparison\n if (!normalizer) {\n if (contractDefault.kind === 'function') {\n return contractDefault.expression === schemaDefault;\n }\n const normalizedValue = normalizeLiteralValue(contractDefault.value, nativeType);\n if (typeof normalizedValue === 'string') {\n return normalizedValue === schemaDefault || `'${normalizedValue}'` === schemaDefault;\n }\n return String(normalizedValue) === schemaDefault;\n }\n\n // Normalize the raw schema default using target-specific logic\n const normalizedSchema = normalizer(schemaDefault, nativeType ?? '');\n if (!normalizedSchema) {\n // Normalizer couldn't parse the expression - treat as mismatch\n return false;\n }\n\n // Compare normalized defaults\n if (contractDefault.kind !== normalizedSchema.kind) {\n return false;\n }\n if (contractDefault.kind === 'literal' && normalizedSchema.kind === 'literal') {\n const contractValue = normalizeLiteralValue(contractDefault.value, nativeType);\n const schemaValue = normalizeLiteralValue(normalizedSchema.value, nativeType);\n return literalValuesEqual(contractValue, schemaValue);\n }\n if (contractDefault.kind === 'function' && normalizedSchema.kind === 'function') {\n // Normalize function expressions for comparison (case-insensitive, whitespace-tolerant)\n const normalizeExpr = (expr: string) => expr.toLowerCase().replace(/\\s+/g, '');\n return normalizeExpr(contractDefault.expression) === normalizeExpr(normalizedSchema.expression);\n }\n return false;\n}\n\nfunction isTemporalNativeType(nativeType?: string): boolean {\n if (!nativeType) return false;\n const normalized = nativeType.toLowerCase();\n return normalized.includes('timestamp') || normalized === 'date';\n}\n\nfunction normalizeLiteralValue(value: unknown, nativeType?: string): unknown {\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'string' && isTemporalNativeType(nativeType)) {\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed.toISOString();\n }\n }\n return value;\n}\n\nfunction literalValuesEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a === 'object' && a !== null && typeof b === 'object' && b !== null) {\n return canonicalStringify(a) === canonicalStringify(b);\n }\n if (typeof a === 'object' && a !== null && typeof b === 'string') {\n try {\n return canonicalStringify(a) === canonicalStringify(JSON.parse(b));\n } catch {\n return false;\n }\n }\n if (typeof a === 'string' && typeof b === 'object' && b !== null) {\n try {\n return canonicalStringify(JSON.parse(a)) === canonicalStringify(b);\n } catch {\n return false;\n }\n }\n return false;\n}\n\nfunction formatLiteralValue(value: unknown): string {\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'string') {\n return value;\n }\n return JSON.stringify(value);\n}\n"],"mappings":"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"}