@prisma-next/family-sql 0.1.0-dev.14 → 0.1.0-dev.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -2
- package/dist/exports/{chunk-JRVDOVCL.js → chunk-FDYFNYMY.js} +4 -4
- package/dist/exports/chunk-FDYFNYMY.js.map +1 -0
- package/dist/exports/control.d.ts +98 -17
- package/dist/exports/control.js +37 -10
- package/dist/exports/control.js.map +1 -1
- package/dist/exports/test-utils.js +1 -1
- package/package.json +15 -15
- package/dist/exports/chunk-JRVDOVCL.js.map +0 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Provides the SQL family descriptor (`ControlFamilyDescriptor`) that includes:
|
|
|
12
12
|
|
|
13
13
|
- **Family Descriptor Export**: Exports the SQL `ControlFamilyDescriptor` for use in CLI configuration files
|
|
14
14
|
- **Family Instance Creation**: Creates `SqlFamilyInstance` objects that implement control-plane domain actions (`verify`, `schemaVerify`, `introspect`, `emitContract`, `validateContractIR`)
|
|
15
|
-
- **Planner SPI**: Owns the `MigrationPlanner`
|
|
15
|
+
- **Planner & Runner SPI**: Owns the `MigrationPlanner` / `MigrationRunner` interfaces plus the `SqlControlTargetDescriptor` helper so targets can expose planners and runners (e.g., Postgres init planner/runner)
|
|
16
16
|
- **Family Hook Integration**: Integrates the SQL target family hook (`sqlTargetFamilyHook`) from `@prisma-next/sql-contract-emitter`
|
|
17
17
|
- **Control Plane Entry Point**: Serves as the control plane entry point for the SQL family, enabling the CLI to select the family hook and create family instances
|
|
18
18
|
|
|
@@ -44,6 +44,21 @@ const emitResult = await familyInstance.emitContract({ contractIR: rawContract }
|
|
|
44
44
|
// Targets that implement SqlControlTargetDescriptor can build planners
|
|
45
45
|
const planner = postgresTargetDescriptor.createPlanner(familyInstance);
|
|
46
46
|
const planResult = planner.plan({ contract: sqlContract, schema, policy });
|
|
47
|
+
|
|
48
|
+
// Targets also provide runners for executing plans
|
|
49
|
+
const runner = postgresTargetDescriptor.createRunner(familyInstance);
|
|
50
|
+
const executeResult = await runner.execute({
|
|
51
|
+
plan: planResult.plan,
|
|
52
|
+
driver,
|
|
53
|
+
destinationContract: sqlContract,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// executeResult is a Result<MigrationRunnerSuccessValue, MigrationRunnerFailure>
|
|
57
|
+
if (executeResult.ok) {
|
|
58
|
+
console.log(`Executed ${executeResult.value.operationsExecuted} operations`);
|
|
59
|
+
} else {
|
|
60
|
+
console.error(`Migration failed: ${executeResult.failure.code} - ${executeResult.failure.summary}`);
|
|
61
|
+
}
|
|
47
62
|
```
|
|
48
63
|
|
|
49
64
|
## Architecture
|
|
@@ -73,7 +88,19 @@ The descriptor is "pure data + factory" - it only provides the hook and factory
|
|
|
73
88
|
- **`src/core/assembly.ts`**: Assembly helpers for building operation registries and extracting type imports from descriptors. Test utilities import `convertOperationManifest` from the same package via relative path.
|
|
74
89
|
- **`src/core/verify.ts`**: Verification helpers (`readMarker`, `collectSupportedCodecTypeIds`)
|
|
75
90
|
- **`src/core/control-adapter.ts`**: SQL control adapter interface (`SqlControlAdapter`) for control-plane operations
|
|
76
|
-
- **`src/core/migrations/`**: Migration IR helpers plus planner SPI types (`MigrationPlanner`, `SqlControlTargetDescriptor`)
|
|
91
|
+
- **`src/core/migrations/`**: Migration IR helpers plus planner and runner SPI types (`MigrationPlanner`, `MigrationRunner`, `SqlControlTargetDescriptor`). Runners return `MigrationRunnerResult` which is a union of success/failure.
|
|
92
|
+
|
|
93
|
+
### Migration Runner Error Codes
|
|
94
|
+
|
|
95
|
+
The runner returns structured errors with the following codes:
|
|
96
|
+
|
|
97
|
+
- **`DESTINATION_CONTRACT_MISMATCH`**: Plan destination hash doesn't match provided contract hash
|
|
98
|
+
- **`MARKER_ORIGIN_MISMATCH`**: Existing marker doesn't match plan's expected origin
|
|
99
|
+
- **`POLICY_VIOLATION`**: Operation class is not allowed by the plan's policy
|
|
100
|
+
- **`PRECHECK_FAILED`**: Operation precheck returned false
|
|
101
|
+
- **`POSTCHECK_FAILED`**: Operation postcheck returned false after execution
|
|
102
|
+
- **`SCHEMA_VERIFY_FAILED`**: Resulting schema doesn't satisfy the destination contract
|
|
103
|
+
- **`EXECUTION_FAILED`**: SQL execution error during operation execution
|
|
77
104
|
- **`src/exports/control.ts`**: Control plane entry point (exports `SqlFamilyDescriptor` instance)
|
|
78
105
|
- **`src/exports/runtime.ts`**: Runtime entry point (placeholder for future functionality)
|
|
79
106
|
|
|
@@ -678,7 +678,7 @@ function createSqlFamilyInstance(options) {
|
|
|
678
678
|
});
|
|
679
679
|
},
|
|
680
680
|
async schemaVerify(options2) {
|
|
681
|
-
const { driver, contractIR, strict,
|
|
681
|
+
const { driver, contractIR, strict, context } = options2;
|
|
682
682
|
const startTime = Date.now();
|
|
683
683
|
const contract = validateContract(contractIR);
|
|
684
684
|
const contractCoreHash = contract.coreHash;
|
|
@@ -1072,9 +1072,9 @@ function createSqlFamilyInstance(options) {
|
|
|
1072
1072
|
counts
|
|
1073
1073
|
},
|
|
1074
1074
|
meta: {
|
|
1075
|
-
contractPath,
|
|
1076
1075
|
strict,
|
|
1077
|
-
...
|
|
1076
|
+
...context?.contractPath ? { contractPath: context.contractPath } : {},
|
|
1077
|
+
...context?.configPath ? { configPath: context.configPath } : {}
|
|
1078
1078
|
},
|
|
1079
1079
|
timings: {
|
|
1080
1080
|
total: totalTime
|
|
@@ -1386,4 +1386,4 @@ export {
|
|
|
1386
1386
|
extractExtensionIdsFromPacks,
|
|
1387
1387
|
createSqlFamilyInstance
|
|
1388
1388
|
};
|
|
1389
|
-
//# sourceMappingURL=chunk-
|
|
1389
|
+
//# sourceMappingURL=chunk-FDYFNYMY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/assembly.ts","../../src/core/instance.ts"],"sourcesContent":["import type {\n ExtensionPackManifest,\n OperationManifest,\n} from '@prisma-next/contract/pack-manifest-types';\nimport type { TypesImportSpec } from '@prisma-next/contract/types';\nimport type {\n ControlAdapterDescriptor,\n ControlExtensionDescriptor,\n ControlTargetDescriptor,\n} from '@prisma-next/core-control-plane/types';\nimport type { OperationRegistry, OperationSignature } from '@prisma-next/operations';\nimport { createOperationRegistry } from '@prisma-next/operations';\n// Import private function from same package (test utility needs it)\nimport { convertOperationManifest } from './instance';\n\n/**\n * Assembles an operation registry from descriptors (adapter, target, extensions).\n * Loops over descriptors, extracts operations, converts them using the provided\n * conversion function, and registers them in a new registry.\n */\nexport function assembleOperationRegistry(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n convertOperationManifest: (manifest: OperationManifest) => OperationSignature,\n): OperationRegistry {\n const registry = createOperationRegistry();\n\n for (const descriptor of descriptors) {\n const operations = descriptor.manifest.operations ?? [];\n for (const operationManifest of operations as ReadonlyArray<OperationManifest>) {\n const signature = convertOperationManifest(operationManifest);\n registry.register(signature);\n }\n }\n\n return registry;\n}\n\n/**\n * Extracts codec type imports from descriptors for contract.d.ts generation.\n */\nexport function extractCodecTypeImports(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const codecTypes = descriptor.manifest.types?.codecTypes;\n if (codecTypes?.import) {\n imports.push(codecTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Extracts operation type imports from descriptors for contract.d.ts generation.\n */\nexport function extractOperationTypeImports(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const operationTypes = descriptor.manifest.types?.operationTypes;\n if (operationTypes?.import) {\n imports.push(operationTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Extracts extension IDs from descriptors in deterministic order:\n * [adapter.id, target.id, ...extensions.map(e => e.id)]\n * Deduplicates while preserving stable order.\n */\nexport function extractExtensionIds(\n adapter: ControlAdapterDescriptor<'sql', string>,\n target: ControlTargetDescriptor<'sql', string>,\n extensions: ReadonlyArray<ControlExtensionDescriptor<'sql', string>>,\n): ReadonlyArray<string> {\n const ids: string[] = [];\n const seen = new Set<string>();\n\n // Add adapter first\n if (!seen.has(adapter.id)) {\n ids.push(adapter.id);\n seen.add(adapter.id);\n }\n\n // Add target second\n if (!seen.has(target.id)) {\n ids.push(target.id);\n seen.add(target.id);\n }\n\n // Add extensions in order\n for (const ext of extensions) {\n if (!seen.has(ext.id)) {\n ids.push(ext.id);\n seen.add(ext.id);\n }\n }\n\n return ids;\n}\n\n/**\n * Extracts codec type imports from extension packs for contract.d.ts generation.\n * Pack-based version for use in tests.\n */\nexport function extractCodecTypeImportsFromPacks(\n packs: ReadonlyArray<{ readonly manifest: ExtensionPackManifest }>,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const pack of packs) {\n const codecTypes = pack.manifest.types?.codecTypes;\n if (codecTypes?.import) {\n imports.push(codecTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Extracts operation type imports from extension packs for contract.d.ts generation.\n * Pack-based version for use in tests.\n */\nexport function extractOperationTypeImportsFromPacks(\n packs: ReadonlyArray<{ readonly manifest: ExtensionPackManifest }>,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const pack of packs) {\n const operationTypes = pack.manifest.types?.operationTypes;\n if (operationTypes?.import) {\n imports.push(operationTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Assembles an operation registry from extension packs.\n * Pack-based version for use in tests.\n */\nexport function assembleOperationRegistryFromPacks(\n packs: ReadonlyArray<{ readonly manifest: ExtensionPackManifest }>,\n): OperationRegistry {\n const registry = createOperationRegistry();\n\n for (const pack of packs) {\n const operations = pack.manifest.operations ?? [];\n for (const operationManifest of operations as ReadonlyArray<OperationManifest>) {\n const signature = convertOperationManifest(operationManifest);\n registry.register(signature);\n }\n }\n\n return registry;\n}\n\n/**\n * Extracts extension IDs from packs.\n * Pack-based version for use in tests.\n */\nexport function extractExtensionIdsFromPacks(\n packs: ReadonlyArray<{ readonly manifest: ExtensionPackManifest }>,\n): ReadonlyArray<string> {\n return packs.map((pack) => pack.manifest.id);\n}\n","import type { ContractIR } from '@prisma-next/contract/ir';\nimport type { OperationManifest } from '@prisma-next/contract/pack-manifest-types';\nimport type { ContractMarkerRecord, TypesImportSpec } from '@prisma-next/contract/types';\nimport { emit } from '@prisma-next/core-control-plane/emission';\nimport type { CoreSchemaView, SchemaTreeNode } from '@prisma-next/core-control-plane/schema-view';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyInstance,\n ControlTargetDescriptor,\n EmitContractResult,\n OperationContext,\n SchemaIssue,\n SchemaVerificationNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/core-control-plane/types';\nimport type { OperationRegistry } from '@prisma-next/operations';\nimport type {\n ForeignKey,\n Index,\n PrimaryKey,\n SqlContract,\n SqlStorage,\n UniqueConstraint,\n} from '@prisma-next/sql-contract/types';\nimport { sqlTargetFamilyHook } from '@prisma-next/sql-contract-emitter';\nimport { validateContract } from '@prisma-next/sql-contract-ts/contract';\nimport type { SqlOperationSignature } from '@prisma-next/sql-operations';\nimport {\n ensureSchemaStatement,\n ensureTableStatement,\n writeContractMarker,\n} from '@prisma-next/sql-runtime';\nimport type {\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlSchemaIR,\n SqlTableIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\nimport {\n assembleOperationRegistry,\n extractCodecTypeImports,\n extractExtensionIds,\n extractOperationTypeImports,\n} from './assembly';\nimport type { SqlControlAdapter } from './control-adapter';\nimport type { SqlControlTargetDescriptor } from './migrations/types';\nimport { collectSupportedCodecTypeIds, readMarker } from './verify';\n\n/**\n * Converts an OperationManifest (from ExtensionPackManifest) to a SqlOperationSignature.\n * This is SQL-family-specific conversion logic.\n * Used internally by instance creation and test utilities in the same package.\n */\nexport function convertOperationManifest(manifest: OperationManifest): SqlOperationSignature {\n return {\n forTypeId: manifest.for,\n method: manifest.method,\n args: manifest.args.map((arg: OperationManifest['args'][number]) => {\n if (arg.kind === 'typeId') {\n if (!arg.type) {\n throw new Error('typeId arg must have type property');\n }\n return { kind: 'typeId' as const, type: arg.type };\n }\n if (arg.kind === 'param') {\n return { kind: 'param' as const };\n }\n if (arg.kind === 'literal') {\n return { kind: 'literal' as const };\n }\n throw new Error(`Invalid arg kind: ${(arg as { kind: unknown }).kind}`);\n }),\n returns: (() => {\n if (manifest.returns.kind === 'typeId') {\n return { kind: 'typeId' as const, type: manifest.returns.type };\n }\n if (manifest.returns.kind === 'builtin') {\n return {\n kind: 'builtin' as const,\n type: manifest.returns.type as 'number' | 'boolean' | 'string',\n };\n }\n throw new Error(`Invalid return kind: ${(manifest.returns as { kind: unknown }).kind}`);\n })(),\n lowering: {\n targetFamily: 'sql',\n strategy: manifest.lowering.strategy,\n template: manifest.lowering.template,\n },\n ...(manifest.capabilities ? { capabilities: manifest.capabilities } : {}),\n };\n}\n\n/**\n * Extracts codec type IDs used in contract storage tables.\n * Uses type guards to safely access SQL-specific structure without importing SQL types.\n */\nfunction extractCodecTypeIdsFromContract(contract: unknown): readonly string[] {\n const typeIds = new Set<string>();\n\n // Type guard for SQL contract structure\n if (\n typeof contract === 'object' &&\n contract !== null &&\n 'storage' in contract &&\n typeof contract.storage === 'object' &&\n contract.storage !== null &&\n 'tables' in contract.storage\n ) {\n const storage = contract.storage as { tables?: Record<string, unknown> };\n if (storage.tables && typeof storage.tables === 'object') {\n for (const table of Object.values(storage.tables)) {\n if (\n typeof table === 'object' &&\n table !== null &&\n 'columns' in table &&\n typeof table.columns === 'object' &&\n table.columns !== null\n ) {\n const columns = table.columns as Record<string, { codecId: string } | undefined>;\n for (const column of Object.values(columns)) {\n if (\n column &&\n typeof column === 'object' &&\n 'codecId' in column &&\n typeof column.codecId === 'string'\n ) {\n typeIds.add(column.codecId);\n }\n }\n }\n }\n }\n }\n\n return Array.from(typeIds).sort();\n}\n\n/**\n * Compares two arrays of strings for equality (order-sensitive).\n */\nfunction 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 * Compares primary keys and adds issues if mismatch.\n * Returns 'pass' or 'fail'.\n */\nfunction comparePrimaryKey(\n contractPK: PrimaryKey,\n schemaPK: PrimaryKey | undefined,\n tableName: string,\n issues: SchemaIssue[],\n): 'pass' | 'fail' {\n if (!schemaPK) {\n issues.push({\n kind: 'primary_key_mismatch',\n table: tableName,\n expected: contractPK.columns.join(', '),\n message: `Table \"${tableName}\" is missing primary key`,\n });\n return 'fail';\n }\n\n if (!arraysEqual(contractPK.columns, schemaPK.columns)) {\n issues.push({\n kind: 'primary_key_mismatch',\n table: tableName,\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 return 'fail';\n }\n\n // Compare name if both are modeled\n if (contractPK.name && schemaPK.name && contractPK.name !== schemaPK.name) {\n issues.push({\n kind: 'primary_key_mismatch',\n table: tableName,\n indexOrConstraint: contractPK.name,\n expected: contractPK.name,\n actual: schemaPK.name,\n message: `Table \"${tableName}\" has primary key name mismatch: expected \"${contractPK.name}\", got \"${schemaPK.name}\"`,\n });\n return 'fail';\n }\n\n return 'pass';\n}\n\n/**\n * Compares foreign keys and returns verification nodes.\n */\nfunction compareForeignKeys(\n contractFKs: readonly ForeignKey[],\n schemaFKs: readonly SqlForeignKeyIR[],\n tableName: string,\n tablePath: string,\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.columns.join(',')}]`;\n const matchingFK = schemaFKs.find((fk) => {\n return (\n arraysEqual(fk.columns, contractFK.columns) &&\n fk.referencedTable === contractFK.references.table &&\n arraysEqual(fk.referencedColumns, contractFK.references.columns)\n );\n });\n\n if (!matchingFK) {\n issues.push({\n kind: 'foreign_key_mismatch',\n table: tableName,\n expected: `${contractFK.columns.join(', ')} -> ${contractFK.references.table}(${contractFK.references.columns.join(', ')})`,\n message: `Table \"${tableName}\" is missing foreign key: ${contractFK.columns.join(', ')} -> ${contractFK.references.table}(${contractFK.references.columns.join(', ')})`,\n });\n nodes.push({\n status: 'fail',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.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 } else {\n // Compare name if both are modeled\n if (contractFK.name && matchingFK.name && contractFK.name !== matchingFK.name) {\n issues.push({\n kind: 'foreign_key_mismatch',\n table: tableName,\n indexOrConstraint: contractFK.name,\n expected: contractFK.name,\n actual: matchingFK.name,\n message: `Table \"${tableName}\" has foreign key name mismatch: expected \"${contractFK.name}\", got \"${matchingFK.name}\"`,\n });\n nodes.push({\n status: 'fail',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.columns.join(', ')})`,\n contractPath: fkPath,\n code: 'foreign_key_mismatch',\n message: 'Foreign key name mismatch',\n expected: contractFK.name,\n actual: matchingFK.name,\n children: [],\n });\n } else {\n nodes.push({\n status: 'pass',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.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 return (\n arraysEqual(fk.columns, schemaFK.columns) &&\n fk.references.table === schemaFK.referencedTable &&\n arraysEqual(fk.references.columns, schemaFK.referencedColumns)\n );\n });\n\n if (!matchingFK) {\n issues.push({\n kind: 'foreign_key_mismatch',\n table: tableName,\n message: `Extra foreign key found in database (not in contract): ${schemaFK.columns.join(', ')} -> ${schemaFK.referencedTable}(${schemaFK.referencedColumns.join(', ')})`,\n });\n nodes.push({\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 }\n }\n }\n\n return nodes;\n}\n\n/**\n * Compares unique constraints and returns verification nodes.\n */\nfunction compareUniqueConstraints(\n contractUniques: readonly UniqueConstraint[],\n schemaUniques: readonly SqlUniqueIR[],\n tableName: string,\n tablePath: string,\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 const matchingUnique = schemaUniques.find((u) =>\n arraysEqual(u.columns, contractUnique.columns),\n );\n\n if (!matchingUnique) {\n issues.push({\n kind: 'unique_constraint_mismatch',\n table: tableName,\n expected: contractUnique.columns.join(', '),\n message: `Table \"${tableName}\" is missing unique constraint: ${contractUnique.columns.join(', ')}`,\n });\n nodes.push({\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 } else {\n // Compare name if both are modeled\n if (\n contractUnique.name &&\n matchingUnique.name &&\n contractUnique.name !== matchingUnique.name\n ) {\n issues.push({\n kind: 'unique_constraint_mismatch',\n table: tableName,\n indexOrConstraint: contractUnique.name,\n expected: contractUnique.name,\n actual: matchingUnique.name,\n message: `Table \"${tableName}\" has unique constraint name mismatch: expected \"${contractUnique.name}\", got \"${matchingUnique.name}\"`,\n });\n nodes.push({\n status: 'fail',\n kind: 'unique',\n name: `unique(${contractUnique.columns.join(', ')})`,\n contractPath: uniquePath,\n code: 'unique_constraint_mismatch',\n message: 'Unique constraint name mismatch',\n expected: contractUnique.name,\n actual: matchingUnique.name,\n children: [],\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\n // Check for extra uniques in strict mode\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 issues.push({\n kind: 'unique_constraint_mismatch',\n table: tableName,\n message: `Extra unique constraint found in database (not in contract): ${schemaUnique.columns.join(', ')}`,\n });\n nodes.push({\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 }\n }\n }\n\n return nodes;\n}\n\n/**\n * Compares indexes and returns verification nodes.\n */\nfunction compareIndexes(\n contractIndexes: readonly Index[],\n schemaIndexes: readonly SqlIndexIR[],\n tableName: string,\n tablePath: string,\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 const matchingIndex = schemaIndexes.find(\n (idx) => arraysEqual(idx.columns, contractIndex.columns) && idx.unique === false,\n );\n\n if (!matchingIndex) {\n issues.push({\n kind: 'index_mismatch',\n table: tableName,\n expected: contractIndex.columns.join(', '),\n message: `Table \"${tableName}\" is missing index: ${contractIndex.columns.join(', ')}`,\n });\n nodes.push({\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 } else {\n // Compare name if both are modeled\n if (contractIndex.name && matchingIndex.name && contractIndex.name !== matchingIndex.name) {\n issues.push({\n kind: 'index_mismatch',\n table: tableName,\n indexOrConstraint: contractIndex.name,\n expected: contractIndex.name,\n actual: matchingIndex.name,\n message: `Table \"${tableName}\" has index name mismatch: expected \"${contractIndex.name}\", got \"${matchingIndex.name}\"`,\n });\n nodes.push({\n status: 'fail',\n kind: 'index',\n name: `index(${contractIndex.columns.join(', ')})`,\n contractPath: indexPath,\n code: 'index_mismatch',\n message: 'Index name mismatch',\n expected: contractIndex.name,\n actual: matchingIndex.name,\n children: [],\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\n // Check for extra indexes in strict mode\n if (strict) {\n for (const schemaIndex of schemaIndexes) {\n // Skip unique indexes (they're handled as unique constraints)\n if (schemaIndex.unique) {\n continue;\n }\n\n const matchingIndex = contractIndexes.find((idx) =>\n arraysEqual(idx.columns, schemaIndex.columns),\n );\n\n if (!matchingIndex) {\n issues.push({\n kind: 'index_mismatch',\n table: tableName,\n message: `Extra index found in database (not in contract): ${schemaIndex.columns.join(', ')}`,\n });\n nodes.push({\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 }\n }\n }\n\n return nodes;\n}\n\n/**\n * Compares extensions and returns verification nodes.\n * Extracts extension names from contract.extensions (keys) and compares with schemaIR.extensions.\n * Filters out the target name (e.g., 'postgres') as it's not an extension.\n */\nfunction compareExtensions(\n contractExtensions: Record<string, unknown> | undefined,\n schemaExtensions: readonly string[],\n contractTarget: string,\n issues: SchemaIssue[],\n _strict: boolean,\n): SchemaVerificationNode[] {\n const nodes: SchemaVerificationNode[] = [];\n\n if (!contractExtensions) {\n return nodes;\n }\n\n // Extract extension names from contract (keys of extensions object)\n // Filter out the target name - it's not an extension (e.g., 'postgres' is the target, not an extension)\n const contractExtensionNames = Object.keys(contractExtensions).filter(\n (name) => name !== contractTarget,\n );\n\n // Check each contract extension exists in schema\n // Extension names in contract may differ from database extension names\n // (e.g., contract has 'pgvector' but database has 'vector')\n // We need to match more flexibly - try exact match, then check if either contains the other\n for (const extName of contractExtensionNames) {\n const extPath = `extensions.${extName}`;\n // Normalize extension names for comparison (remove common prefixes like 'pg')\n const normalizedExtName = extName.toLowerCase().replace(/^pg/, '');\n const matchingExt = schemaExtensions.find((e) => {\n const normalizedE = e.toLowerCase();\n // Exact match\n if (normalizedE === normalizedExtName || normalizedE === extName.toLowerCase()) {\n return true;\n }\n // Check if one contains the other (e.g., 'pgvector' contains 'vector', 'vector' is in 'pgvector')\n if (normalizedE.includes(normalizedExtName) || normalizedExtName.includes(normalizedE)) {\n return true;\n }\n return false;\n });\n\n // Map extension names to descriptive labels\n const extensionLabels: Record<string, string> = {\n pg: 'database is postgres',\n pgvector: 'vector extension is enabled',\n vector: 'vector extension is enabled',\n };\n const extensionLabel = extensionLabels[extName] ?? `extension \"${extName}\" is enabled`;\n\n if (!matchingExt) {\n issues.push({\n kind: 'extension_missing',\n table: '',\n message: `Extension \"${extName}\" is missing from database`,\n });\n nodes.push({\n status: 'fail',\n kind: 'extension',\n name: extensionLabel,\n contractPath: extPath,\n code: 'extension_missing',\n message: `Extension \"${extName}\" is missing`,\n expected: undefined,\n actual: undefined,\n children: [],\n });\n } else {\n nodes.push({\n status: 'pass',\n kind: 'extension',\n name: extensionLabel,\n contractPath: extPath,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n\n // In strict mode, we don't check for extra extensions (they're allowed)\n // Extensions are additive - having extra extensions doesn't break the contract\n\n return nodes;\n}\n\n/**\n * Computes counts of pass/warn/fail nodes by traversing the tree.\n */\nfunction 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 * Creates a VerifyDatabaseResult object with common structure.\n */\nfunction createVerifyResult(options: {\n ok: boolean;\n code?: string;\n summary: string;\n contractCoreHash: string;\n contractProfileHash?: string;\n marker?: ContractMarkerRecord;\n expectedTargetId: string;\n actualTargetId?: string;\n missingCodecs?: readonly string[];\n codecCoverageSkipped?: boolean;\n configPath?: string;\n contractPath: string;\n totalTime: number;\n}): VerifyDatabaseResult {\n const contract: { coreHash: string; profileHash?: string } = {\n coreHash: options.contractCoreHash,\n };\n if (options.contractProfileHash) {\n contract.profileHash = options.contractProfileHash;\n }\n\n const target: { expected: string; actual?: string } = {\n expected: options.expectedTargetId,\n };\n if (options.actualTargetId) {\n target.actual = options.actualTargetId;\n }\n\n const meta: { contractPath: string; configPath?: string } = {\n contractPath: options.contractPath,\n };\n if (options.configPath) {\n meta.configPath = options.configPath;\n }\n\n const result: VerifyDatabaseResult = {\n ok: options.ok,\n summary: options.summary,\n contract,\n target,\n meta,\n timings: {\n total: options.totalTime,\n },\n };\n\n if (options.code) {\n (result as { code?: string }).code = options.code;\n }\n\n if (options.marker) {\n (result as { marker?: { coreHash: string; profileHash: string } }).marker = {\n coreHash: options.marker.coreHash,\n profileHash: options.marker.profileHash,\n };\n }\n\n if (options.missingCodecs) {\n (result as { missingCodecs?: readonly string[] }).missingCodecs = options.missingCodecs;\n }\n\n if (options.codecCoverageSkipped) {\n (result as { codecCoverageSkipped?: boolean }).codecCoverageSkipped =\n options.codecCoverageSkipped;\n }\n\n return result;\n}\n\n/**\n * Type metadata for SQL storage types.\n * Maps contract storage type IDs to native database types.\n */\ninterface SqlTypeMetadata {\n readonly typeId: string;\n readonly familyId: 'sql';\n readonly targetId: string;\n readonly nativeType?: string;\n}\n\n/**\n * Registry mapping type IDs to their metadata.\n * Keyed by contract storage type ID (e.g., 'pg/int4@1').\n */\ntype SqlTypeMetadataRegistry = Map<string, SqlTypeMetadata>;\n\n/**\n * State fields for SQL family instance that hold assembly data.\n */\ninterface SqlFamilyInstanceState {\n readonly operationRegistry: OperationRegistry;\n readonly codecTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly operationTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly extensionIds: ReadonlyArray<string>;\n readonly typeMetadataRegistry: SqlTypeMetadataRegistry;\n}\n\n/**\n * Options for schema verification.\n */\nexport interface SchemaVerifyOptions {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly strict: boolean;\n readonly context?: OperationContext;\n}\n\n/**\n * SQL control family instance interface.\n * Extends ControlFamilyInstance with SQL-specific domain actions.\n */\nexport interface SqlControlFamilyInstance\n extends ControlFamilyInstance<'sql'>,\n SqlFamilyInstanceState {\n /**\n * Validates a contract JSON and returns a validated ContractIR (without mappings).\n * Mappings are runtime-only and should not be part of ContractIR.\n */\n validateContractIR(contractJson: unknown): unknown;\n\n /**\n * Verifies the database marker against the contract.\n * Compares target, coreHash, and profileHash.\n */\n verify(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult>;\n\n /**\n * Verifies the database schema against the contract.\n * Compares contract requirements against live database schema.\n */\n schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult>;\n\n /**\n * Signs the database with the contract marker.\n * Writes or updates the contract marker if schema verification passes.\n * This operation is idempotent - if the marker already matches, no changes are made.\n */\n sign(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult>;\n\n /**\n * Introspects the database schema and returns a family-specific schema IR.\n *\n * This is a read-only operation that returns a snapshot of the live database schema.\n * The method is family-owned and delegates to target/adapter-specific introspectors\n * to perform the actual schema introspection.\n *\n * @param options - Introspection options\n * @param options.driver - Control plane driver for database connection\n * @param options.contractIR - Optional contract IR for contract-guided introspection.\n * When provided, families may use it for filtering, optimization, or validation\n * during introspection. The contract IR does not change the meaning of \"what exists\"\n * in the database - it only guides how introspection is performed.\n * @returns Promise resolving to the family-specific Schema IR (e.g., `SqlSchemaIR` for SQL).\n * The IR represents the complete schema snapshot at the time of introspection.\n */\n introspect(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR?: unknown;\n }): Promise<SqlSchemaIR>;\n\n /**\n * Projects a SQL Schema IR into a core schema view for CLI visualization.\n * Converts SqlSchemaIR (tables, columns, indexes, extensions) into a tree structure.\n */\n toSchemaView(schema: SqlSchemaIR): CoreSchemaView;\n\n /**\n * Emits contract JSON and DTS as strings.\n * Uses the instance's preassembled state (operation registry, type imports, extension IDs).\n * Handles stripping mappings and validation internally.\n */\n emitContract(options: { readonly contractIR: ContractIR | unknown }): Promise<EmitContractResult>;\n}\n\n/**\n * SQL family instance type.\n * Maintains backward compatibility with FamilyInstance while implementing SqlControlFamilyInstance.\n */\nexport type SqlFamilyInstance = SqlControlFamilyInstance;\n\ninterface CreateSqlFamilyInstanceOptions<\n TTargetId extends string = string,\n TTargetDetails = Record<string, never>,\n> {\n readonly target: SqlControlTargetDescriptor<TTargetId, TTargetDetails>;\n readonly adapter: ControlAdapterDescriptor<'sql', string>;\n readonly extensions: readonly ControlExtensionDescriptor<'sql', string>[];\n}\n\n/**\n * Builds a SQL type metadata registry from extension pack manifests.\n * Collects type metadata from target, adapter, and extension pack manifests.\n *\n * @param options - Descriptors for target, adapter, and extensions\n * @returns Registry mapping type IDs to their metadata, filtered by targetId\n */\nfunction buildSqlTypeMetadataRegistry(options: {\n readonly target: ControlTargetDescriptor<'sql', string>;\n readonly adapter: ControlAdapterDescriptor<'sql', string>;\n readonly extensions: readonly ControlExtensionDescriptor<'sql', string>[];\n}): SqlTypeMetadataRegistry {\n const { target, adapter, extensions } = options;\n const registry = new Map<string, SqlTypeMetadata>();\n\n // Get targetId from adapter (they should match)\n const targetId = adapter.targetId;\n\n // Collect descriptors to iterate over\n const descriptors = [target, adapter, ...extensions];\n\n // Iterate over each descriptor's manifest\n for (const descriptor of descriptors) {\n const manifest = descriptor.manifest;\n const storageTypes = manifest.types?.storage;\n\n if (!storageTypes) {\n continue;\n }\n\n // Filter for SQL family and matching targetId\n for (const storageType of storageTypes) {\n if (storageType.familyId === 'sql' && storageType.targetId === targetId) {\n // Use existing entry if present, otherwise create new one\n // Later entries (extensions) can override earlier ones (adapter/target)\n registry.set(storageType.typeId, {\n typeId: storageType.typeId,\n familyId: 'sql',\n targetId: storageType.targetId,\n ...(storageType.nativeType !== undefined ? { nativeType: storageType.nativeType } : {}),\n });\n }\n }\n }\n\n return registry;\n}\n\n/**\n * Creates a SQL family instance for control-plane operations.\n */\nexport function createSqlFamilyInstance<\n TTargetId extends string = string,\n TTargetDetails = Record<string, never>,\n>(options: CreateSqlFamilyInstanceOptions<TTargetId, TTargetDetails>): SqlFamilyInstance {\n const { target, adapter, extensions } = options;\n\n // Build descriptors array for assembly\n // Assembly functions only use manifest and id, so we can pass Control*Descriptor types directly\n const descriptors = [target, adapter, ...extensions];\n\n // Assemble operation registry, type imports, and extension IDs\n const operationRegistry = assembleOperationRegistry(descriptors, convertOperationManifest);\n const codecTypeImports = extractCodecTypeImports(descriptors);\n const operationTypeImports = extractOperationTypeImports(descriptors);\n const extensionIds = extractExtensionIds(adapter, target, extensions);\n\n // Build type metadata registry from manifests\n const typeMetadataRegistry = buildSqlTypeMetadataRegistry({ target, adapter, extensions });\n\n /**\n * Strips mappings from a contract (mappings are runtime-only).\n */\n function stripMappings(contract: unknown): unknown {\n // Type guard to check if contract has mappings\n if (typeof contract === 'object' && contract !== null && 'mappings' in contract) {\n const { mappings: _mappings, ...contractIR } = contract as {\n mappings?: unknown;\n [key: string]: unknown;\n };\n return contractIR;\n }\n return contract;\n }\n\n return {\n familyId: 'sql',\n operationRegistry,\n codecTypeImports,\n operationTypeImports,\n extensionIds,\n typeMetadataRegistry,\n\n validateContractIR(contractJson: unknown): unknown {\n // Validate the contract (this normalizes and validates structure/logic)\n const validated = validateContract<SqlContract<SqlStorage>>(contractJson);\n // Strip mappings before returning ContractIR (mappings are runtime-only)\n const { mappings: _mappings, ...contractIR } = validated;\n return contractIR;\n },\n\n async verify(verifyOptions: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult> {\n const { driver, contractIR, expectedTargetId, contractPath, configPath } = verifyOptions;\n const startTime = Date.now();\n\n // Type guard to ensure contract has required properties\n if (\n typeof contractIR !== 'object' ||\n contractIR === null ||\n !('coreHash' in contractIR) ||\n !('target' in contractIR) ||\n typeof contractIR.coreHash !== 'string' ||\n typeof contractIR.target !== 'string'\n ) {\n throw new Error('Contract is missing required fields: coreHash or target');\n }\n\n // Extract contract hashes and target\n const contractCoreHash = contractIR.coreHash;\n const contractProfileHash =\n 'profileHash' in contractIR && typeof contractIR.profileHash === 'string'\n ? contractIR.profileHash\n : undefined;\n const contractTarget = contractIR.target;\n\n // Read marker from database\n const marker = await readMarker(driver);\n\n // Compute codec coverage (optional)\n let missingCodecs: readonly string[] | undefined;\n let codecCoverageSkipped = false;\n const supportedTypeIds = collectSupportedCodecTypeIds<'sql', string>([\n adapter,\n target,\n ...extensions,\n ]);\n if (supportedTypeIds.length === 0) {\n // Helper is present but returns empty (MVP behavior)\n // Coverage check is skipped - missingCodecs remains undefined\n codecCoverageSkipped = true;\n } else {\n const supportedSet = new Set(supportedTypeIds);\n const usedTypeIds = extractCodecTypeIdsFromContract(contractIR);\n const missing = usedTypeIds.filter((id) => !supportedSet.has(id));\n if (missing.length > 0) {\n missingCodecs = missing;\n }\n }\n\n // Check marker presence\n if (!marker) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: 'PN-RTM-3001',\n summary: 'Marker missing',\n contractCoreHash,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n // Compare target\n if (contractTarget !== expectedTargetId) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: 'PN-RTM-3003',\n summary: 'Target mismatch',\n contractCoreHash,\n marker,\n expectedTargetId,\n actualTargetId: contractTarget,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n // Compare hashes\n if (marker.coreHash !== contractCoreHash) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: 'PN-RTM-3002',\n summary: 'Hash mismatch',\n contractCoreHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n // Compare profile hash if present\n if (contractProfileHash && marker.profileHash !== contractProfileHash) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: 'PN-RTM-3002',\n summary: 'Hash mismatch',\n contractCoreHash,\n contractProfileHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n // Success - all checks passed\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: true,\n summary: 'Database matches contract',\n contractCoreHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n },\n\n async schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult> {\n const { driver, contractIR, strict, context } = options;\n const startTime = Date.now();\n\n // Validate contractIR as SqlContract<SqlStorage>\n const contract = validateContract<SqlContract<SqlStorage>>(contractIR);\n\n // Extract contract hashes and target\n const contractCoreHash = contract.coreHash;\n const contractProfileHash =\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : undefined;\n const contractTarget = contract.target;\n\n // Introspect live schema\n const controlAdapter = adapter.create() as SqlControlAdapter;\n const schemaIR = await controlAdapter.introspect(\n driver as ControlDriverInstance<string>,\n contractIR,\n );\n\n // Compare contract vs schema IR\n const issues: SchemaIssue[] = [];\n const rootChildren: SchemaVerificationNode[] = [];\n\n // Compare tables\n const contractTables = contract.storage.tables;\n const schemaTables = schemaIR.tables;\n\n for (const [tableName, contractTable] of Object.entries(contractTables)) {\n const schemaTable = schemaTables[tableName];\n const tablePath = `storage.tables.${tableName}`;\n\n if (!schemaTable) {\n // Missing table\n issues.push({\n kind: 'missing_table',\n table: tableName,\n message: `Table \"${tableName}\" is missing from database`,\n });\n rootChildren.push({\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 continue;\n }\n\n // Table exists - compare columns, constraints, etc.\n const tableChildren: SchemaVerificationNode[] = [];\n const columnNodes: SchemaVerificationNode[] = [];\n\n // Compare columns\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 // Missing column\n issues.push({\n kind: 'missing_column',\n table: tableName,\n column: columnName,\n message: `Column \"${tableName}\".\"${columnName}\" is missing from database`,\n });\n columnNodes.push({\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 continue;\n }\n\n // Column exists - compare type and nullability\n const columnChildren: SchemaVerificationNode[] = [];\n let columnStatus: 'pass' | 'warn' | 'fail' = 'pass';\n\n // Compare type using nativeType directly\n // Contract now stores nativeType directly (e.g., 'int4'), schema IR has nativeType (e.g., 'int4')\n const contractNativeType = contractColumn.nativeType;\n const schemaNativeType = schemaColumn.nativeType;\n\n if (!contractNativeType) {\n // Contract column doesn't have nativeType - this shouldn't happen with new contract format\n issues.push({\n kind: 'type_mismatch',\n table: tableName,\n column: columnName,\n expected: 'nativeType required',\n actual: schemaNativeType || 'unknown',\n message: `Column \"${tableName}\".\"${columnName}\" is missing nativeType in contract`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'type',\n name: 'type',\n contractPath: `${columnPath}.nativeType`,\n code: 'type_mismatch',\n message: 'Contract column is missing nativeType',\n expected: 'nativeType required',\n actual: schemaNativeType || 'unknown',\n children: [],\n });\n columnStatus = 'fail';\n } else if (!schemaNativeType) {\n // Schema IR doesn't have nativeType - this shouldn't happen\n issues.push({\n kind: 'type_mismatch',\n table: tableName,\n column: columnName,\n expected: contractNativeType,\n actual: 'unknown',\n message: `Column \"${tableName}\".\"${columnName}\" has type mismatch: schema column has no nativeType`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'type',\n name: 'type',\n contractPath: `${columnPath}.nativeType`,\n code: 'type_mismatch',\n message: 'Schema column has no nativeType',\n expected: contractNativeType,\n actual: 'unknown',\n children: [],\n });\n columnStatus = 'fail';\n } else if (contractNativeType !== schemaNativeType) {\n // Compare native types directly\n issues.push({\n kind: 'type_mismatch',\n table: tableName,\n column: columnName,\n expected: contractNativeType,\n actual: schemaNativeType,\n message: `Column \"${tableName}\".\"${columnName}\" has type mismatch: expected \"${contractNativeType}\", got \"${schemaNativeType}\"`,\n });\n columnChildren.push({\n status: 'fail',\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 = 'fail';\n }\n\n // Optionally validate that codecId (if present) and nativeType agree with registry\n if (contractColumn.codecId) {\n const typeMetadata = typeMetadataRegistry.get(contractColumn.codecId);\n if (!typeMetadata) {\n // Warning: codecId not found in registry\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 \"${contractColumn.codecId}\" not found in type metadata registry`,\n expected: contractColumn.codecId,\n actual: undefined,\n children: [],\n });\n } else if (typeMetadata.nativeType && typeMetadata.nativeType !== contractNativeType) {\n // Warning: codecId and nativeType don't agree with registry\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 \"${contractColumn.codecId}\" maps to nativeType \"${typeMetadata.nativeType}\" in registry, but contract has \"${contractNativeType}\"`,\n expected: typeMetadata.nativeType,\n actual: contractNativeType,\n children: [],\n });\n }\n }\n\n // Compare nullability\n if (contractColumn.nullable !== schemaColumn.nullable) {\n issues.push({\n kind: 'nullability_mismatch',\n table: tableName,\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 columnChildren.push({\n status: 'fail',\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 = 'fail';\n }\n\n // Compute column status from children (fail > warn > pass)\n const computedColumnStatus = columnChildren.some((c) => c.status === 'fail')\n ? 'fail'\n : columnChildren.some((c) => c.status === 'warn')\n ? 'warn'\n : 'pass';\n // Use computed status if we have children, otherwise use the manually set status\n const finalColumnStatus = columnChildren.length > 0 ? computedColumnStatus : columnStatus;\n\n // Build column node\n const nullableText = contractColumn.nullable ? 'nullable' : 'not nullable';\n // Format: columnName: nativeType (codecId) (nullability)\n // Reuse contractNativeType from above scope\n const columnTypeDisplay = contractColumn.codecId\n ? `${contractNativeType} (${contractColumn.codecId})`\n : contractNativeType;\n // Collect failure messages from children to create a summary message\n const failureMessages = columnChildren\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 columnMessage =\n finalColumnStatus === 'fail' && failureMessages.length > 0\n ? failureMessages.join('; ')\n : '';\n const columnCode =\n finalColumnStatus === 'fail' && columnChildren.length > 0 && columnChildren[0]\n ? columnChildren[0].code\n : finalColumnStatus === 'warn' && columnChildren.length > 0 && columnChildren[0]\n ? columnChildren[0].code\n : '';\n columnNodes.push({\n status: finalColumnStatus,\n kind: 'column',\n name: `${columnName}: ${columnTypeDisplay} (${nullableText})`,\n contractPath: columnPath,\n code: columnCode,\n message: columnMessage,\n expected: undefined,\n actual: undefined,\n children: columnChildren,\n });\n }\n\n // Group columns under a \"columns\" header if we have any columns\n if (columnNodes.length > 0) {\n const columnsStatus = columnNodes.some((c) => c.status === 'fail')\n ? 'fail'\n : columnNodes.some((c) => c.status === 'warn')\n ? 'warn'\n : 'pass';\n tableChildren.push({\n status: columnsStatus,\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\n // Check for extra columns in strict mode\n if (strict) {\n for (const [columnName, schemaColumn] of Object.entries(schemaTable.columns)) {\n if (!contractTable.columns[columnName]) {\n issues.push({\n kind: 'missing_column',\n table: tableName,\n column: columnName,\n message: `Extra column \"${tableName}\".\"${columnName}\" found in database (not in contract)`,\n });\n columnNodes.push({\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: schemaColumn.nativeType,\n children: [],\n });\n }\n }\n }\n\n // Compare primary key\n if (contractTable.primaryKey) {\n const pkStatus = comparePrimaryKey(\n contractTable.primaryKey,\n schemaTable.primaryKey,\n tableName,\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 {\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 // Extra primary key in strict mode\n issues.push({\n kind: 'primary_key_mismatch',\n table: tableName,\n message: 'Extra primary key found in database (not in contract)',\n });\n tableChildren.push({\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 }\n\n // Compare foreign keys\n const fkStatuses = compareForeignKeys(\n contractTable.foreignKeys,\n schemaTable.foreignKeys,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...fkStatuses);\n\n // Compare unique constraints\n const uniqueStatuses = compareUniqueConstraints(\n contractTable.uniques,\n schemaTable.uniques,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...uniqueStatuses);\n\n // Compare indexes\n const indexStatuses = compareIndexes(\n contractTable.indexes,\n schemaTable.indexes,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...indexStatuses);\n\n // Build table node\n const tableStatus = tableChildren.some((c) => c.status === 'fail')\n ? 'fail'\n : tableChildren.some((c) => c.status === 'warn')\n ? 'warn'\n : 'pass';\n // Collect failure messages from children to create a summary message\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 rootChildren.push({\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\n // Check for extra tables in strict mode\n if (strict) {\n for (const tableName of Object.keys(schemaTables)) {\n if (!contractTables[tableName]) {\n issues.push({\n kind: 'missing_table',\n table: tableName,\n message: `Extra table \"${tableName}\" found in database (not in contract)`,\n });\n rootChildren.push({\n status: 'fail',\n kind: 'table',\n name: `table ${tableName}`,\n contractPath: `storage.tables.${tableName}`,\n code: 'extra_table',\n message: `Extra table \"${tableName}\" found`,\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n }\n\n // Compare extensions\n const extensionStatuses = compareExtensions(\n contract.extensions,\n schemaIR.extensions,\n contractTarget,\n issues,\n strict,\n );\n rootChildren.push(...extensionStatuses);\n\n // Build root node\n const rootStatus = rootChildren.some((c) => c.status === 'fail')\n ? 'fail'\n : rootChildren.some((c) => c.status === 'warn')\n ? 'warn'\n : 'pass';\n const root: SchemaVerificationNode = {\n status: rootStatus,\n kind: 'contract',\n name: 'contract',\n contractPath: '',\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: rootChildren,\n };\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 ...(code ? { code } : {}),\n summary,\n contract: {\n coreHash: contractCoreHash,\n ...(contractProfileHash ? { 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 ...(context?.contractPath ? { contractPath: context.contractPath } : {}),\n ...(context?.configPath ? { configPath: context.configPath } : {}),\n },\n timings: {\n total: totalTime,\n },\n };\n },\n async sign(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult> {\n const { driver, contractIR, contractPath, configPath } = options;\n const startTime = Date.now();\n\n // Validate contractIR as SqlContract<SqlStorage>\n const contract = validateContract<SqlContract<SqlStorage>>(contractIR);\n\n // Extract contract hashes and target\n const contractCoreHash = contract.coreHash;\n const contractProfileHash =\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : contractCoreHash;\n const contractTarget = contract.target;\n\n // Ensure marker schema and table exist\n await driver.query(ensureSchemaStatement.sql, ensureSchemaStatement.params);\n await driver.query(ensureTableStatement.sql, ensureTableStatement.params);\n\n // Read existing marker\n const existingMarker = await readMarker(driver);\n\n // Determine if we need to write/update marker\n let markerCreated = false;\n let markerUpdated = false;\n let previousHashes: { coreHash?: string; profileHash?: string } | undefined;\n\n if (!existingMarker) {\n // No marker exists - insert new one\n const write = writeContractMarker({\n coreHash: contractCoreHash,\n profileHash: contractProfileHash,\n contractJson: contractIR,\n canonicalVersion: 1,\n });\n await driver.query(write.insert.sql, write.insert.params);\n markerCreated = true;\n } else {\n // Marker exists - check if hashes differ\n const existingCoreHash = existingMarker.coreHash;\n const existingProfileHash = existingMarker.profileHash;\n\n // Compare hashes (use strict equality to ensure exact match)\n const coreHashMatches = existingCoreHash === contractCoreHash;\n const profileHashMatches = existingProfileHash === contractProfileHash;\n\n if (!coreHashMatches || !profileHashMatches) {\n // Hashes differ - update marker and capture previous hashes for output\n previousHashes = {\n coreHash: existingCoreHash,\n profileHash: existingProfileHash,\n };\n const write = writeContractMarker({\n coreHash: contractCoreHash,\n profileHash: contractProfileHash,\n contractJson: contractIR,\n canonicalVersion: existingMarker.canonicalVersion ?? 1,\n });\n await driver.query(write.update.sql, write.update.params);\n markerUpdated = true;\n }\n // If hashes match, no-op (idempotent) - previousHashes remains undefined\n }\n\n // Build summary message\n let summary: string;\n if (markerCreated) {\n summary = 'Database signed (marker created)';\n } else if (markerUpdated) {\n summary = `Database signed (marker updated from ${previousHashes?.coreHash ?? 'unknown'})`;\n } else {\n summary = 'Database already signed with this contract';\n }\n\n const totalTime = Date.now() - startTime;\n\n return {\n ok: true,\n summary,\n contract: {\n coreHash: contractCoreHash,\n profileHash: contractProfileHash,\n },\n target: {\n expected: contractTarget,\n actual: contractTarget,\n },\n marker: {\n created: markerCreated,\n updated: markerUpdated,\n ...(previousHashes ? { previous: previousHashes } : {}),\n },\n meta: {\n contractPath,\n ...(configPath ? { configPath } : {}),\n },\n timings: {\n total: totalTime,\n },\n };\n },\n async introspect(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR?: unknown;\n }): Promise<SqlSchemaIR> {\n const { driver, contractIR } = options;\n\n // ControlAdapterDescriptor has create() method that returns SqlControlAdapter\n const controlAdapter = adapter.create() as SqlControlAdapter;\n return controlAdapter.introspect(driver as ControlDriverInstance<string>, contractIR);\n },\n\n toSchemaView(schema: SqlSchemaIR): CoreSchemaView {\n const rootLabel = 'contract';\n\n // Build table nodes\n const tableNodes: readonly SchemaTreeNode[] = Object.entries(schema.tables).map(\n ([tableName, table]: [string, SqlTableIR]) => {\n const children: SchemaTreeNode[] = [];\n\n // Add column nodes grouped under \"columns\"\n const columnNodes: SchemaTreeNode[] = [];\n for (const [columnName, column] of Object.entries(table.columns)) {\n const nullableText = column.nullable ? '(nullable)' : '(not nullable)';\n // Always display nativeType for introspection (database state)\n const typeDisplay = column.nativeType;\n const label = `${columnName}: ${typeDisplay} ${nullableText}`;\n columnNodes.push({\n kind: 'field',\n id: `column-${tableName}-${columnName}`,\n label,\n meta: {\n nativeType: column.nativeType,\n nullable: column.nullable,\n },\n });\n }\n\n // Add \"columns\" grouping node if there are columns\n if (columnNodes.length > 0) {\n children.push({\n kind: 'collection',\n id: `columns-${tableName}`,\n label: 'columns',\n children: columnNodes,\n });\n }\n\n // Add primary key node if present\n if (table.primaryKey) {\n const pkColumns = table.primaryKey.columns.join(', ');\n children.push({\n kind: 'index',\n id: `primary-key-${tableName}`,\n label: `primary key: ${pkColumns}`,\n meta: {\n columns: table.primaryKey.columns,\n ...(table.primaryKey.name ? { name: table.primaryKey.name } : {}),\n },\n });\n }\n\n // Add unique constraint nodes\n for (const unique of table.uniques) {\n const name = unique.name ?? `${tableName}_${unique.columns.join('_')}_unique`;\n const label = `unique ${name}`;\n children.push({\n kind: 'index',\n id: `unique-${tableName}-${name}`,\n label,\n meta: {\n columns: unique.columns,\n unique: true,\n },\n });\n }\n\n // Add index nodes\n for (const index of table.indexes) {\n const name = index.name ?? `${tableName}_${index.columns.join('_')}_idx`;\n const label = index.unique ? `unique index ${name}` : `index ${name}`;\n children.push({\n kind: 'index',\n id: `index-${tableName}-${name}`,\n label,\n meta: {\n columns: index.columns,\n unique: index.unique,\n },\n });\n }\n\n // Build table meta\n const tableMeta: Record<string, unknown> = {};\n if (table.primaryKey) {\n tableMeta['primaryKey'] = table.primaryKey.columns;\n if (table.primaryKey.name) {\n tableMeta['primaryKeyName'] = table.primaryKey.name;\n }\n }\n if (table.foreignKeys.length > 0) {\n tableMeta['foreignKeys'] = table.foreignKeys.map((fk) => ({\n columns: fk.columns,\n referencedTable: fk.referencedTable,\n referencedColumns: fk.referencedColumns,\n ...(fk.name ? { name: fk.name } : {}),\n }));\n }\n\n const node: SchemaTreeNode = {\n kind: 'entity',\n id: `table-${tableName}`,\n label: `table ${tableName}`,\n ...(Object.keys(tableMeta).length > 0 ? { meta: tableMeta } : {}),\n ...(children.length > 0 ? { children: children as readonly SchemaTreeNode[] } : {}),\n };\n return node;\n },\n );\n\n // Add extension nodes (format: \"extensionName extension is enabled\")\n const extensionNodes: readonly SchemaTreeNode[] = schema.extensions.map((extName) => ({\n kind: 'extension',\n id: `extension-${extName}`,\n label: `${extName} extension is enabled`,\n }));\n\n // Combine all children\n const rootChildren = [...tableNodes, ...extensionNodes];\n\n const rootNode: SchemaTreeNode = {\n kind: 'root',\n id: 'sql-schema',\n label: rootLabel,\n ...(rootChildren.length > 0 ? { children: rootChildren } : {}),\n };\n\n return {\n root: rootNode,\n };\n },\n\n async emitContract({ contractIR }): Promise<EmitContractResult> {\n // Strip mappings if present (mappings are runtime-only)\n const contractWithoutMappings = stripMappings(contractIR);\n\n // Validate and normalize the contract\n const validatedIR = this.validateContractIR(contractWithoutMappings) as ContractIR;\n\n const result = await emit(\n validatedIR,\n {\n outputDir: '',\n operationRegistry,\n codecTypeImports,\n operationTypeImports,\n extensionIds,\n },\n sqlTargetFamilyHook,\n );\n\n return {\n contractJson: result.contractJson,\n contractDts: result.contractDts,\n coreHash: result.coreHash,\n profileHash: result.profileHash,\n };\n },\n };\n}\n"],"mappings":"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","names":["totalTime","options","convertOperationManifest"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { OperationRegistry } from '@prisma-next/operations';
|
|
2
2
|
import { ExtensionPackManifest } from '@prisma-next/contract/pack-manifest-types';
|
|
3
|
-
import { ControlTargetDescriptor,
|
|
3
|
+
import { ControlTargetDescriptor, ControlDriverInstance, OperationContext, ControlFamilyInstance, VerifyDatabaseResult, VerifyDatabaseSchemaResult, SignDatabaseResult, EmitContractResult, ControlFamilyDescriptor, ControlAdapterDescriptor, ControlDriverDescriptor, ControlExtensionDescriptor } from '@prisma-next/core-control-plane/types';
|
|
4
4
|
import { ContractIR as ContractIR$1 } from '@prisma-next/contract/ir';
|
|
5
5
|
import { TypesImportSpec as TypesImportSpec$1 } from '@prisma-next/contract/types';
|
|
6
6
|
import { CoreSchemaView } from '@prisma-next/core-control-plane/schema-view';
|
|
7
7
|
import { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
8
|
+
import { Result, NotOk, Ok } from '@prisma-next/core-control-plane/result';
|
|
8
9
|
import { SqlContract, SqlStorage as SqlStorage$1 } from '@prisma-next/sql-contract/types';
|
|
9
10
|
|
|
10
11
|
type StorageColumn = {
|
|
@@ -99,7 +100,7 @@ interface ValidationContext {
|
|
|
99
100
|
|
|
100
101
|
type AnyRecord = Readonly<Record<string, unknown>>;
|
|
101
102
|
type MigrationOperationClass = 'additive' | 'widening' | 'destructive';
|
|
102
|
-
interface
|
|
103
|
+
interface MigrationOperationPolicy {
|
|
103
104
|
readonly allowedOperationClasses: readonly MigrationOperationClass[];
|
|
104
105
|
}
|
|
105
106
|
interface MigrationPlanOperationStep {
|
|
@@ -112,8 +113,11 @@ interface MigrationPlanOperationTarget<TTargetDetails> {
|
|
|
112
113
|
readonly details?: TTargetDetails;
|
|
113
114
|
}
|
|
114
115
|
interface MigrationPlanOperation<TTargetDetails = Record<string, never>> {
|
|
116
|
+
/** Unique identifier for this operation (e.g., "table.users.create"). */
|
|
115
117
|
readonly id: string;
|
|
118
|
+
/** Human-readable label for display in UI/CLI (e.g., "Create table users"). */
|
|
116
119
|
readonly label: string;
|
|
120
|
+
/** Optional detailed explanation of what this operation does and why. */
|
|
117
121
|
readonly summary?: string;
|
|
118
122
|
readonly operationClass: MigrationOperationClass;
|
|
119
123
|
readonly target: MigrationPlanOperationTarget<TTargetDetails>;
|
|
@@ -128,12 +132,20 @@ interface MigrationPlanContractInfo {
|
|
|
128
132
|
}
|
|
129
133
|
interface MigrationPlan<TTargetDetails = Record<string, never>> {
|
|
130
134
|
readonly targetId: string;
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Origin contract identity that the plan expects the database to currently be at.
|
|
137
|
+
* If omitted, the runner treats the origin as "no marker present" (empty database),
|
|
138
|
+
* and will only proceed if no marker exists (or if the marker already matches destination).
|
|
139
|
+
*/
|
|
140
|
+
readonly origin?: MigrationPlanContractInfo | null;
|
|
141
|
+
/**
|
|
142
|
+
* Destination contract identity that the plan intends to reach.
|
|
143
|
+
*/
|
|
144
|
+
readonly destination: MigrationPlanContractInfo;
|
|
133
145
|
readonly operations: readonly MigrationPlanOperation<TTargetDetails>[];
|
|
134
146
|
readonly meta?: AnyRecord;
|
|
135
147
|
}
|
|
136
|
-
type PlannerConflictKind = 'typeMismatch' | 'nullabilityConflict' | 'indexIncompatible' | 'foreignKeyConflict' | 'missingButNonAdditive' | 'extensionMissing' | 'unsupportedOperation';
|
|
148
|
+
type PlannerConflictKind = 'typeMismatch' | 'nullabilityConflict' | 'indexIncompatible' | 'foreignKeyConflict' | 'missingButNonAdditive' | 'unsupportedExtension' | 'extensionMissing' | 'unsupportedOperation';
|
|
137
149
|
interface PlannerConflictLocation {
|
|
138
150
|
readonly table?: string;
|
|
139
151
|
readonly column?: string;
|
|
@@ -160,19 +172,71 @@ type PlannerResult<TTargetDetails = Record<string, never>> = PlannerSuccessResul
|
|
|
160
172
|
interface MigrationPlannerPlanOptions {
|
|
161
173
|
readonly contract: SqlContract<SqlStorage$1>;
|
|
162
174
|
readonly schema: SqlSchemaIR;
|
|
163
|
-
readonly policy:
|
|
175
|
+
readonly policy: MigrationOperationPolicy;
|
|
164
176
|
readonly schemaName?: string;
|
|
165
177
|
}
|
|
166
178
|
interface MigrationPlanner<TTargetDetails = Record<string, never>> {
|
|
167
179
|
plan(options: MigrationPlannerPlanOptions): PlannerResult<TTargetDetails>;
|
|
168
180
|
}
|
|
181
|
+
interface MigrationRunnerExecuteCallbacks<TTargetDetails = Record<string, never>> {
|
|
182
|
+
onOperationStart?(operation: MigrationPlanOperation<TTargetDetails>): void;
|
|
183
|
+
onOperationComplete?(operation: MigrationPlanOperation<TTargetDetails>): void;
|
|
184
|
+
}
|
|
185
|
+
interface MigrationRunnerExecuteOptions<TTargetDetails = Record<string, never>> {
|
|
186
|
+
readonly plan: MigrationPlan<TTargetDetails>;
|
|
187
|
+
readonly driver: ControlDriverInstance;
|
|
188
|
+
/**
|
|
189
|
+
* Destination contract IR.
|
|
190
|
+
* Must correspond to `plan.destination` and is used for schema verification and marker/ledger writes.
|
|
191
|
+
*/
|
|
192
|
+
readonly destinationContract: SqlContract<SqlStorage$1>;
|
|
193
|
+
/**
|
|
194
|
+
* Execution-time policy that defines which operation classes are allowed.
|
|
195
|
+
* The runner validates each operation against this policy before execution.
|
|
196
|
+
*/
|
|
197
|
+
readonly policy: MigrationOperationPolicy;
|
|
198
|
+
readonly schemaName?: string;
|
|
199
|
+
readonly strictVerification?: boolean;
|
|
200
|
+
readonly callbacks?: MigrationRunnerExecuteCallbacks<TTargetDetails>;
|
|
201
|
+
readonly context?: OperationContext;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Error codes for migration runner failures.
|
|
205
|
+
*/
|
|
206
|
+
type MigrationRunnerErrorCode = 'DESTINATION_CONTRACT_MISMATCH' | 'MARKER_ORIGIN_MISMATCH' | 'POLICY_VIOLATION' | 'PRECHECK_FAILED' | 'POSTCHECK_FAILED' | 'SCHEMA_VERIFY_FAILED' | 'EXECUTION_FAILED';
|
|
207
|
+
/**
|
|
208
|
+
* Detailed information about a migration runner failure.
|
|
209
|
+
* This is the failure payload type for `NotOk<MigrationRunnerFailure>`.
|
|
210
|
+
*/
|
|
211
|
+
interface MigrationRunnerFailure {
|
|
212
|
+
readonly code: MigrationRunnerErrorCode;
|
|
213
|
+
readonly summary: string;
|
|
214
|
+
readonly why?: string;
|
|
215
|
+
readonly meta?: AnyRecord;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Success value for migration runner execution.
|
|
219
|
+
*/
|
|
220
|
+
interface MigrationRunnerSuccessValue {
|
|
221
|
+
readonly operationsPlanned: number;
|
|
222
|
+
readonly operationsExecuted: number;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Result union for migration runner execution.
|
|
226
|
+
* Either success with operation counts, or failure with error details.
|
|
227
|
+
*/
|
|
228
|
+
type MigrationRunnerResult = Result<MigrationRunnerSuccessValue, MigrationRunnerFailure>;
|
|
229
|
+
interface MigrationRunner<TTargetDetails = Record<string, never>> {
|
|
230
|
+
execute(options: MigrationRunnerExecuteOptions<TTargetDetails>): Promise<MigrationRunnerResult>;
|
|
231
|
+
}
|
|
169
232
|
interface SqlControlTargetDescriptor<TTargetId extends string, TTargetDetails = Record<string, never>> extends ControlTargetDescriptor<'sql', TTargetId> {
|
|
170
233
|
createPlanner(family: SqlControlFamilyInstance): MigrationPlanner<TTargetDetails>;
|
|
234
|
+
createRunner(family: SqlControlFamilyInstance): MigrationRunner<TTargetDetails>;
|
|
171
235
|
}
|
|
172
236
|
interface CreateMigrationPlanOptions<TTargetDetails> {
|
|
173
237
|
readonly targetId: string;
|
|
174
|
-
readonly
|
|
175
|
-
readonly
|
|
238
|
+
readonly origin?: MigrationPlanContractInfo | null;
|
|
239
|
+
readonly destination: MigrationPlanContractInfo;
|
|
176
240
|
readonly operations: readonly MigrationPlanOperation<TTargetDetails>[];
|
|
177
241
|
readonly meta?: AnyRecord;
|
|
178
242
|
}
|
|
@@ -202,6 +266,15 @@ interface SqlFamilyInstanceState {
|
|
|
202
266
|
readonly extensionIds: ReadonlyArray<string>;
|
|
203
267
|
readonly typeMetadataRegistry: SqlTypeMetadataRegistry;
|
|
204
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Options for schema verification.
|
|
271
|
+
*/
|
|
272
|
+
interface SchemaVerifyOptions {
|
|
273
|
+
readonly driver: ControlDriverInstance;
|
|
274
|
+
readonly contractIR: unknown;
|
|
275
|
+
readonly strict: boolean;
|
|
276
|
+
readonly context?: OperationContext;
|
|
277
|
+
}
|
|
205
278
|
/**
|
|
206
279
|
* SQL control family instance interface.
|
|
207
280
|
* Extends ControlFamilyInstance with SQL-specific domain actions.
|
|
@@ -227,13 +300,7 @@ interface SqlControlFamilyInstance extends ControlFamilyInstance<'sql'>, SqlFami
|
|
|
227
300
|
* Verifies the database schema against the contract.
|
|
228
301
|
* Compares contract requirements against live database schema.
|
|
229
302
|
*/
|
|
230
|
-
schemaVerify(options:
|
|
231
|
-
readonly driver: ControlDriverInstance;
|
|
232
|
-
readonly contractIR: unknown;
|
|
233
|
-
readonly strict: boolean;
|
|
234
|
-
readonly contractPath: string;
|
|
235
|
-
readonly configPath?: string;
|
|
236
|
-
}): Promise<VerifyDatabaseSchemaResult>;
|
|
303
|
+
schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult>;
|
|
237
304
|
/**
|
|
238
305
|
* Signs the database with the contract marker.
|
|
239
306
|
* Writes or updates the contract marker if schema verification passes.
|
|
@@ -310,11 +377,25 @@ declare class SqlFamilyDescriptor implements ControlFamilyDescriptor<'sql', SqlC
|
|
|
310
377
|
declare function createMigrationPlan<TTargetDetails = Record<string, never>>(options: CreateMigrationPlanOptions<TTargetDetails>): MigrationPlan<TTargetDetails>;
|
|
311
378
|
declare function plannerSuccess<TTargetDetails>(plan: MigrationPlan<TTargetDetails>): PlannerSuccessResult<TTargetDetails>;
|
|
312
379
|
declare function plannerFailure(conflicts: readonly PlannerConflict[]): PlannerFailureResult;
|
|
380
|
+
/**
|
|
381
|
+
* Creates a successful migration runner result.
|
|
382
|
+
*/
|
|
383
|
+
declare function runnerSuccess(value: {
|
|
384
|
+
operationsPlanned: number;
|
|
385
|
+
operationsExecuted: number;
|
|
386
|
+
}): Ok<MigrationRunnerSuccessValue>;
|
|
387
|
+
/**
|
|
388
|
+
* Creates a failed migration runner result.
|
|
389
|
+
*/
|
|
390
|
+
declare function runnerFailure(code: MigrationRunnerErrorCode, summary: string, options?: {
|
|
391
|
+
why?: string;
|
|
392
|
+
meta?: AnyRecord;
|
|
393
|
+
}): NotOk<MigrationRunnerFailure>;
|
|
313
394
|
|
|
314
395
|
/**
|
|
315
396
|
* Policy used by `db init`: additive-only operations, no widening/destructive steps.
|
|
316
397
|
*/
|
|
317
|
-
declare const INIT_ADDITIVE_POLICY:
|
|
398
|
+
declare const INIT_ADDITIVE_POLICY: MigrationOperationPolicy;
|
|
318
399
|
|
|
319
400
|
/**
|
|
320
401
|
* SQL family descriptor for control plane (CLI/config).
|
|
@@ -322,4 +403,4 @@ declare const INIT_ADDITIVE_POLICY: MigrationPolicy;
|
|
|
322
403
|
*/
|
|
323
404
|
declare const _default: SqlFamilyDescriptor;
|
|
324
405
|
|
|
325
|
-
export { type CreateMigrationPlanOptions, INIT_ADDITIVE_POLICY, type MigrationOperationClass, type MigrationPlan, type MigrationPlanContractInfo, type MigrationPlanOperation, type MigrationPlanOperationStep, type MigrationPlanOperationTarget, type MigrationPlanner, type MigrationPlannerPlanOptions, type
|
|
406
|
+
export { type CreateMigrationPlanOptions, INIT_ADDITIVE_POLICY, type MigrationOperationClass, type MigrationOperationPolicy, type MigrationPlan, type MigrationPlanContractInfo, type MigrationPlanOperation, type MigrationPlanOperationStep, type MigrationPlanOperationTarget, type MigrationPlanner, type MigrationPlannerPlanOptions, type MigrationRunner, type MigrationRunnerErrorCode, type MigrationRunnerExecuteCallbacks, type MigrationRunnerExecuteOptions, type MigrationRunnerFailure, type MigrationRunnerResult, type MigrationRunnerSuccessValue, type PlannerConflict, type PlannerConflictKind, type PlannerConflictLocation, type PlannerFailureResult, type PlannerResult, type PlannerSuccessResult, type SchemaVerifyOptions, type SqlControlFamilyInstance, type SqlControlTargetDescriptor, createMigrationPlan, _default as default, plannerFailure, plannerSuccess, runnerFailure, runnerSuccess };
|
package/dist/exports/control.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createSqlFamilyInstance
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FDYFNYMY.js";
|
|
4
4
|
import "./chunk-3HYKCN35.js";
|
|
5
5
|
|
|
6
6
|
// src/core/descriptor.ts
|
|
@@ -25,6 +25,7 @@ var SqlFamilyDescriptor = class {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
// src/core/migrations/plan-helpers.ts
|
|
28
|
+
import { notOk, ok } from "@prisma-next/core-control-plane/result";
|
|
28
29
|
var readOnlyEmptyObject = Object.freeze({});
|
|
29
30
|
function cloneRecord(value) {
|
|
30
31
|
if (value === readOnlyEmptyObject) {
|
|
@@ -46,10 +47,22 @@ function freezeSteps(steps) {
|
|
|
46
47
|
)
|
|
47
48
|
);
|
|
48
49
|
}
|
|
50
|
+
function freezeDetailsValue(value) {
|
|
51
|
+
if (value === null || value === void 0) {
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
if (typeof value !== "object") {
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
if (Array.isArray(value)) {
|
|
58
|
+
return Object.freeze([...value]);
|
|
59
|
+
}
|
|
60
|
+
return Object.freeze({ ...value });
|
|
61
|
+
}
|
|
49
62
|
function freezeTargetDetails(target) {
|
|
50
63
|
return Object.freeze({
|
|
51
64
|
id: target.id,
|
|
52
|
-
...target.details ? { details: target.details } : {}
|
|
65
|
+
...target.details !== void 0 ? { details: freezeDetailsValue(target.details) } : {}
|
|
53
66
|
});
|
|
54
67
|
}
|
|
55
68
|
function freezeOperation(operation) {
|
|
@@ -71,16 +84,11 @@ function freezeOperations(operations) {
|
|
|
71
84
|
}
|
|
72
85
|
return Object.freeze(operations.map((operation) => freezeOperation(operation)));
|
|
73
86
|
}
|
|
74
|
-
function normalizePolicy(policy) {
|
|
75
|
-
return Object.freeze({
|
|
76
|
-
allowedOperationClasses: Object.freeze([...policy.allowedOperationClasses])
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
87
|
function createMigrationPlan(options) {
|
|
80
88
|
return Object.freeze({
|
|
81
89
|
targetId: options.targetId,
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
...options.origin !== void 0 ? { origin: options.origin ? Object.freeze({ ...options.origin }) : null } : {},
|
|
91
|
+
destination: Object.freeze({ ...options.destination }),
|
|
84
92
|
operations: freezeOperations(options.operations),
|
|
85
93
|
...options.meta ? { meta: cloneRecord(options.meta) } : {}
|
|
86
94
|
});
|
|
@@ -107,6 +115,23 @@ function plannerFailure(conflicts) {
|
|
|
107
115
|
)
|
|
108
116
|
});
|
|
109
117
|
}
|
|
118
|
+
function runnerSuccess(value) {
|
|
119
|
+
return ok(
|
|
120
|
+
Object.freeze({
|
|
121
|
+
operationsPlanned: value.operationsPlanned,
|
|
122
|
+
operationsExecuted: value.operationsExecuted
|
|
123
|
+
})
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
function runnerFailure(code, summary, options) {
|
|
127
|
+
const failure = Object.freeze({
|
|
128
|
+
code,
|
|
129
|
+
summary,
|
|
130
|
+
...options?.why ? { why: options.why } : {},
|
|
131
|
+
...options?.meta ? { meta: cloneRecord(options.meta) } : {}
|
|
132
|
+
});
|
|
133
|
+
return notOk(failure);
|
|
134
|
+
}
|
|
110
135
|
|
|
111
136
|
// src/core/migrations/policies.ts
|
|
112
137
|
var INIT_ADDITIVE_POLICY = Object.freeze({
|
|
@@ -120,6 +145,8 @@ export {
|
|
|
120
145
|
createMigrationPlan,
|
|
121
146
|
control_default as default,
|
|
122
147
|
plannerFailure,
|
|
123
|
-
plannerSuccess
|
|
148
|
+
plannerSuccess,
|
|
149
|
+
runnerFailure,
|
|
150
|
+
runnerSuccess
|
|
124
151
|
};
|
|
125
152
|
//# sourceMappingURL=control.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/descriptor.ts","../../src/core/migrations/plan-helpers.ts","../../src/core/migrations/policies.ts","../../src/exports/control.ts"],"sourcesContent":["import type { ExtensionPackManifest } from '@prisma-next/contract/pack-manifest-types';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n} from '@prisma-next/core-control-plane/types';\nimport { sqlTargetFamilyHook } from '@prisma-next/sql-contract-emitter';\nimport { createSqlFamilyInstance, type SqlControlFamilyInstance } from './instance';\nimport type { SqlControlTargetDescriptor } from './migrations/types';\n\n/**\n * SQL family manifest.\n */\nconst sqlFamilyManifest: ExtensionPackManifest = {\n id: 'sql',\n version: '0.0.1',\n};\n\n/**\n * SQL family descriptor implementation.\n * Provides the SQL family hook and factory method.\n */\nexport class SqlFamilyDescriptor\n implements ControlFamilyDescriptor<'sql', SqlControlFamilyInstance>\n{\n readonly kind = 'family' as const;\n readonly id = 'sql';\n readonly familyId = 'sql' as const;\n readonly manifest = sqlFamilyManifest;\n readonly hook = sqlTargetFamilyHook;\n\n create<TTargetId extends string, TTargetDetails = Record<string, never>>(options: {\n readonly target: SqlControlTargetDescriptor<TTargetId, TTargetDetails>;\n readonly adapter: ControlAdapterDescriptor<'sql', TTargetId>;\n readonly driver: ControlDriverDescriptor<'sql', TTargetId>;\n readonly extensions: readonly ControlExtensionDescriptor<'sql', TTargetId>[];\n }): SqlControlFamilyInstance {\n return createSqlFamilyInstance({\n target: options.target,\n adapter: options.adapter,\n extensions: options.extensions,\n });\n }\n}\n","import type {\n AnyRecord,\n CreateMigrationPlanOptions,\n MigrationPlan,\n MigrationPlanOperation,\n MigrationPlanOperationStep,\n MigrationPlanOperationTarget,\n MigrationPolicy,\n PlannerConflict,\n PlannerFailureResult,\n PlannerSuccessResult,\n} from './types';\n\nconst readOnlyEmptyObject: Record<string, never> = Object.freeze({});\n\nfunction cloneRecord<T extends AnyRecord>(value: T): T {\n if (value === readOnlyEmptyObject) {\n return value;\n }\n return Object.freeze({ ...value }) as T;\n}\n\nfunction freezeSteps(\n steps: readonly MigrationPlanOperationStep[],\n): readonly MigrationPlanOperationStep[] {\n if (steps.length === 0) {\n return Object.freeze([]);\n }\n return Object.freeze(\n steps.map((step) =>\n Object.freeze({\n description: step.description,\n sql: step.sql,\n ...(step.meta ? { meta: cloneRecord(step.meta) } : {}),\n }),\n ),\n );\n}\n\nfunction freezeTargetDetails<TTargetDetails>(\n target: MigrationPlanOperationTarget<TTargetDetails>,\n): MigrationPlanOperationTarget<TTargetDetails> {\n return Object.freeze({\n id: target.id,\n ...(target.details ? { details: target.details } : {}),\n });\n}\n\nfunction freezeOperation<TTargetDetails>(\n operation: MigrationPlanOperation<TTargetDetails>,\n): MigrationPlanOperation<TTargetDetails> {\n return Object.freeze({\n id: operation.id,\n label: operation.label,\n ...(operation.summary ? { summary: operation.summary } : {}),\n operationClass: operation.operationClass,\n target: freezeTargetDetails(operation.target),\n precheck: freezeSteps(operation.precheck),\n execute: freezeSteps(operation.execute),\n postcheck: freezeSteps(operation.postcheck),\n ...(operation.meta ? { meta: cloneRecord(operation.meta) } : {}),\n });\n}\n\nfunction freezeOperations<TTargetDetails>(\n operations: readonly MigrationPlanOperation<TTargetDetails>[],\n): readonly MigrationPlanOperation<TTargetDetails>[] {\n if (operations.length === 0) {\n return Object.freeze([]);\n }\n return Object.freeze(operations.map((operation) => freezeOperation(operation)));\n}\n\nfunction normalizePolicy(policy: MigrationPolicy): MigrationPolicy {\n return Object.freeze({\n allowedOperationClasses: Object.freeze([...policy.allowedOperationClasses]),\n });\n}\n\nexport function createMigrationPlan<TTargetDetails = Record<string, never>>(\n options: CreateMigrationPlanOptions<TTargetDetails>,\n): MigrationPlan<TTargetDetails> {\n return Object.freeze({\n targetId: options.targetId,\n policy: normalizePolicy(options.policy),\n contract: Object.freeze({ ...options.contract }),\n operations: freezeOperations(options.operations),\n ...(options.meta ? { meta: cloneRecord(options.meta) } : {}),\n });\n}\n\nexport function plannerSuccess<TTargetDetails>(\n plan: MigrationPlan<TTargetDetails>,\n): PlannerSuccessResult<TTargetDetails> {\n return Object.freeze({\n kind: 'success',\n plan,\n });\n}\n\nexport function plannerFailure(conflicts: readonly PlannerConflict[]): PlannerFailureResult {\n return Object.freeze({\n kind: 'failure' as const,\n conflicts: Object.freeze(\n conflicts.map((conflict) =>\n Object.freeze({\n kind: conflict.kind,\n summary: conflict.summary,\n ...(conflict.why ? { why: conflict.why } : {}),\n ...(conflict.location ? { location: Object.freeze({ ...conflict.location }) } : {}),\n ...(conflict.meta ? { meta: cloneRecord(conflict.meta) } : {}),\n }),\n ),\n ),\n });\n}\n","import type { MigrationPolicy } from './types';\n\n/**\n * Policy used by `db init`: additive-only operations, no widening/destructive steps.\n */\nexport const INIT_ADDITIVE_POLICY: MigrationPolicy = Object.freeze({\n allowedOperationClasses: Object.freeze(['additive'] as const),\n});\n","import { SqlFamilyDescriptor } from '../core/descriptor';\n\nexport type { SqlControlFamilyInstance } from '../core/instance';\nexport {\n createMigrationPlan,\n plannerFailure,\n plannerSuccess,\n} from '../core/migrations/plan-helpers';\nexport { INIT_ADDITIVE_POLICY } from '../core/migrations/policies';\nexport type {\n CreateMigrationPlanOptions,\n MigrationOperationClass,\n MigrationPlan,\n MigrationPlanContractInfo,\n MigrationPlanner,\n MigrationPlannerPlanOptions,\n MigrationPlanOperation,\n MigrationPlanOperationStep,\n MigrationPlanOperationTarget,\n MigrationPolicy,\n PlannerConflict,\n PlannerConflictKind,\n PlannerConflictLocation,\n PlannerFailureResult,\n PlannerResult,\n PlannerSuccessResult,\n SqlControlTargetDescriptor,\n} from '../core/migrations/types';\n\n/**\n * SQL family descriptor for control plane (CLI/config).\n * Provides the SQL family hook and conversion helpers.\n */\nexport default new SqlFamilyDescriptor();\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/descriptor.ts","../../src/core/migrations/plan-helpers.ts","../../src/core/migrations/policies.ts","../../src/exports/control.ts"],"sourcesContent":["import type { ExtensionPackManifest } from '@prisma-next/contract/pack-manifest-types';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n} from '@prisma-next/core-control-plane/types';\nimport { sqlTargetFamilyHook } from '@prisma-next/sql-contract-emitter';\nimport { createSqlFamilyInstance, type SqlControlFamilyInstance } from './instance';\nimport type { SqlControlTargetDescriptor } from './migrations/types';\n\n/**\n * SQL family manifest.\n */\nconst sqlFamilyManifest: ExtensionPackManifest = {\n id: 'sql',\n version: '0.0.1',\n};\n\n/**\n * SQL family descriptor implementation.\n * Provides the SQL family hook and factory method.\n */\nexport class SqlFamilyDescriptor\n implements ControlFamilyDescriptor<'sql', SqlControlFamilyInstance>\n{\n readonly kind = 'family' as const;\n readonly id = 'sql';\n readonly familyId = 'sql' as const;\n readonly manifest = sqlFamilyManifest;\n readonly hook = sqlTargetFamilyHook;\n\n create<TTargetId extends string, TTargetDetails = Record<string, never>>(options: {\n readonly target: SqlControlTargetDescriptor<TTargetId, TTargetDetails>;\n readonly adapter: ControlAdapterDescriptor<'sql', TTargetId>;\n readonly driver: ControlDriverDescriptor<'sql', TTargetId>;\n readonly extensions: readonly ControlExtensionDescriptor<'sql', TTargetId>[];\n }): SqlControlFamilyInstance {\n return createSqlFamilyInstance({\n target: options.target,\n adapter: options.adapter,\n extensions: options.extensions,\n });\n }\n}\n","import type { NotOk, Ok } from '@prisma-next/core-control-plane/result';\nimport { notOk, ok } from '@prisma-next/core-control-plane/result';\nimport type {\n AnyRecord,\n CreateMigrationPlanOptions,\n MigrationPlan,\n MigrationPlanOperation,\n MigrationPlanOperationStep,\n MigrationPlanOperationTarget,\n MigrationRunnerErrorCode,\n MigrationRunnerFailure,\n MigrationRunnerSuccessValue,\n PlannerConflict,\n PlannerFailureResult,\n PlannerSuccessResult,\n} from './types';\n\nconst readOnlyEmptyObject: Record<string, never> = Object.freeze({});\n\nfunction cloneRecord<T extends AnyRecord>(value: T): T {\n if (value === readOnlyEmptyObject) {\n return value;\n }\n return Object.freeze({ ...value }) as T;\n}\n\nfunction freezeSteps(\n steps: readonly MigrationPlanOperationStep[],\n): readonly MigrationPlanOperationStep[] {\n if (steps.length === 0) {\n return Object.freeze([]);\n }\n return Object.freeze(\n steps.map((step) =>\n Object.freeze({\n description: step.description,\n sql: step.sql,\n ...(step.meta ? { meta: cloneRecord(step.meta) } : {}),\n }),\n ),\n );\n}\n\nfunction freezeDetailsValue<T>(value: T): T {\n // Primitives and null/undefined are already immutable, return as-is\n if (value === null || value === undefined) {\n return value;\n }\n if (typeof value !== 'object') {\n return value;\n }\n // Arrays: shallow clone and freeze\n if (Array.isArray(value)) {\n return Object.freeze([...value]) as T;\n }\n // Objects: shallow clone and freeze (matching cloneRecord pattern)\n return Object.freeze({ ...value }) as T;\n}\n\nfunction freezeTargetDetails<TTargetDetails>(\n target: MigrationPlanOperationTarget<TTargetDetails>,\n): MigrationPlanOperationTarget<TTargetDetails> {\n return Object.freeze({\n id: target.id,\n ...(target.details !== undefined ? { details: freezeDetailsValue(target.details) } : {}),\n });\n}\n\nfunction freezeOperation<TTargetDetails>(\n operation: MigrationPlanOperation<TTargetDetails>,\n): MigrationPlanOperation<TTargetDetails> {\n return Object.freeze({\n id: operation.id,\n label: operation.label,\n ...(operation.summary ? { summary: operation.summary } : {}),\n operationClass: operation.operationClass,\n target: freezeTargetDetails(operation.target),\n precheck: freezeSteps(operation.precheck),\n execute: freezeSteps(operation.execute),\n postcheck: freezeSteps(operation.postcheck),\n ...(operation.meta ? { meta: cloneRecord(operation.meta) } : {}),\n });\n}\n\nfunction freezeOperations<TTargetDetails>(\n operations: readonly MigrationPlanOperation<TTargetDetails>[],\n): readonly MigrationPlanOperation<TTargetDetails>[] {\n if (operations.length === 0) {\n return Object.freeze([]);\n }\n return Object.freeze(operations.map((operation) => freezeOperation(operation)));\n}\n\nexport function createMigrationPlan<TTargetDetails = Record<string, never>>(\n options: CreateMigrationPlanOptions<TTargetDetails>,\n): MigrationPlan<TTargetDetails> {\n return Object.freeze({\n targetId: options.targetId,\n ...(options.origin !== undefined\n ? { origin: options.origin ? Object.freeze({ ...options.origin }) : null }\n : {}),\n destination: Object.freeze({ ...options.destination }),\n operations: freezeOperations(options.operations),\n ...(options.meta ? { meta: cloneRecord(options.meta) } : {}),\n });\n}\n\nexport function plannerSuccess<TTargetDetails>(\n plan: MigrationPlan<TTargetDetails>,\n): PlannerSuccessResult<TTargetDetails> {\n return Object.freeze({\n kind: 'success',\n plan,\n });\n}\n\nexport function plannerFailure(conflicts: readonly PlannerConflict[]): PlannerFailureResult {\n return Object.freeze({\n kind: 'failure' as const,\n conflicts: Object.freeze(\n conflicts.map((conflict) =>\n Object.freeze({\n kind: conflict.kind,\n summary: conflict.summary,\n ...(conflict.why ? { why: conflict.why } : {}),\n ...(conflict.location ? { location: Object.freeze({ ...conflict.location }) } : {}),\n ...(conflict.meta ? { meta: cloneRecord(conflict.meta) } : {}),\n }),\n ),\n ),\n });\n}\n\n/**\n * Creates a successful migration runner result.\n */\nexport function runnerSuccess(value: {\n operationsPlanned: number;\n operationsExecuted: number;\n}): Ok<MigrationRunnerSuccessValue> {\n return ok(\n Object.freeze({\n operationsPlanned: value.operationsPlanned,\n operationsExecuted: value.operationsExecuted,\n }),\n );\n}\n\n/**\n * Creates a failed migration runner result.\n */\nexport function runnerFailure(\n code: MigrationRunnerErrorCode,\n summary: string,\n options?: { why?: string; meta?: AnyRecord },\n): NotOk<MigrationRunnerFailure> {\n const failure: MigrationRunnerFailure = Object.freeze({\n code,\n summary,\n ...(options?.why ? { why: options.why } : {}),\n ...(options?.meta ? { meta: cloneRecord(options.meta) } : {}),\n });\n return notOk(failure);\n}\n","import type { MigrationOperationPolicy } from './types';\n\n/**\n * Policy used by `db init`: additive-only operations, no widening/destructive steps.\n */\nexport const INIT_ADDITIVE_POLICY: MigrationOperationPolicy = Object.freeze({\n allowedOperationClasses: Object.freeze(['additive'] as const),\n});\n","import { SqlFamilyDescriptor } from '../core/descriptor';\n\nexport type { SchemaVerifyOptions, SqlControlFamilyInstance } from '../core/instance';\nexport {\n createMigrationPlan,\n plannerFailure,\n plannerSuccess,\n runnerFailure,\n runnerSuccess,\n} from '../core/migrations/plan-helpers';\nexport { INIT_ADDITIVE_POLICY } from '../core/migrations/policies';\nexport type {\n CreateMigrationPlanOptions,\n MigrationOperationClass,\n MigrationOperationPolicy,\n MigrationPlan,\n MigrationPlanContractInfo,\n MigrationPlanner,\n MigrationPlannerPlanOptions,\n MigrationPlanOperation,\n MigrationPlanOperationStep,\n MigrationPlanOperationTarget,\n MigrationRunner,\n MigrationRunnerErrorCode,\n MigrationRunnerExecuteCallbacks,\n MigrationRunnerExecuteOptions,\n MigrationRunnerFailure,\n MigrationRunnerResult,\n MigrationRunnerSuccessValue,\n PlannerConflict,\n PlannerConflictKind,\n PlannerConflictLocation,\n PlannerFailureResult,\n PlannerResult,\n PlannerSuccessResult,\n SqlControlTargetDescriptor,\n} from '../core/migrations/types';\n\n/**\n * SQL family descriptor for control plane (CLI/config).\n * Provides the SQL family hook and conversion helpers.\n */\nexport default new SqlFamilyDescriptor();\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/family-sql",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "SQL family descriptor for Prisma Next",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"arktype": "^2.0.0",
|
|
9
|
-
"@prisma-next/cli": "0.1.0-dev.
|
|
10
|
-
"@prisma-next/contract": "0.1.0-dev.
|
|
11
|
-
"@prisma-next/core-control-plane": "0.1.0-dev.
|
|
12
|
-
"@prisma-next/core-execution-plane": "0.1.0-dev.
|
|
13
|
-
"@prisma-next/operations": "0.1.0-dev.
|
|
14
|
-
"@prisma-next/runtime-executor": "0.1.0-dev.
|
|
15
|
-
"@prisma-next/sql-contract-emitter": "0.1.0-dev.
|
|
16
|
-
"@prisma-next/sql-contract-ts": "0.1.0-dev.
|
|
17
|
-
"@prisma-next/sql-contract": "0.1.0-dev.
|
|
18
|
-
"@prisma-next/sql-operations": "0.1.0-dev.
|
|
19
|
-
"@prisma-next/sql-relational-core": "0.1.0-dev.
|
|
20
|
-
"@prisma-next/sql-runtime": "0.1.0-dev.
|
|
21
|
-
"@prisma-next/sql-schema-ir": "0.1.0-dev.
|
|
9
|
+
"@prisma-next/cli": "0.1.0-dev.15",
|
|
10
|
+
"@prisma-next/contract": "0.1.0-dev.15",
|
|
11
|
+
"@prisma-next/core-control-plane": "0.1.0-dev.15",
|
|
12
|
+
"@prisma-next/core-execution-plane": "0.1.0-dev.15",
|
|
13
|
+
"@prisma-next/operations": "0.1.0-dev.15",
|
|
14
|
+
"@prisma-next/runtime-executor": "0.1.0-dev.15",
|
|
15
|
+
"@prisma-next/sql-contract-emitter": "0.1.0-dev.15",
|
|
16
|
+
"@prisma-next/sql-contract-ts": "0.1.0-dev.15",
|
|
17
|
+
"@prisma-next/sql-contract": "0.1.0-dev.15",
|
|
18
|
+
"@prisma-next/sql-operations": "0.1.0-dev.15",
|
|
19
|
+
"@prisma-next/sql-relational-core": "0.1.0-dev.15",
|
|
20
|
+
"@prisma-next/sql-runtime": "0.1.0-dev.15",
|
|
21
|
+
"@prisma-next/sql-schema-ir": "0.1.0-dev.15"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"tsup": "^8.3.0",
|
|
25
25
|
"typescript": "^5.9.3",
|
|
26
26
|
"vite-tsconfig-paths": "^5.1.4",
|
|
27
27
|
"vitest": "^2.1.1",
|
|
28
|
-
"@prisma-next/driver-postgres": "0.1.0-dev.
|
|
28
|
+
"@prisma-next/driver-postgres": "0.1.0-dev.15",
|
|
29
29
|
"@prisma-next/test-utils": "0.0.1"
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/assembly.ts","../../src/core/instance.ts"],"sourcesContent":["import type {\n ExtensionPackManifest,\n OperationManifest,\n} from '@prisma-next/contract/pack-manifest-types';\nimport type { TypesImportSpec } from '@prisma-next/contract/types';\nimport type {\n ControlAdapterDescriptor,\n ControlExtensionDescriptor,\n ControlTargetDescriptor,\n} from '@prisma-next/core-control-plane/types';\nimport type { OperationRegistry, OperationSignature } from '@prisma-next/operations';\nimport { createOperationRegistry } from '@prisma-next/operations';\n// Import private function from same package (test utility needs it)\nimport { convertOperationManifest } from './instance';\n\n/**\n * Assembles an operation registry from descriptors (adapter, target, extensions).\n * Loops over descriptors, extracts operations, converts them using the provided\n * conversion function, and registers them in a new registry.\n */\nexport function assembleOperationRegistry(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n convertOperationManifest: (manifest: OperationManifest) => OperationSignature,\n): OperationRegistry {\n const registry = createOperationRegistry();\n\n for (const descriptor of descriptors) {\n const operations = descriptor.manifest.operations ?? [];\n for (const operationManifest of operations as ReadonlyArray<OperationManifest>) {\n const signature = convertOperationManifest(operationManifest);\n registry.register(signature);\n }\n }\n\n return registry;\n}\n\n/**\n * Extracts codec type imports from descriptors for contract.d.ts generation.\n */\nexport function extractCodecTypeImports(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const codecTypes = descriptor.manifest.types?.codecTypes;\n if (codecTypes?.import) {\n imports.push(codecTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Extracts operation type imports from descriptors for contract.d.ts generation.\n */\nexport function extractOperationTypeImports(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const operationTypes = descriptor.manifest.types?.operationTypes;\n if (operationTypes?.import) {\n imports.push(operationTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Extracts extension IDs from descriptors in deterministic order:\n * [adapter.id, target.id, ...extensions.map(e => e.id)]\n * Deduplicates while preserving stable order.\n */\nexport function extractExtensionIds(\n adapter: ControlAdapterDescriptor<'sql', string>,\n target: ControlTargetDescriptor<'sql', string>,\n extensions: ReadonlyArray<ControlExtensionDescriptor<'sql', string>>,\n): ReadonlyArray<string> {\n const ids: string[] = [];\n const seen = new Set<string>();\n\n // Add adapter first\n if (!seen.has(adapter.id)) {\n ids.push(adapter.id);\n seen.add(adapter.id);\n }\n\n // Add target second\n if (!seen.has(target.id)) {\n ids.push(target.id);\n seen.add(target.id);\n }\n\n // Add extensions in order\n for (const ext of extensions) {\n if (!seen.has(ext.id)) {\n ids.push(ext.id);\n seen.add(ext.id);\n }\n }\n\n return ids;\n}\n\n/**\n * Extracts codec type imports from extension packs for contract.d.ts generation.\n * Pack-based version for use in tests.\n */\nexport function extractCodecTypeImportsFromPacks(\n packs: ReadonlyArray<{ readonly manifest: ExtensionPackManifest }>,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const pack of packs) {\n const codecTypes = pack.manifest.types?.codecTypes;\n if (codecTypes?.import) {\n imports.push(codecTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Extracts operation type imports from extension packs for contract.d.ts generation.\n * Pack-based version for use in tests.\n */\nexport function extractOperationTypeImportsFromPacks(\n packs: ReadonlyArray<{ readonly manifest: ExtensionPackManifest }>,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const pack of packs) {\n const operationTypes = pack.manifest.types?.operationTypes;\n if (operationTypes?.import) {\n imports.push(operationTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Assembles an operation registry from extension packs.\n * Pack-based version for use in tests.\n */\nexport function assembleOperationRegistryFromPacks(\n packs: ReadonlyArray<{ readonly manifest: ExtensionPackManifest }>,\n): OperationRegistry {\n const registry = createOperationRegistry();\n\n for (const pack of packs) {\n const operations = pack.manifest.operations ?? [];\n for (const operationManifest of operations as ReadonlyArray<OperationManifest>) {\n const signature = convertOperationManifest(operationManifest);\n registry.register(signature);\n }\n }\n\n return registry;\n}\n\n/**\n * Extracts extension IDs from packs.\n * Pack-based version for use in tests.\n */\nexport function extractExtensionIdsFromPacks(\n packs: ReadonlyArray<{ readonly manifest: ExtensionPackManifest }>,\n): ReadonlyArray<string> {\n return packs.map((pack) => pack.manifest.id);\n}\n","import type { ContractIR } from '@prisma-next/contract/ir';\nimport type { OperationManifest } from '@prisma-next/contract/pack-manifest-types';\nimport type { ContractMarkerRecord, TypesImportSpec } from '@prisma-next/contract/types';\nimport { emit } from '@prisma-next/core-control-plane/emission';\nimport type { CoreSchemaView, SchemaTreeNode } from '@prisma-next/core-control-plane/schema-view';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyInstance,\n ControlTargetDescriptor,\n EmitContractResult,\n SchemaIssue,\n SchemaVerificationNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/core-control-plane/types';\nimport type { OperationRegistry } from '@prisma-next/operations';\nimport type {\n ForeignKey,\n Index,\n PrimaryKey,\n SqlContract,\n SqlStorage,\n UniqueConstraint,\n} from '@prisma-next/sql-contract/types';\nimport { sqlTargetFamilyHook } from '@prisma-next/sql-contract-emitter';\nimport { validateContract } from '@prisma-next/sql-contract-ts/contract';\nimport type { SqlOperationSignature } from '@prisma-next/sql-operations';\nimport {\n ensureSchemaStatement,\n ensureTableStatement,\n writeContractMarker,\n} from '@prisma-next/sql-runtime';\nimport type {\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlSchemaIR,\n SqlTableIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\nimport {\n assembleOperationRegistry,\n extractCodecTypeImports,\n extractExtensionIds,\n extractOperationTypeImports,\n} from './assembly';\nimport type { SqlControlAdapter } from './control-adapter';\nimport type { SqlControlTargetDescriptor } from './migrations/types';\nimport { collectSupportedCodecTypeIds, readMarker } from './verify';\n\n/**\n * Converts an OperationManifest (from ExtensionPackManifest) to a SqlOperationSignature.\n * This is SQL-family-specific conversion logic.\n * Used internally by instance creation and test utilities in the same package.\n */\nexport function convertOperationManifest(manifest: OperationManifest): SqlOperationSignature {\n return {\n forTypeId: manifest.for,\n method: manifest.method,\n args: manifest.args.map((arg: OperationManifest['args'][number]) => {\n if (arg.kind === 'typeId') {\n if (!arg.type) {\n throw new Error('typeId arg must have type property');\n }\n return { kind: 'typeId' as const, type: arg.type };\n }\n if (arg.kind === 'param') {\n return { kind: 'param' as const };\n }\n if (arg.kind === 'literal') {\n return { kind: 'literal' as const };\n }\n throw new Error(`Invalid arg kind: ${(arg as { kind: unknown }).kind}`);\n }),\n returns: (() => {\n if (manifest.returns.kind === 'typeId') {\n return { kind: 'typeId' as const, type: manifest.returns.type };\n }\n if (manifest.returns.kind === 'builtin') {\n return {\n kind: 'builtin' as const,\n type: manifest.returns.type as 'number' | 'boolean' | 'string',\n };\n }\n throw new Error(`Invalid return kind: ${(manifest.returns as { kind: unknown }).kind}`);\n })(),\n lowering: {\n targetFamily: 'sql',\n strategy: manifest.lowering.strategy,\n template: manifest.lowering.template,\n },\n ...(manifest.capabilities ? { capabilities: manifest.capabilities } : {}),\n };\n}\n\n/**\n * Extracts codec type IDs used in contract storage tables.\n * Uses type guards to safely access SQL-specific structure without importing SQL types.\n */\nfunction extractCodecTypeIdsFromContract(contract: unknown): readonly string[] {\n const typeIds = new Set<string>();\n\n // Type guard for SQL contract structure\n if (\n typeof contract === 'object' &&\n contract !== null &&\n 'storage' in contract &&\n typeof contract.storage === 'object' &&\n contract.storage !== null &&\n 'tables' in contract.storage\n ) {\n const storage = contract.storage as { tables?: Record<string, unknown> };\n if (storage.tables && typeof storage.tables === 'object') {\n for (const table of Object.values(storage.tables)) {\n if (\n typeof table === 'object' &&\n table !== null &&\n 'columns' in table &&\n typeof table.columns === 'object' &&\n table.columns !== null\n ) {\n const columns = table.columns as Record<string, { codecId: string } | undefined>;\n for (const column of Object.values(columns)) {\n if (\n column &&\n typeof column === 'object' &&\n 'codecId' in column &&\n typeof column.codecId === 'string'\n ) {\n typeIds.add(column.codecId);\n }\n }\n }\n }\n }\n }\n\n return Array.from(typeIds).sort();\n}\n\n/**\n * Compares two arrays of strings for equality (order-sensitive).\n */\nfunction 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 * Compares primary keys and adds issues if mismatch.\n * Returns 'pass' or 'fail'.\n */\nfunction comparePrimaryKey(\n contractPK: PrimaryKey,\n schemaPK: PrimaryKey | undefined,\n tableName: string,\n issues: SchemaIssue[],\n): 'pass' | 'fail' {\n if (!schemaPK) {\n issues.push({\n kind: 'primary_key_mismatch',\n table: tableName,\n expected: contractPK.columns.join(', '),\n message: `Table \"${tableName}\" is missing primary key`,\n });\n return 'fail';\n }\n\n if (!arraysEqual(contractPK.columns, schemaPK.columns)) {\n issues.push({\n kind: 'primary_key_mismatch',\n table: tableName,\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 return 'fail';\n }\n\n // Compare name if both are modeled\n if (contractPK.name && schemaPK.name && contractPK.name !== schemaPK.name) {\n issues.push({\n kind: 'primary_key_mismatch',\n table: tableName,\n indexOrConstraint: contractPK.name,\n expected: contractPK.name,\n actual: schemaPK.name,\n message: `Table \"${tableName}\" has primary key name mismatch: expected \"${contractPK.name}\", got \"${schemaPK.name}\"`,\n });\n return 'fail';\n }\n\n return 'pass';\n}\n\n/**\n * Compares foreign keys and returns verification nodes.\n */\nfunction compareForeignKeys(\n contractFKs: readonly ForeignKey[],\n schemaFKs: readonly SqlForeignKeyIR[],\n tableName: string,\n tablePath: string,\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.columns.join(',')}]`;\n const matchingFK = schemaFKs.find((fk) => {\n return (\n arraysEqual(fk.columns, contractFK.columns) &&\n fk.referencedTable === contractFK.references.table &&\n arraysEqual(fk.referencedColumns, contractFK.references.columns)\n );\n });\n\n if (!matchingFK) {\n issues.push({\n kind: 'foreign_key_mismatch',\n table: tableName,\n expected: `${contractFK.columns.join(', ')} -> ${contractFK.references.table}(${contractFK.references.columns.join(', ')})`,\n message: `Table \"${tableName}\" is missing foreign key: ${contractFK.columns.join(', ')} -> ${contractFK.references.table}(${contractFK.references.columns.join(', ')})`,\n });\n nodes.push({\n status: 'fail',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.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 } else {\n // Compare name if both are modeled\n if (contractFK.name && matchingFK.name && contractFK.name !== matchingFK.name) {\n issues.push({\n kind: 'foreign_key_mismatch',\n table: tableName,\n indexOrConstraint: contractFK.name,\n expected: contractFK.name,\n actual: matchingFK.name,\n message: `Table \"${tableName}\" has foreign key name mismatch: expected \"${contractFK.name}\", got \"${matchingFK.name}\"`,\n });\n nodes.push({\n status: 'fail',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.columns.join(', ')})`,\n contractPath: fkPath,\n code: 'foreign_key_mismatch',\n message: 'Foreign key name mismatch',\n expected: contractFK.name,\n actual: matchingFK.name,\n children: [],\n });\n } else {\n nodes.push({\n status: 'pass',\n kind: 'foreignKey',\n name: `foreignKey(${contractFK.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 return (\n arraysEqual(fk.columns, schemaFK.columns) &&\n fk.references.table === schemaFK.referencedTable &&\n arraysEqual(fk.references.columns, schemaFK.referencedColumns)\n );\n });\n\n if (!matchingFK) {\n issues.push({\n kind: 'foreign_key_mismatch',\n table: tableName,\n message: `Extra foreign key found in database (not in contract): ${schemaFK.columns.join(', ')} -> ${schemaFK.referencedTable}(${schemaFK.referencedColumns.join(', ')})`,\n });\n nodes.push({\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 }\n }\n }\n\n return nodes;\n}\n\n/**\n * Compares unique constraints and returns verification nodes.\n */\nfunction compareUniqueConstraints(\n contractUniques: readonly UniqueConstraint[],\n schemaUniques: readonly SqlUniqueIR[],\n tableName: string,\n tablePath: string,\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 const matchingUnique = schemaUniques.find((u) =>\n arraysEqual(u.columns, contractUnique.columns),\n );\n\n if (!matchingUnique) {\n issues.push({\n kind: 'unique_constraint_mismatch',\n table: tableName,\n expected: contractUnique.columns.join(', '),\n message: `Table \"${tableName}\" is missing unique constraint: ${contractUnique.columns.join(', ')}`,\n });\n nodes.push({\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 } else {\n // Compare name if both are modeled\n if (\n contractUnique.name &&\n matchingUnique.name &&\n contractUnique.name !== matchingUnique.name\n ) {\n issues.push({\n kind: 'unique_constraint_mismatch',\n table: tableName,\n indexOrConstraint: contractUnique.name,\n expected: contractUnique.name,\n actual: matchingUnique.name,\n message: `Table \"${tableName}\" has unique constraint name mismatch: expected \"${contractUnique.name}\", got \"${matchingUnique.name}\"`,\n });\n nodes.push({\n status: 'fail',\n kind: 'unique',\n name: `unique(${contractUnique.columns.join(', ')})`,\n contractPath: uniquePath,\n code: 'unique_constraint_mismatch',\n message: 'Unique constraint name mismatch',\n expected: contractUnique.name,\n actual: matchingUnique.name,\n children: [],\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\n // Check for extra uniques in strict mode\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 issues.push({\n kind: 'unique_constraint_mismatch',\n table: tableName,\n message: `Extra unique constraint found in database (not in contract): ${schemaUnique.columns.join(', ')}`,\n });\n nodes.push({\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 }\n }\n }\n\n return nodes;\n}\n\n/**\n * Compares indexes and returns verification nodes.\n */\nfunction compareIndexes(\n contractIndexes: readonly Index[],\n schemaIndexes: readonly SqlIndexIR[],\n tableName: string,\n tablePath: string,\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 const matchingIndex = schemaIndexes.find(\n (idx) => arraysEqual(idx.columns, contractIndex.columns) && idx.unique === false,\n );\n\n if (!matchingIndex) {\n issues.push({\n kind: 'index_mismatch',\n table: tableName,\n expected: contractIndex.columns.join(', '),\n message: `Table \"${tableName}\" is missing index: ${contractIndex.columns.join(', ')}`,\n });\n nodes.push({\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 } else {\n // Compare name if both are modeled\n if (contractIndex.name && matchingIndex.name && contractIndex.name !== matchingIndex.name) {\n issues.push({\n kind: 'index_mismatch',\n table: tableName,\n indexOrConstraint: contractIndex.name,\n expected: contractIndex.name,\n actual: matchingIndex.name,\n message: `Table \"${tableName}\" has index name mismatch: expected \"${contractIndex.name}\", got \"${matchingIndex.name}\"`,\n });\n nodes.push({\n status: 'fail',\n kind: 'index',\n name: `index(${contractIndex.columns.join(', ')})`,\n contractPath: indexPath,\n code: 'index_mismatch',\n message: 'Index name mismatch',\n expected: contractIndex.name,\n actual: matchingIndex.name,\n children: [],\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\n // Check for extra indexes in strict mode\n if (strict) {\n for (const schemaIndex of schemaIndexes) {\n // Skip unique indexes (they're handled as unique constraints)\n if (schemaIndex.unique) {\n continue;\n }\n\n const matchingIndex = contractIndexes.find((idx) =>\n arraysEqual(idx.columns, schemaIndex.columns),\n );\n\n if (!matchingIndex) {\n issues.push({\n kind: 'index_mismatch',\n table: tableName,\n message: `Extra index found in database (not in contract): ${schemaIndex.columns.join(', ')}`,\n });\n nodes.push({\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 }\n }\n }\n\n return nodes;\n}\n\n/**\n * Compares extensions and returns verification nodes.\n * Extracts extension names from contract.extensions (keys) and compares with schemaIR.extensions.\n * Filters out the target name (e.g., 'postgres') as it's not an extension.\n */\nfunction compareExtensions(\n contractExtensions: Record<string, unknown> | undefined,\n schemaExtensions: readonly string[],\n contractTarget: string,\n issues: SchemaIssue[],\n _strict: boolean,\n): SchemaVerificationNode[] {\n const nodes: SchemaVerificationNode[] = [];\n\n if (!contractExtensions) {\n return nodes;\n }\n\n // Extract extension names from contract (keys of extensions object)\n // Filter out the target name - it's not an extension (e.g., 'postgres' is the target, not an extension)\n const contractExtensionNames = Object.keys(contractExtensions).filter(\n (name) => name !== contractTarget,\n );\n\n // Check each contract extension exists in schema\n // Extension names in contract may differ from database extension names\n // (e.g., contract has 'pgvector' but database has 'vector')\n // We need to match more flexibly - try exact match, then check if either contains the other\n for (const extName of contractExtensionNames) {\n const extPath = `extensions.${extName}`;\n // Normalize extension names for comparison (remove common prefixes like 'pg')\n const normalizedExtName = extName.toLowerCase().replace(/^pg/, '');\n const matchingExt = schemaExtensions.find((e) => {\n const normalizedE = e.toLowerCase();\n // Exact match\n if (normalizedE === normalizedExtName || normalizedE === extName.toLowerCase()) {\n return true;\n }\n // Check if one contains the other (e.g., 'pgvector' contains 'vector', 'vector' is in 'pgvector')\n if (normalizedE.includes(normalizedExtName) || normalizedExtName.includes(normalizedE)) {\n return true;\n }\n return false;\n });\n\n // Map extension names to descriptive labels\n const extensionLabels: Record<string, string> = {\n pg: 'database is postgres',\n pgvector: 'vector extension is enabled',\n vector: 'vector extension is enabled',\n };\n const extensionLabel = extensionLabels[extName] ?? `extension \"${extName}\" is enabled`;\n\n if (!matchingExt) {\n issues.push({\n kind: 'extension_missing',\n table: '',\n message: `Extension \"${extName}\" is missing from database`,\n });\n nodes.push({\n status: 'fail',\n kind: 'extension',\n name: extensionLabel,\n contractPath: extPath,\n code: 'extension_missing',\n message: `Extension \"${extName}\" is missing`,\n expected: undefined,\n actual: undefined,\n children: [],\n });\n } else {\n nodes.push({\n status: 'pass',\n kind: 'extension',\n name: extensionLabel,\n contractPath: extPath,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n\n // In strict mode, we don't check for extra extensions (they're allowed)\n // Extensions are additive - having extra extensions doesn't break the contract\n\n return nodes;\n}\n\n/**\n * Computes counts of pass/warn/fail nodes by traversing the tree.\n */\nfunction 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 * Creates a VerifyDatabaseResult object with common structure.\n */\nfunction createVerifyResult(options: {\n ok: boolean;\n code?: string;\n summary: string;\n contractCoreHash: string;\n contractProfileHash?: string;\n marker?: ContractMarkerRecord;\n expectedTargetId: string;\n actualTargetId?: string;\n missingCodecs?: readonly string[];\n codecCoverageSkipped?: boolean;\n configPath?: string;\n contractPath: string;\n totalTime: number;\n}): VerifyDatabaseResult {\n const contract: { coreHash: string; profileHash?: string } = {\n coreHash: options.contractCoreHash,\n };\n if (options.contractProfileHash) {\n contract.profileHash = options.contractProfileHash;\n }\n\n const target: { expected: string; actual?: string } = {\n expected: options.expectedTargetId,\n };\n if (options.actualTargetId) {\n target.actual = options.actualTargetId;\n }\n\n const meta: { contractPath: string; configPath?: string } = {\n contractPath: options.contractPath,\n };\n if (options.configPath) {\n meta.configPath = options.configPath;\n }\n\n const result: VerifyDatabaseResult = {\n ok: options.ok,\n summary: options.summary,\n contract,\n target,\n meta,\n timings: {\n total: options.totalTime,\n },\n };\n\n if (options.code) {\n (result as { code?: string }).code = options.code;\n }\n\n if (options.marker) {\n (result as { marker?: { coreHash: string; profileHash: string } }).marker = {\n coreHash: options.marker.coreHash,\n profileHash: options.marker.profileHash,\n };\n }\n\n if (options.missingCodecs) {\n (result as { missingCodecs?: readonly string[] }).missingCodecs = options.missingCodecs;\n }\n\n if (options.codecCoverageSkipped) {\n (result as { codecCoverageSkipped?: boolean }).codecCoverageSkipped =\n options.codecCoverageSkipped;\n }\n\n return result;\n}\n\n/**\n * Type metadata for SQL storage types.\n * Maps contract storage type IDs to native database types.\n */\ninterface SqlTypeMetadata {\n readonly typeId: string;\n readonly familyId: 'sql';\n readonly targetId: string;\n readonly nativeType?: string;\n}\n\n/**\n * Registry mapping type IDs to their metadata.\n * Keyed by contract storage type ID (e.g., 'pg/int4@1').\n */\ntype SqlTypeMetadataRegistry = Map<string, SqlTypeMetadata>;\n\n/**\n * State fields for SQL family instance that hold assembly data.\n */\ninterface SqlFamilyInstanceState {\n readonly operationRegistry: OperationRegistry;\n readonly codecTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly operationTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly extensionIds: ReadonlyArray<string>;\n readonly typeMetadataRegistry: SqlTypeMetadataRegistry;\n}\n\n/**\n * SQL control family instance interface.\n * Extends ControlFamilyInstance with SQL-specific domain actions.\n */\nexport interface SqlControlFamilyInstance\n extends ControlFamilyInstance<'sql'>,\n SqlFamilyInstanceState {\n /**\n * Validates a contract JSON and returns a validated ContractIR (without mappings).\n * Mappings are runtime-only and should not be part of ContractIR.\n */\n validateContractIR(contractJson: unknown): unknown;\n\n /**\n * Verifies the database marker against the contract.\n * Compares target, coreHash, and profileHash.\n */\n verify(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult>;\n\n /**\n * Verifies the database schema against the contract.\n * Compares contract requirements against live database schema.\n */\n schemaVerify(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly strict: boolean;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseSchemaResult>;\n\n /**\n * Signs the database with the contract marker.\n * Writes or updates the contract marker if schema verification passes.\n * This operation is idempotent - if the marker already matches, no changes are made.\n */\n sign(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult>;\n\n /**\n * Introspects the database schema and returns a family-specific schema IR.\n *\n * This is a read-only operation that returns a snapshot of the live database schema.\n * The method is family-owned and delegates to target/adapter-specific introspectors\n * to perform the actual schema introspection.\n *\n * @param options - Introspection options\n * @param options.driver - Control plane driver for database connection\n * @param options.contractIR - Optional contract IR for contract-guided introspection.\n * When provided, families may use it for filtering, optimization, or validation\n * during introspection. The contract IR does not change the meaning of \"what exists\"\n * in the database - it only guides how introspection is performed.\n * @returns Promise resolving to the family-specific Schema IR (e.g., `SqlSchemaIR` for SQL).\n * The IR represents the complete schema snapshot at the time of introspection.\n */\n introspect(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR?: unknown;\n }): Promise<SqlSchemaIR>;\n\n /**\n * Projects a SQL Schema IR into a core schema view for CLI visualization.\n * Converts SqlSchemaIR (tables, columns, indexes, extensions) into a tree structure.\n */\n toSchemaView(schema: SqlSchemaIR): CoreSchemaView;\n\n /**\n * Emits contract JSON and DTS as strings.\n * Uses the instance's preassembled state (operation registry, type imports, extension IDs).\n * Handles stripping mappings and validation internally.\n */\n emitContract(options: { readonly contractIR: ContractIR | unknown }): Promise<EmitContractResult>;\n}\n\n/**\n * SQL family instance type.\n * Maintains backward compatibility with FamilyInstance while implementing SqlControlFamilyInstance.\n */\nexport type SqlFamilyInstance = SqlControlFamilyInstance;\n\ninterface CreateSqlFamilyInstanceOptions<\n TTargetId extends string = string,\n TTargetDetails = Record<string, never>,\n> {\n readonly target: SqlControlTargetDescriptor<TTargetId, TTargetDetails>;\n readonly adapter: ControlAdapterDescriptor<'sql', string>;\n readonly extensions: readonly ControlExtensionDescriptor<'sql', string>[];\n}\n\n/**\n * Builds a SQL type metadata registry from extension pack manifests.\n * Collects type metadata from target, adapter, and extension pack manifests.\n *\n * @param options - Descriptors for target, adapter, and extensions\n * @returns Registry mapping type IDs to their metadata, filtered by targetId\n */\nfunction buildSqlTypeMetadataRegistry(options: {\n readonly target: ControlTargetDescriptor<'sql', string>;\n readonly adapter: ControlAdapterDescriptor<'sql', string>;\n readonly extensions: readonly ControlExtensionDescriptor<'sql', string>[];\n}): SqlTypeMetadataRegistry {\n const { target, adapter, extensions } = options;\n const registry = new Map<string, SqlTypeMetadata>();\n\n // Get targetId from adapter (they should match)\n const targetId = adapter.targetId;\n\n // Collect descriptors to iterate over\n const descriptors = [target, adapter, ...extensions];\n\n // Iterate over each descriptor's manifest\n for (const descriptor of descriptors) {\n const manifest = descriptor.manifest;\n const storageTypes = manifest.types?.storage;\n\n if (!storageTypes) {\n continue;\n }\n\n // Filter for SQL family and matching targetId\n for (const storageType of storageTypes) {\n if (storageType.familyId === 'sql' && storageType.targetId === targetId) {\n // Use existing entry if present, otherwise create new one\n // Later entries (extensions) can override earlier ones (adapter/target)\n registry.set(storageType.typeId, {\n typeId: storageType.typeId,\n familyId: 'sql',\n targetId: storageType.targetId,\n ...(storageType.nativeType !== undefined ? { nativeType: storageType.nativeType } : {}),\n });\n }\n }\n }\n\n return registry;\n}\n\n/**\n * Creates a SQL family instance for control-plane operations.\n */\nexport function createSqlFamilyInstance<\n TTargetId extends string = string,\n TTargetDetails = Record<string, never>,\n>(options: CreateSqlFamilyInstanceOptions<TTargetId, TTargetDetails>): SqlFamilyInstance {\n const { target, adapter, extensions } = options;\n\n // Build descriptors array for assembly\n // Assembly functions only use manifest and id, so we can pass Control*Descriptor types directly\n const descriptors = [target, adapter, ...extensions];\n\n // Assemble operation registry, type imports, and extension IDs\n const operationRegistry = assembleOperationRegistry(descriptors, convertOperationManifest);\n const codecTypeImports = extractCodecTypeImports(descriptors);\n const operationTypeImports = extractOperationTypeImports(descriptors);\n const extensionIds = extractExtensionIds(adapter, target, extensions);\n\n // Build type metadata registry from manifests\n const typeMetadataRegistry = buildSqlTypeMetadataRegistry({ target, adapter, extensions });\n\n /**\n * Strips mappings from a contract (mappings are runtime-only).\n */\n function stripMappings(contract: unknown): unknown {\n // Type guard to check if contract has mappings\n if (typeof contract === 'object' && contract !== null && 'mappings' in contract) {\n const { mappings: _mappings, ...contractIR } = contract as {\n mappings?: unknown;\n [key: string]: unknown;\n };\n return contractIR;\n }\n return contract;\n }\n\n return {\n familyId: 'sql',\n operationRegistry,\n codecTypeImports,\n operationTypeImports,\n extensionIds,\n typeMetadataRegistry,\n\n validateContractIR(contractJson: unknown): unknown {\n // Validate the contract (this normalizes and validates structure/logic)\n const validated = validateContract<SqlContract<SqlStorage>>(contractJson);\n // Strip mappings before returning ContractIR (mappings are runtime-only)\n const { mappings: _mappings, ...contractIR } = validated;\n return contractIR;\n },\n\n async verify(verifyOptions: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult> {\n const { driver, contractIR, expectedTargetId, contractPath, configPath } = verifyOptions;\n const startTime = Date.now();\n\n // Type guard to ensure contract has required properties\n if (\n typeof contractIR !== 'object' ||\n contractIR === null ||\n !('coreHash' in contractIR) ||\n !('target' in contractIR) ||\n typeof contractIR.coreHash !== 'string' ||\n typeof contractIR.target !== 'string'\n ) {\n throw new Error('Contract is missing required fields: coreHash or target');\n }\n\n // Extract contract hashes and target\n const contractCoreHash = contractIR.coreHash;\n const contractProfileHash =\n 'profileHash' in contractIR && typeof contractIR.profileHash === 'string'\n ? contractIR.profileHash\n : undefined;\n const contractTarget = contractIR.target;\n\n // Read marker from database\n const marker = await readMarker(driver);\n\n // Compute codec coverage (optional)\n let missingCodecs: readonly string[] | undefined;\n let codecCoverageSkipped = false;\n const supportedTypeIds = collectSupportedCodecTypeIds<'sql', string>([\n adapter,\n target,\n ...extensions,\n ]);\n if (supportedTypeIds.length === 0) {\n // Helper is present but returns empty (MVP behavior)\n // Coverage check is skipped - missingCodecs remains undefined\n codecCoverageSkipped = true;\n } else {\n const supportedSet = new Set(supportedTypeIds);\n const usedTypeIds = extractCodecTypeIdsFromContract(contractIR);\n const missing = usedTypeIds.filter((id) => !supportedSet.has(id));\n if (missing.length > 0) {\n missingCodecs = missing;\n }\n }\n\n // Check marker presence\n if (!marker) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: 'PN-RTM-3001',\n summary: 'Marker missing',\n contractCoreHash,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n // Compare target\n if (contractTarget !== expectedTargetId) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: 'PN-RTM-3003',\n summary: 'Target mismatch',\n contractCoreHash,\n marker,\n expectedTargetId,\n actualTargetId: contractTarget,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n // Compare hashes\n if (marker.coreHash !== contractCoreHash) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: 'PN-RTM-3002',\n summary: 'Hash mismatch',\n contractCoreHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n // Compare profile hash if present\n if (contractProfileHash && marker.profileHash !== contractProfileHash) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: 'PN-RTM-3002',\n summary: 'Hash mismatch',\n contractCoreHash,\n contractProfileHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n // Success - all checks passed\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: true,\n summary: 'Database matches contract',\n contractCoreHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n },\n\n async schemaVerify(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly strict: boolean;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseSchemaResult> {\n const { driver, contractIR, strict, contractPath, configPath } = options;\n const startTime = Date.now();\n\n // Validate contractIR as SqlContract<SqlStorage>\n const contract = validateContract<SqlContract<SqlStorage>>(contractIR);\n\n // Extract contract hashes and target\n const contractCoreHash = contract.coreHash;\n const contractProfileHash =\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : undefined;\n const contractTarget = contract.target;\n\n // Introspect live schema\n const controlAdapter = adapter.create() as SqlControlAdapter;\n const schemaIR = await controlAdapter.introspect(\n driver as ControlDriverInstance<string>,\n contractIR,\n );\n\n // Compare contract vs schema IR\n const issues: SchemaIssue[] = [];\n const rootChildren: SchemaVerificationNode[] = [];\n\n // Compare tables\n const contractTables = contract.storage.tables;\n const schemaTables = schemaIR.tables;\n\n for (const [tableName, contractTable] of Object.entries(contractTables)) {\n const schemaTable = schemaTables[tableName];\n const tablePath = `storage.tables.${tableName}`;\n\n if (!schemaTable) {\n // Missing table\n issues.push({\n kind: 'missing_table',\n table: tableName,\n message: `Table \"${tableName}\" is missing from database`,\n });\n rootChildren.push({\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 continue;\n }\n\n // Table exists - compare columns, constraints, etc.\n const tableChildren: SchemaVerificationNode[] = [];\n const columnNodes: SchemaVerificationNode[] = [];\n\n // Compare columns\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 // Missing column\n issues.push({\n kind: 'missing_column',\n table: tableName,\n column: columnName,\n message: `Column \"${tableName}\".\"${columnName}\" is missing from database`,\n });\n columnNodes.push({\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 continue;\n }\n\n // Column exists - compare type and nullability\n const columnChildren: SchemaVerificationNode[] = [];\n let columnStatus: 'pass' | 'warn' | 'fail' = 'pass';\n\n // Compare type using nativeType directly\n // Contract now stores nativeType directly (e.g., 'int4'), schema IR has nativeType (e.g., 'int4')\n const contractNativeType = contractColumn.nativeType;\n const schemaNativeType = schemaColumn.nativeType;\n\n if (!contractNativeType) {\n // Contract column doesn't have nativeType - this shouldn't happen with new contract format\n issues.push({\n kind: 'type_mismatch',\n table: tableName,\n column: columnName,\n expected: 'nativeType required',\n actual: schemaNativeType || 'unknown',\n message: `Column \"${tableName}\".\"${columnName}\" is missing nativeType in contract`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'type',\n name: 'type',\n contractPath: `${columnPath}.nativeType`,\n code: 'type_mismatch',\n message: 'Contract column is missing nativeType',\n expected: 'nativeType required',\n actual: schemaNativeType || 'unknown',\n children: [],\n });\n columnStatus = 'fail';\n } else if (!schemaNativeType) {\n // Schema IR doesn't have nativeType - this shouldn't happen\n issues.push({\n kind: 'type_mismatch',\n table: tableName,\n column: columnName,\n expected: contractNativeType,\n actual: 'unknown',\n message: `Column \"${tableName}\".\"${columnName}\" has type mismatch: schema column has no nativeType`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'type',\n name: 'type',\n contractPath: `${columnPath}.nativeType`,\n code: 'type_mismatch',\n message: 'Schema column has no nativeType',\n expected: contractNativeType,\n actual: 'unknown',\n children: [],\n });\n columnStatus = 'fail';\n } else if (contractNativeType !== schemaNativeType) {\n // Compare native types directly\n issues.push({\n kind: 'type_mismatch',\n table: tableName,\n column: columnName,\n expected: contractNativeType,\n actual: schemaNativeType,\n message: `Column \"${tableName}\".\"${columnName}\" has type mismatch: expected \"${contractNativeType}\", got \"${schemaNativeType}\"`,\n });\n columnChildren.push({\n status: 'fail',\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 = 'fail';\n }\n\n // Optionally validate that codecId (if present) and nativeType agree with registry\n if (contractColumn.codecId) {\n const typeMetadata = typeMetadataRegistry.get(contractColumn.codecId);\n if (!typeMetadata) {\n // Warning: codecId not found in registry\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 \"${contractColumn.codecId}\" not found in type metadata registry`,\n expected: contractColumn.codecId,\n actual: undefined,\n children: [],\n });\n } else if (typeMetadata.nativeType && typeMetadata.nativeType !== contractNativeType) {\n // Warning: codecId and nativeType don't agree with registry\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 \"${contractColumn.codecId}\" maps to nativeType \"${typeMetadata.nativeType}\" in registry, but contract has \"${contractNativeType}\"`,\n expected: typeMetadata.nativeType,\n actual: contractNativeType,\n children: [],\n });\n }\n }\n\n // Compare nullability\n if (contractColumn.nullable !== schemaColumn.nullable) {\n issues.push({\n kind: 'nullability_mismatch',\n table: tableName,\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 columnChildren.push({\n status: 'fail',\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 = 'fail';\n }\n\n // Compute column status from children (fail > warn > pass)\n const computedColumnStatus = columnChildren.some((c) => c.status === 'fail')\n ? 'fail'\n : columnChildren.some((c) => c.status === 'warn')\n ? 'warn'\n : 'pass';\n // Use computed status if we have children, otherwise use the manually set status\n const finalColumnStatus = columnChildren.length > 0 ? computedColumnStatus : columnStatus;\n\n // Build column node\n const nullableText = contractColumn.nullable ? 'nullable' : 'not nullable';\n // Format: columnName: nativeType (codecId) (nullability)\n // Reuse contractNativeType from above scope\n const columnTypeDisplay = contractColumn.codecId\n ? `${contractNativeType} (${contractColumn.codecId})`\n : contractNativeType;\n // Collect failure messages from children to create a summary message\n const failureMessages = columnChildren\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 columnMessage =\n finalColumnStatus === 'fail' && failureMessages.length > 0\n ? failureMessages.join('; ')\n : '';\n const columnCode =\n finalColumnStatus === 'fail' && columnChildren.length > 0 && columnChildren[0]\n ? columnChildren[0].code\n : finalColumnStatus === 'warn' && columnChildren.length > 0 && columnChildren[0]\n ? columnChildren[0].code\n : '';\n columnNodes.push({\n status: finalColumnStatus,\n kind: 'column',\n name: `${columnName}: ${columnTypeDisplay} (${nullableText})`,\n contractPath: columnPath,\n code: columnCode,\n message: columnMessage,\n expected: undefined,\n actual: undefined,\n children: columnChildren,\n });\n }\n\n // Group columns under a \"columns\" header if we have any columns\n if (columnNodes.length > 0) {\n const columnsStatus = columnNodes.some((c) => c.status === 'fail')\n ? 'fail'\n : columnNodes.some((c) => c.status === 'warn')\n ? 'warn'\n : 'pass';\n tableChildren.push({\n status: columnsStatus,\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\n // Check for extra columns in strict mode\n if (strict) {\n for (const [columnName, schemaColumn] of Object.entries(schemaTable.columns)) {\n if (!contractTable.columns[columnName]) {\n issues.push({\n kind: 'missing_column',\n table: tableName,\n column: columnName,\n message: `Extra column \"${tableName}\".\"${columnName}\" found in database (not in contract)`,\n });\n columnNodes.push({\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: schemaColumn.nativeType,\n children: [],\n });\n }\n }\n }\n\n // Compare primary key\n if (contractTable.primaryKey) {\n const pkStatus = comparePrimaryKey(\n contractTable.primaryKey,\n schemaTable.primaryKey,\n tableName,\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 {\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 // Extra primary key in strict mode\n issues.push({\n kind: 'primary_key_mismatch',\n table: tableName,\n message: 'Extra primary key found in database (not in contract)',\n });\n tableChildren.push({\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 }\n\n // Compare foreign keys\n const fkStatuses = compareForeignKeys(\n contractTable.foreignKeys,\n schemaTable.foreignKeys,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...fkStatuses);\n\n // Compare unique constraints\n const uniqueStatuses = compareUniqueConstraints(\n contractTable.uniques,\n schemaTable.uniques,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...uniqueStatuses);\n\n // Compare indexes\n const indexStatuses = compareIndexes(\n contractTable.indexes,\n schemaTable.indexes,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...indexStatuses);\n\n // Build table node\n const tableStatus = tableChildren.some((c) => c.status === 'fail')\n ? 'fail'\n : tableChildren.some((c) => c.status === 'warn')\n ? 'warn'\n : 'pass';\n // Collect failure messages from children to create a summary message\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 rootChildren.push({\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\n // Check for extra tables in strict mode\n if (strict) {\n for (const tableName of Object.keys(schemaTables)) {\n if (!contractTables[tableName]) {\n issues.push({\n kind: 'missing_table',\n table: tableName,\n message: `Extra table \"${tableName}\" found in database (not in contract)`,\n });\n rootChildren.push({\n status: 'fail',\n kind: 'table',\n name: `table ${tableName}`,\n contractPath: `storage.tables.${tableName}`,\n code: 'extra_table',\n message: `Extra table \"${tableName}\" found`,\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n }\n\n // Compare extensions\n const extensionStatuses = compareExtensions(\n contract.extensions,\n schemaIR.extensions,\n contractTarget,\n issues,\n strict,\n );\n rootChildren.push(...extensionStatuses);\n\n // Build root node\n const rootStatus = rootChildren.some((c) => c.status === 'fail')\n ? 'fail'\n : rootChildren.some((c) => c.status === 'warn')\n ? 'warn'\n : 'pass';\n const root: SchemaVerificationNode = {\n status: rootStatus,\n kind: 'contract',\n name: 'contract',\n contractPath: '',\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: rootChildren,\n };\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 ...(code ? { code } : {}),\n summary,\n contract: {\n coreHash: contractCoreHash,\n ...(contractProfileHash ? { profileHash: contractProfileHash } : {}),\n },\n target: {\n expected: contractTarget,\n actual: contractTarget,\n },\n schema: {\n issues,\n root,\n counts,\n },\n meta: {\n contractPath,\n strict,\n ...(configPath ? { configPath } : {}),\n },\n timings: {\n total: totalTime,\n },\n };\n },\n async sign(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult> {\n const { driver, contractIR, contractPath, configPath } = options;\n const startTime = Date.now();\n\n // Validate contractIR as SqlContract<SqlStorage>\n const contract = validateContract<SqlContract<SqlStorage>>(contractIR);\n\n // Extract contract hashes and target\n const contractCoreHash = contract.coreHash;\n const contractProfileHash =\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : contractCoreHash;\n const contractTarget = contract.target;\n\n // Ensure marker schema and table exist\n await driver.query(ensureSchemaStatement.sql, ensureSchemaStatement.params);\n await driver.query(ensureTableStatement.sql, ensureTableStatement.params);\n\n // Read existing marker\n const existingMarker = await readMarker(driver);\n\n // Determine if we need to write/update marker\n let markerCreated = false;\n let markerUpdated = false;\n let previousHashes: { coreHash?: string; profileHash?: string } | undefined;\n\n if (!existingMarker) {\n // No marker exists - insert new one\n const write = writeContractMarker({\n coreHash: contractCoreHash,\n profileHash: contractProfileHash,\n contractJson: contractIR,\n canonicalVersion: 1,\n });\n await driver.query(write.insert.sql, write.insert.params);\n markerCreated = true;\n } else {\n // Marker exists - check if hashes differ\n const existingCoreHash = existingMarker.coreHash;\n const existingProfileHash = existingMarker.profileHash;\n\n // Compare hashes (use strict equality to ensure exact match)\n const coreHashMatches = existingCoreHash === contractCoreHash;\n const profileHashMatches = existingProfileHash === contractProfileHash;\n\n if (!coreHashMatches || !profileHashMatches) {\n // Hashes differ - update marker and capture previous hashes for output\n previousHashes = {\n coreHash: existingCoreHash,\n profileHash: existingProfileHash,\n };\n const write = writeContractMarker({\n coreHash: contractCoreHash,\n profileHash: contractProfileHash,\n contractJson: contractIR,\n canonicalVersion: existingMarker.canonicalVersion ?? 1,\n });\n await driver.query(write.update.sql, write.update.params);\n markerUpdated = true;\n }\n // If hashes match, no-op (idempotent) - previousHashes remains undefined\n }\n\n // Build summary message\n let summary: string;\n if (markerCreated) {\n summary = 'Database signed (marker created)';\n } else if (markerUpdated) {\n summary = `Database signed (marker updated from ${previousHashes?.coreHash ?? 'unknown'})`;\n } else {\n summary = 'Database already signed with this contract';\n }\n\n const totalTime = Date.now() - startTime;\n\n return {\n ok: true,\n summary,\n contract: {\n coreHash: contractCoreHash,\n profileHash: contractProfileHash,\n },\n target: {\n expected: contractTarget,\n actual: contractTarget,\n },\n marker: {\n created: markerCreated,\n updated: markerUpdated,\n ...(previousHashes ? { previous: previousHashes } : {}),\n },\n meta: {\n contractPath,\n ...(configPath ? { configPath } : {}),\n },\n timings: {\n total: totalTime,\n },\n };\n },\n async introspect(options: {\n readonly driver: ControlDriverInstance;\n readonly contractIR?: unknown;\n }): Promise<SqlSchemaIR> {\n const { driver, contractIR } = options;\n\n // ControlAdapterDescriptor has create() method that returns SqlControlAdapter\n const controlAdapter = adapter.create() as SqlControlAdapter;\n return controlAdapter.introspect(driver as ControlDriverInstance<string>, contractIR);\n },\n\n toSchemaView(schema: SqlSchemaIR): CoreSchemaView {\n const rootLabel = 'contract';\n\n // Build table nodes\n const tableNodes: readonly SchemaTreeNode[] = Object.entries(schema.tables).map(\n ([tableName, table]: [string, SqlTableIR]) => {\n const children: SchemaTreeNode[] = [];\n\n // Add column nodes grouped under \"columns\"\n const columnNodes: SchemaTreeNode[] = [];\n for (const [columnName, column] of Object.entries(table.columns)) {\n const nullableText = column.nullable ? '(nullable)' : '(not nullable)';\n // Always display nativeType for introspection (database state)\n const typeDisplay = column.nativeType;\n const label = `${columnName}: ${typeDisplay} ${nullableText}`;\n columnNodes.push({\n kind: 'field',\n id: `column-${tableName}-${columnName}`,\n label,\n meta: {\n nativeType: column.nativeType,\n nullable: column.nullable,\n },\n });\n }\n\n // Add \"columns\" grouping node if there are columns\n if (columnNodes.length > 0) {\n children.push({\n kind: 'collection',\n id: `columns-${tableName}`,\n label: 'columns',\n children: columnNodes,\n });\n }\n\n // Add primary key node if present\n if (table.primaryKey) {\n const pkColumns = table.primaryKey.columns.join(', ');\n children.push({\n kind: 'index',\n id: `primary-key-${tableName}`,\n label: `primary key: ${pkColumns}`,\n meta: {\n columns: table.primaryKey.columns,\n ...(table.primaryKey.name ? { name: table.primaryKey.name } : {}),\n },\n });\n }\n\n // Add unique constraint nodes\n for (const unique of table.uniques) {\n const name = unique.name ?? `${tableName}_${unique.columns.join('_')}_unique`;\n const label = `unique ${name}`;\n children.push({\n kind: 'index',\n id: `unique-${tableName}-${name}`,\n label,\n meta: {\n columns: unique.columns,\n unique: true,\n },\n });\n }\n\n // Add index nodes\n for (const index of table.indexes) {\n const name = index.name ?? `${tableName}_${index.columns.join('_')}_idx`;\n const label = index.unique ? `unique index ${name}` : `index ${name}`;\n children.push({\n kind: 'index',\n id: `index-${tableName}-${name}`,\n label,\n meta: {\n columns: index.columns,\n unique: index.unique,\n },\n });\n }\n\n // Build table meta\n const tableMeta: Record<string, unknown> = {};\n if (table.primaryKey) {\n tableMeta['primaryKey'] = table.primaryKey.columns;\n if (table.primaryKey.name) {\n tableMeta['primaryKeyName'] = table.primaryKey.name;\n }\n }\n if (table.foreignKeys.length > 0) {\n tableMeta['foreignKeys'] = table.foreignKeys.map((fk) => ({\n columns: fk.columns,\n referencedTable: fk.referencedTable,\n referencedColumns: fk.referencedColumns,\n ...(fk.name ? { name: fk.name } : {}),\n }));\n }\n\n const node: SchemaTreeNode = {\n kind: 'entity',\n id: `table-${tableName}`,\n label: `table ${tableName}`,\n ...(Object.keys(tableMeta).length > 0 ? { meta: tableMeta } : {}),\n ...(children.length > 0 ? { children: children as readonly SchemaTreeNode[] } : {}),\n };\n return node;\n },\n );\n\n // Add extension nodes (format: \"extensionName extension is enabled\")\n const extensionNodes: readonly SchemaTreeNode[] = schema.extensions.map((extName) => ({\n kind: 'extension',\n id: `extension-${extName}`,\n label: `${extName} extension is enabled`,\n }));\n\n // Combine all children\n const rootChildren = [...tableNodes, ...extensionNodes];\n\n const rootNode: SchemaTreeNode = {\n kind: 'root',\n id: 'sql-schema',\n label: rootLabel,\n ...(rootChildren.length > 0 ? { children: rootChildren } : {}),\n };\n\n return {\n root: rootNode,\n };\n },\n\n async emitContract({ contractIR }): Promise<EmitContractResult> {\n // Strip mappings if present (mappings are runtime-only)\n const contractWithoutMappings = stripMappings(contractIR);\n\n // Validate and normalize the contract\n const validatedIR = this.validateContractIR(contractWithoutMappings) as ContractIR;\n\n const result = await emit(\n validatedIR,\n {\n outputDir: '',\n operationRegistry,\n codecTypeImports,\n operationTypeImports,\n extensionIds,\n },\n sqlTargetFamilyHook,\n );\n\n return {\n contractJson: result.contractJson,\n contractDts: result.contractDts,\n coreHash: result.coreHash,\n profileHash: result.profileHash,\n };\n },\n };\n}\n"],"mappings":"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","names":["totalTime","options","convertOperationManifest"]}
|