@prisma-next/family-sql 0.5.0-dev.33 → 0.5.0-dev.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/control.d.mts +1 -1
- package/dist/migration.d.mts +1 -1
- package/dist/schema-verify.d.mts +1 -1
- package/dist/{types-sZihdnGx.d.mts → types-DhhBX-xv.d.mts} +14 -7
- package/dist/{types-sZihdnGx.d.mts.map → types-DhhBX-xv.d.mts.map} +1 -1
- package/dist/verify-sql-schema-Ovz7RXR5.mjs.map +1 -1
- package/package.json +20 -20
- package/src/core/migrations/types.ts +13 -6
package/dist/control.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as SqlPlannerFailureResult, C as SqlMigrationRunnerFailure, D as SqlPlannerConflict, E as SqlPlanTargetDetails, F as isDatabaseDependencyProvider, I as SchemaVerifyOptions, L as SqlControlFamilyInstance, M as SqlPlannerSuccessResult, N as StorageTypePlanResult, O as SqlPlannerConflictKind, P as collectInitDependencies, S as SqlMigrationRunnerExecuteOptions, T as SqlMigrationRunnerSuccessValue, _ as SqlMigrationPlanner, a as ComponentDatabaseDependency, b as SqlMigrationRunnerErrorCode, c as ResolveIdentityValueInput, d as SqlControlTargetDescriptor, f as SqlMigrationPlan, g as SqlMigrationPlanOperationTarget, h as SqlMigrationPlanOperationStep, i as ComponentDatabaseDependencies, j as SqlPlannerResult, k as SqlPlannerConflictLocation, l as SqlControlAdapterDescriptor, m as SqlMigrationPlanOperation, n as AnySqlMigrationOperation, o as CreateSqlMigrationPlanOptions, p as SqlMigrationPlanContractInfo, r as CodecControlHooks, s as ExpandNativeTypeInput, t as AnyRecord, u as SqlControlExtensionDescriptor, v as SqlMigrationPlannerPlanOptions, w as SqlMigrationRunnerResult, x as SqlMigrationRunnerExecuteCallbacks, y as SqlMigrationRunner } from "./types-
|
|
1
|
+
import { A as SqlPlannerFailureResult, C as SqlMigrationRunnerFailure, D as SqlPlannerConflict, E as SqlPlanTargetDetails, F as isDatabaseDependencyProvider, I as SchemaVerifyOptions, L as SqlControlFamilyInstance, M as SqlPlannerSuccessResult, N as StorageTypePlanResult, O as SqlPlannerConflictKind, P as collectInitDependencies, S as SqlMigrationRunnerExecuteOptions, T as SqlMigrationRunnerSuccessValue, _ as SqlMigrationPlanner, a as ComponentDatabaseDependency, b as SqlMigrationRunnerErrorCode, c as ResolveIdentityValueInput, d as SqlControlTargetDescriptor, f as SqlMigrationPlan, g as SqlMigrationPlanOperationTarget, h as SqlMigrationPlanOperationStep, i as ComponentDatabaseDependencies, j as SqlPlannerResult, k as SqlPlannerConflictLocation, l as SqlControlAdapterDescriptor, m as SqlMigrationPlanOperation, n as AnySqlMigrationOperation, o as CreateSqlMigrationPlanOptions, p as SqlMigrationPlanContractInfo, r as CodecControlHooks, s as ExpandNativeTypeInput, t as AnyRecord, u as SqlControlExtensionDescriptor, v as SqlMigrationPlannerPlanOptions, w as SqlMigrationRunnerResult, x as SqlMigrationRunnerExecuteCallbacks, y as SqlMigrationRunner } from "./types-DhhBX-xv.mjs";
|
|
2
2
|
import { ControlFamilyDescriptor, ControlStack, MigrationOperationClass, MigrationOperationPolicy, MigrationOperationPolicy as MigrationOperationPolicy$1, MigrationPlan, MigrationPlanOperation, MigrationPlanner, MigrationPlannerConflict, MigrationPlannerConflict as MigrationPlannerConflict$1, MigrationPlannerResult, TargetMigrationsCapability, assembleAuthoringContributions } from "@prisma-next/framework-components/control";
|
|
3
3
|
import { NotOk, Ok } from "@prisma-next/utils/result";
|
|
4
4
|
import * as _prisma_next_contract_types0 from "@prisma-next/contract/types";
|
package/dist/migration.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as SqlPlanTargetDetails, n as AnySqlMigrationOperation } from "./types-
|
|
1
|
+
import { E as SqlPlanTargetDetails, n as AnySqlMigrationOperation } from "./types-DhhBX-xv.mjs";
|
|
2
2
|
import { Migration } from "@prisma-next/migration-tools/migration";
|
|
3
3
|
|
|
4
4
|
//#region src/core/sql-migration.d.ts
|
package/dist/schema-verify.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as verifySqlSchema, n as NativeTypeNormalizer, r as VerifySqlSchemaOptions } from "./verify-sql-schema-_EoNcGIq.mjs";
|
|
2
|
-
import { a as ComponentDatabaseDependency } from "./types-
|
|
2
|
+
import { a as ComponentDatabaseDependency } from "./types-DhhBX-xv.mjs";
|
|
3
3
|
import { SchemaIssue, SchemaVerificationNode } from "@prisma-next/framework-components/control";
|
|
4
4
|
import { SqlIndexIR, SqlSchemaIR, SqlUniqueIR } from "@prisma-next/sql-schema-ir/types";
|
|
5
5
|
|
|
@@ -226,14 +226,21 @@ interface SqlMigrationPlannerPlanOptions {
|
|
|
226
226
|
readonly policy: MigrationOperationPolicy;
|
|
227
227
|
readonly schemaName?: string;
|
|
228
228
|
/**
|
|
229
|
-
* The "from" contract (state the planner assumes the database starts at)
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
229
|
+
* The "from" contract (state the planner assumes the database starts at),
|
|
230
|
+
* or `null` for reconciliation flows that have no prior contract.
|
|
231
|
+
*
|
|
232
|
+
* Required at every call site so the structural fact "I have a prior
|
|
233
|
+
* contract / I don't" is visible in the type. `migration plan` supplies
|
|
234
|
+
* the previous bundle's `metadata.toContract`; `db update` / `db init`
|
|
235
|
+
* reconcile against the live schema and pass `null`. Strategies that
|
|
236
|
+
* need from/to column-shape comparisons (unsafe type change, nullability
|
|
233
237
|
* tightening) use this to decide whether to emit `dataTransform`
|
|
234
|
-
* placeholders
|
|
238
|
+
* placeholders; they short-circuit when it is `null`.
|
|
239
|
+
*
|
|
240
|
+
* Planners also derive the "from" identity they stamp onto the produced
|
|
241
|
+
* plan's `describe()` as `fromContract?.storage.storageHash ?? null`.
|
|
235
242
|
*/
|
|
236
|
-
readonly fromContract
|
|
243
|
+
readonly fromContract: Contract<SqlStorage> | null;
|
|
237
244
|
/**
|
|
238
245
|
* Active framework components participating in this composition.
|
|
239
246
|
* SQL targets can interpret this list to derive database dependencies.
|
|
@@ -307,4 +314,4 @@ interface CreateSqlMigrationPlanOptions<TTargetDetails> {
|
|
|
307
314
|
}
|
|
308
315
|
//#endregion
|
|
309
316
|
export { SqlPlannerFailureResult as A, SqlMigrationRunnerFailure as C, SqlPlannerConflict as D, SqlPlanTargetDetails as E, isDatabaseDependencyProvider as F, SchemaVerifyOptions as I, SqlControlFamilyInstance as L, SqlPlannerSuccessResult as M, StorageTypePlanResult as N, SqlPlannerConflictKind as O, collectInitDependencies as P, SqlMigrationRunnerExecuteOptions as S, SqlMigrationRunnerSuccessValue as T, SqlMigrationPlanner as _, ComponentDatabaseDependency as a, SqlMigrationRunnerErrorCode as b, ResolveIdentityValueInput as c, SqlControlTargetDescriptor as d, SqlMigrationPlan as f, SqlMigrationPlanOperationTarget as g, SqlMigrationPlanOperationStep as h, ComponentDatabaseDependencies as i, SqlPlannerResult as j, SqlPlannerConflictLocation as k, SqlControlAdapterDescriptor as l, SqlMigrationPlanOperation as m, AnySqlMigrationOperation as n, CreateSqlMigrationPlanOptions as o, SqlMigrationPlanContractInfo as p, CodecControlHooks as r, ExpandNativeTypeInput as s, AnyRecord as t, SqlControlExtensionDescriptor as u, SqlMigrationPlannerPlanOptions as v, SqlMigrationRunnerResult as w, SqlMigrationRunnerExecuteCallbacks as x, SqlMigrationRunner as y };
|
|
310
|
-
//# sourceMappingURL=types-
|
|
317
|
+
//# sourceMappingURL=types-DhhBX-xv.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-
|
|
1
|
+
{"version":3,"file":"types-DhhBX-xv.d.mts","names":[],"sources":["../src/core/control-instance.ts","../src/core/migrations/types.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-sql-schema-Ovz7RXR5.mjs","names":["result: ComponentDatabaseDependency<unknown>[]","nodes: SchemaVerificationNode[]","depIssue: SchemaIssue","mismatches: Array<{ expected: string; actual: string; message: string }>","typeNodes: SchemaVerificationNode[]","issues: SchemaIssue[]","rootChildren: SchemaVerificationNode[]","tableChildren: SchemaVerificationNode[]","columnNodes: SchemaVerificationNode[]","columnChildren: SchemaVerificationNode[]","columnStatus: VerificationStatus","status: VerificationStatus","failureMessages: string[]","sorted: Record<string, unknown>"],"sources":["../src/core/assembly.ts","../src/core/migrations/types.ts","../src/core/schema-verify/verify-helpers.ts","../src/core/schema-verify/verify-sql-schema.ts"],"sourcesContent":["import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport { assertUniqueCodecOwner } from '@prisma-next/framework-components/control';\nimport type { CodecControlHooks } from './migrations/types';\n\ntype CodecControlHooksMap = Record<string, CodecControlHooks>;\n\nfunction hasCodecControlHooks(descriptor: unknown): descriptor is {\n readonly id: string;\n readonly types: {\n readonly codecTypes: {\n readonly controlPlaneHooks: CodecControlHooksMap;\n };\n };\n} {\n if (typeof descriptor !== 'object' || descriptor === null) {\n return false;\n }\n const d = descriptor as { types?: { codecTypes?: { controlPlaneHooks?: unknown } } };\n const hooks = d.types?.codecTypes?.controlPlaneHooks;\n return hooks !== null && hooks !== undefined && typeof hooks === 'object';\n}\n\nexport function extractCodecControlHooks(\n descriptors: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n): Map<string, CodecControlHooks> {\n const hooks = new Map<string, CodecControlHooks>();\n const owners = new Map<string, string>();\n\n for (const descriptor of descriptors) {\n if (typeof descriptor !== 'object' || descriptor === null) {\n continue;\n }\n if (!hasCodecControlHooks(descriptor)) {\n continue;\n }\n const controlPlaneHooks = descriptor.types.codecTypes.controlPlaneHooks;\n for (const [codecId, hook] of Object.entries(controlPlaneHooks)) {\n assertUniqueCodecOwner({\n codecId,\n owners,\n descriptorId: descriptor.id,\n entityLabel: 'control hooks',\n entityOwnershipLabel: 'owner',\n });\n hooks.set(codecId, hook);\n owners.set(codecId, descriptor.id);\n }\n }\n\n return hooks;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n DataTransformOperation,\n MigratableTargetDescriptor,\n MigrationOperationPolicy,\n MigrationPlan,\n MigrationPlannerConflict,\n MigrationPlannerFailureResult,\n MigrationPlannerSuccessResult,\n MigrationPlanOperation,\n MigrationRunnerExecutionChecks,\n MigrationRunnerFailure,\n MigrationRunnerSuccessValue,\n OperationContext,\n SchemaIssue,\n} from '@prisma-next/framework-components/control';\nimport type { SqlStorage, StorageTypeInstance } from '@prisma-next/sql-contract/types';\nimport type { SqlOperationDescriptor } from '@prisma-next/sql-operations';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport type { Result } from '@prisma-next/utils/result';\nimport type { SqlControlFamilyInstance } from '../control-instance';\n\nexport type AnyRecord = Readonly<Record<string, unknown>>;\n\nexport interface ComponentDatabaseDependency<TTargetDetails> {\n readonly id: string;\n readonly label: string;\n readonly install: readonly SqlMigrationPlanOperation<TTargetDetails>[];\n}\n\nexport interface ComponentDatabaseDependencies<TTargetDetails> {\n readonly init?: readonly ComponentDatabaseDependency<TTargetDetails>[];\n}\n\nexport interface DatabaseDependencyProvider {\n readonly databaseDependencies?: ComponentDatabaseDependencies<unknown>;\n}\n\nexport function isDatabaseDependencyProvider(value: unknown): value is DatabaseDependencyProvider {\n return typeof value === 'object' && value !== null && 'databaseDependencies' in value;\n}\n\nexport function collectInitDependencies(\n components: ReadonlyArray<unknown>,\n): readonly ComponentDatabaseDependency<unknown>[] {\n const result: ComponentDatabaseDependency<unknown>[] = [];\n for (const component of components) {\n if (!isDatabaseDependencyProvider(component)) continue;\n const deps = component.databaseDependencies?.init;\n if (!deps) continue;\n result.push(...deps);\n }\n return result;\n}\n\nexport interface StorageTypePlanResult<TTargetDetails> {\n readonly operations: readonly SqlMigrationPlanOperation<TTargetDetails>[];\n}\n\n/**\n * Input for expanding parameterized native types.\n */\nexport interface ExpandNativeTypeInput {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n}\n\n/**\n * Input for resolving an identity-value SQL literal used to backfill existing rows when\n * adding a NOT NULL column without an explicit default.\n *\n * \"Identity value\" in the algebraic (monoid) sense: the neutral element for the type\n * (0 for numbers, '' for strings, false for booleans, etc.).\n */\nexport interface ResolveIdentityValueInput {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n}\n\nexport interface CodecControlHooks<TTargetDetails = unknown> {\n planTypeOperations?: (options: {\n readonly typeName: string;\n readonly typeInstance: StorageTypeInstance;\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIR;\n readonly schemaName?: string;\n readonly policy: MigrationOperationPolicy;\n }) => StorageTypePlanResult<TTargetDetails>;\n verifyType?: (options: {\n readonly typeName: string;\n readonly typeInstance: StorageTypeInstance;\n readonly schema: SqlSchemaIR;\n readonly schemaName?: string;\n }) => readonly SchemaIssue[];\n introspectTypes?: (options: {\n readonly driver: ControlDriverInstance<'sql', string>;\n readonly schemaName?: string;\n }) => Promise<Record<string, StorageTypeInstance>>;\n /**\n * Expands a parameterized native type to its full SQL representation.\n * Used by schema verification to compare contract types against database types.\n *\n * For example, expands:\n * - { nativeType: 'character varying', typeParams: { length: 255 } } -> 'character varying(255)'\n * - { nativeType: 'numeric', typeParams: { precision: 10, scale: 2 } } -> 'numeric(10,2)'\n *\n * Returns the expanded type string, or the original nativeType if no expansion is needed.\n */\n expandNativeType?: (input: ExpandNativeTypeInput) => string;\n /**\n * Resolves the identity value (monoid neutral element) as a SQL literal for safely adding\n * a NOT NULL column without an explicit default to a non-empty table.\n *\n * Return semantics:\n * - string: use this literal\n * - null: explicitly no safe identity value is known; fall back to another strategy\n * - undefined: no opinion; planner may use built-in fallbacks\n */\n resolveIdentityValue?: (input: ResolveIdentityValueInput) => string | null | undefined;\n}\n\nexport interface SqlControlExtensionDescriptor<TTargetId extends string>\n extends ControlExtensionDescriptor<'sql', TTargetId> {\n readonly databaseDependencies?: ComponentDatabaseDependencies<unknown>;\n readonly queryOperations?: () => ReadonlyArray<SqlOperationDescriptor>;\n}\n\nexport interface SqlControlAdapterDescriptor<TTargetId extends string>\n extends ControlAdapterDescriptor<'sql', TTargetId> {\n readonly queryOperations?: () => ReadonlyArray<SqlOperationDescriptor>;\n}\n\nexport interface SqlMigrationPlanOperationStep {\n readonly description: string;\n readonly sql: string;\n readonly meta?: AnyRecord;\n}\n\n/**\n * Minimal shape every SQL-family target must conform to for its per-operation\n * `target.details` payload. Each SQL operation addresses a named database\n * object in some schema; targets (Postgres, MySQL, SQLite, …) extend this\n * shape with their own fields (e.g. Postgres adds `objectType` and optional\n * `table`).\n */\nexport interface SqlPlanTargetDetails {\n readonly schema: string;\n readonly name: string;\n}\n\nexport interface SqlMigrationPlanOperationTarget<TTargetDetails> {\n readonly id: string;\n readonly details?: TTargetDetails;\n}\n\nexport interface SqlMigrationPlanOperation<TTargetDetails> extends MigrationPlanOperation {\n readonly summary?: string;\n readonly target: SqlMigrationPlanOperationTarget<TTargetDetails>;\n readonly precheck: readonly SqlMigrationPlanOperationStep[];\n readonly execute: readonly SqlMigrationPlanOperationStep[];\n readonly postcheck: readonly SqlMigrationPlanOperationStep[];\n readonly meta?: AnyRecord;\n}\n\n/**\n * Union of all operation shapes a SQL-family migration may emit: schema-facing\n * `SqlMigrationPlanOperation`s and family-agnostic `DataTransformOperation`s.\n *\n * Mirrors `AnyMongoMigrationOperation` in shape — the runner already handles\n * both branches via `isDataTransformOperation`, and authored `migration.ts`\n * files must be able to intermix `dataTransform(endContract, …)` calls with\n * DDL factory calls (e.g. `setNotNull(…)`) in a single `operations` array.\n */\nexport type AnySqlMigrationOperation<TTargetDetails> =\n | SqlMigrationPlanOperation<TTargetDetails>\n | DataTransformOperation;\n\nexport interface SqlMigrationPlanContractInfo {\n readonly storageHash: string;\n readonly profileHash?: string;\n}\n\nexport interface SqlMigrationPlan<TTargetDetails> extends MigrationPlan {\n /**\n * Origin contract identity that the plan expects the database to currently be at.\n * If omitted or null, the runner skips origin validation entirely.\n */\n readonly origin?: SqlMigrationPlanContractInfo | null;\n /**\n * Destination contract identity that the plan intends to reach.\n */\n readonly destination: SqlMigrationPlanContractInfo;\n readonly operations: readonly SqlMigrationPlanOperation<TTargetDetails>[];\n readonly meta?: AnyRecord;\n}\n\nexport type SqlPlannerConflictKind =\n | 'typeMismatch'\n | 'nullabilityConflict'\n | 'indexIncompatible'\n | 'foreignKeyConflict'\n | 'missingButNonAdditive'\n | 'unsupportedOperation';\n\nexport interface SqlPlannerConflictLocation {\n readonly table?: string;\n readonly column?: string;\n readonly index?: string;\n readonly constraint?: string;\n readonly type?: string;\n}\n\nexport interface SqlPlannerConflict extends MigrationPlannerConflict {\n readonly kind: SqlPlannerConflictKind;\n readonly location?: SqlPlannerConflictLocation;\n readonly meta?: AnyRecord;\n}\n\nexport interface SqlPlannerSuccessResult<TTargetDetails>\n extends Omit<MigrationPlannerSuccessResult, 'plan'> {\n readonly kind: 'success';\n readonly plan: SqlMigrationPlan<TTargetDetails>;\n}\n\nexport interface SqlPlannerFailureResult extends Omit<MigrationPlannerFailureResult, 'conflicts'> {\n readonly kind: 'failure';\n readonly conflicts: readonly SqlPlannerConflict[];\n}\n\nexport type SqlPlannerResult<TTargetDetails> =\n | SqlPlannerSuccessResult<TTargetDetails>\n | SqlPlannerFailureResult;\n\nexport interface SqlMigrationPlannerPlanOptions {\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIR;\n readonly policy: MigrationOperationPolicy;\n readonly schemaName?: string;\n /**\n * The \"from\" contract (state the planner assumes the database starts at).\n * Only `migration plan` supplies this; `db update` / `db init` reconcile\n * against the live schema with no old contract. Strategies that need\n * from/to column-shape comparisons (unsafe type change, nullability\n * tightening) use this to decide whether to emit `dataTransform`\n * placeholders.\n */\n readonly fromContract?: Contract<SqlStorage> | null;\n /**\n * Active framework components participating in this composition.\n * SQL targets can interpret this list to derive database dependencies.\n * All components must have matching familyId ('sql') and targetId.\n */\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n}\n\nexport interface SqlMigrationPlanner<TTargetDetails> {\n plan(options: SqlMigrationPlannerPlanOptions): SqlPlannerResult<TTargetDetails>;\n}\n\nexport interface SqlMigrationRunnerExecuteCallbacks<TTargetDetails> {\n onOperationStart?(operation: SqlMigrationPlanOperation<TTargetDetails>): void;\n onOperationComplete?(operation: SqlMigrationPlanOperation<TTargetDetails>): void;\n}\n\nexport interface SqlMigrationRunnerExecuteOptions<TTargetDetails> {\n readonly plan: SqlMigrationPlan<TTargetDetails>;\n readonly driver: ControlDriverInstance<'sql', string>;\n /**\n * Destination contract IR.\n * Must correspond to `plan.destination` and is used for schema verification and marker/ledger writes.\n */\n readonly destinationContract: Contract<SqlStorage>;\n /**\n * Execution-time policy that defines which operation classes are allowed.\n * The runner validates each operation against this policy before execution.\n */\n readonly policy: MigrationOperationPolicy;\n readonly schemaName?: string;\n readonly strictVerification?: boolean;\n readonly callbacks?: SqlMigrationRunnerExecuteCallbacks<TTargetDetails>;\n readonly context?: OperationContext;\n /**\n * Execution-time checks configuration.\n * All checks default to `true` (enabled) when omitted.\n */\n readonly executionChecks?: MigrationRunnerExecutionChecks;\n /**\n * Active framework components participating in this composition.\n * SQL targets can interpret this list to derive database dependencies.\n * All components must have matching familyId ('sql') and targetId.\n */\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Invariant ids contributed by this apply (the migration's `providedInvariants`).\n * The runner unions these into `marker.invariants` atomically with the marker write.\n * Defaults to `[]` for marker-only flows (`db update`, `db init`).\n */\n readonly invariants?: readonly string[];\n}\n\nexport type SqlMigrationRunnerErrorCode =\n | 'DESTINATION_CONTRACT_MISMATCH'\n | 'MARKER_ORIGIN_MISMATCH'\n | 'POLICY_VIOLATION'\n | 'PRECHECK_FAILED'\n | 'POSTCHECK_FAILED'\n | 'SCHEMA_VERIFY_FAILED'\n | 'FOREIGN_KEY_VIOLATION'\n | 'EXECUTION_FAILED';\n\nexport interface SqlMigrationRunnerFailure extends MigrationRunnerFailure {\n readonly code: SqlMigrationRunnerErrorCode;\n readonly meta?: AnyRecord;\n}\n\nexport interface SqlMigrationRunnerSuccessValue extends MigrationRunnerSuccessValue {}\n\nexport type SqlMigrationRunnerResult = Result<\n SqlMigrationRunnerSuccessValue,\n SqlMigrationRunnerFailure\n>;\n\nexport interface SqlMigrationRunner<TTargetDetails> {\n execute(\n options: SqlMigrationRunnerExecuteOptions<TTargetDetails>,\n ): Promise<SqlMigrationRunnerResult>;\n}\n\nexport interface SqlControlTargetDescriptor<TTargetId extends string, TTargetDetails>\n extends MigratableTargetDescriptor<'sql', TTargetId, SqlControlFamilyInstance> {\n readonly queryOperations?: () => ReadonlyArray<SqlOperationDescriptor>;\n createPlanner(family: SqlControlFamilyInstance): SqlMigrationPlanner<TTargetDetails>;\n createRunner(family: SqlControlFamilyInstance): SqlMigrationRunner<TTargetDetails>;\n}\n\nexport interface CreateSqlMigrationPlanOptions<TTargetDetails> {\n readonly targetId: string;\n readonly origin?: SqlMigrationPlanContractInfo | null;\n readonly destination: SqlMigrationPlanContractInfo;\n readonly operations: readonly SqlMigrationPlanOperation<TTargetDetails>[];\n readonly meta?: AnyRecord;\n}\n","/**\n * Pure verification helper functions for SQL schema verification.\n * These functions verify schema IR against contract requirements.\n */\n\nimport type {\n SchemaIssue,\n SchemaVerificationNode,\n} from '@prisma-next/framework-components/control';\nimport type {\n ForeignKey,\n Index,\n PrimaryKey,\n UniqueConstraint,\n} from '@prisma-next/sql-contract/types';\nimport type {\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlSchemaIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\nimport type { ComponentDatabaseDependency } from '../migrations/types';\n\n/**\n * Compares two arrays of strings for equality (order-sensitive).\n */\nexport function arraysEqual(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n// ============================================================================\n// Semantic Satisfaction Predicates\n// ============================================================================\n// These predicates implement the \"stronger satisfies weaker\" logic for storage\n// objects. They are used by both verification and migration planning to ensure\n// consistent behavior across the control plane.\n\n/**\n * Checks if a unique constraint requirement is satisfied by the given columns.\n *\n * Semantic satisfaction: a unique constraint requirement can be satisfied by:\n * - A unique constraint with the same columns, OR\n * - A unique index with the same columns\n *\n * @param uniques - The unique constraints in the schema table\n * @param indexes - The indexes in the schema table\n * @param columns - The columns required by the unique constraint\n * @returns true if the requirement is satisfied\n */\nexport function isUniqueConstraintSatisfied(\n uniques: readonly SqlUniqueIR[],\n indexes: readonly SqlIndexIR[],\n columns: readonly string[],\n): boolean {\n // Check for matching unique constraint\n const hasConstraint = uniques.some((unique) => arraysEqual(unique.columns, columns));\n if (hasConstraint) {\n return true;\n }\n // Check for matching unique index (semantic satisfaction)\n return indexes.some((index) => index.unique && arraysEqual(index.columns, columns));\n}\n\n/**\n * Checks if an index requirement is satisfied by the given columns.\n *\n * Semantic satisfaction: a non-unique index requirement can be satisfied by:\n * - Any index (unique or non-unique) with the same columns, OR\n * - A unique constraint with the same columns (stronger satisfies weaker)\n *\n * @param indexes - The indexes in the schema table\n * @param uniques - The unique constraints in the schema table\n * @param columns - The columns required by the index\n * @returns true if the requirement is satisfied\n */\nexport function isIndexSatisfied(\n indexes: readonly SqlIndexIR[],\n uniques: readonly SqlUniqueIR[],\n columns: readonly string[],\n): boolean {\n // Check for any matching index (unique or non-unique)\n const hasMatchingIndex = indexes.some((index) => arraysEqual(index.columns, columns));\n if (hasMatchingIndex) {\n return true;\n }\n // Check for matching unique constraint (semantic satisfaction)\n return uniques.some((unique) => arraysEqual(unique.columns, columns));\n}\n\n/**\n * Verifies primary key matches between contract and schema.\n * Returns 'pass' or 'fail'.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyPrimaryKey(\n contractPK: PrimaryKey,\n schemaPK: PrimaryKey | undefined,\n tableName: string,\n 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 // Name differences are ignored for semantic satisfaction.\n // Names are persisted for deterministic DDL and diagnostics but are not identity.\n\n return 'pass';\n}\n\n/**\n * Verifies foreign keys match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + columns + referenced table + referenced columns).\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyForeignKeys(\n contractFKs: readonly ForeignKey[],\n schemaFKs: readonly SqlForeignKeyIR[],\n tableName: string,\n 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 const actionMismatches = getReferentialActionMismatches(contractFK, matchingFK);\n if (actionMismatches.length > 0) {\n const combinedMessage = actionMismatches.map((m) => m.message).join('; ');\n const combinedExpected = actionMismatches.map((m) => m.expected).join(', ');\n const combinedActual = actionMismatches.map((m) => m.actual).join(', ');\n issues.push({\n kind: 'foreign_key_mismatch',\n table: tableName,\n // Set indexOrConstraint so the planner classifies this as a non-additive\n // conflict (existing FK with wrong actions cannot be fixed additively).\n indexOrConstraint: matchingFK.name ?? `fk(${contractFK.columns.join(',')})`,\n expected: combinedExpected,\n actual: combinedActual,\n message: `Table \"${tableName}\" foreign key ${contractFK.columns.join(', ')} -> ${contractFK.references.table}: ${combinedMessage}`,\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: combinedMessage,\n expected: contractFK,\n actual: matchingFK,\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: 'extra_foreign_key',\n table: tableName,\n indexOrConstraint: schemaFK.name ?? `fk(${schemaFK.columns.join(',')})`,\n message: `Extra foreign key found in database (not in contract): ${schemaFK.columns.join(', ')} -> ${schemaFK.referencedTable}(${schemaFK.referencedColumns.join(', ')})`,\n });\n 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 * Verifies unique constraints match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * A unique constraint requirement can be satisfied by either:\n * - A unique constraint with the same columns, or\n * - A unique index with the same columns\n *\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyUniqueConstraints(\n contractUniques: readonly UniqueConstraint[],\n schemaUniques: readonly SqlUniqueIR[],\n schemaIndexes: readonly SqlIndexIR[],\n tableName: string,\n 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\n // First check for a matching unique constraint\n const matchingUnique = schemaUniques.find((u) =>\n arraysEqual(u.columns, contractUnique.columns),\n );\n\n // If no matching constraint, check for a unique index with the same columns\n const matchingUniqueIndex =\n !matchingUnique &&\n schemaIndexes.find((idx) => idx.unique && arraysEqual(idx.columns, contractUnique.columns));\n\n if (!matchingUnique && !matchingUniqueIndex) {\n 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 // Name differences are ignored for semantic satisfaction.\n // Names are persisted for deterministic DDL and diagnostics but are not identity.\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 // 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: 'extra_unique_constraint',\n table: tableName,\n indexOrConstraint: schemaUnique.name ?? `unique(${schemaUnique.columns.join(',')})`,\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 * Verifies indexes match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * A non-unique index requirement can be satisfied by either:\n * - A non-unique index with the same columns, or\n * - A unique index with the same columns (stronger satisfies weaker)\n *\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyIndexes(\n contractIndexes: readonly Index[],\n schemaIndexes: readonly SqlIndexIR[],\n schemaUniques: readonly SqlUniqueIR[],\n tableName: string,\n 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\n // Check for any matching index (unique or non-unique)\n // A unique index can satisfy a non-unique index requirement (stronger satisfies weaker)\n const matchingIndex = schemaIndexes.find((idx) =>\n arraysEqual(idx.columns, contractIndex.columns),\n );\n\n // Also check if a unique constraint satisfies the index requirement\n const matchingUniqueConstraint =\n !matchingIndex && schemaUniques.find((u) => arraysEqual(u.columns, contractIndex.columns));\n\n if (!matchingIndex && !matchingUniqueConstraint) {\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 // Name differences are ignored for semantic satisfaction.\n // Names are persisted for deterministic DDL and diagnostics but are not identity.\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 // 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: 'extra_index',\n table: tableName,\n indexOrConstraint: schemaIndex.name ?? `idx(${schemaIndex.columns.join(',')})`,\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 * Verifies database dependencies are installed using component-owned verification hooks.\n * Checks whether each dependency is satisfied by verifying its id is present in\n * schema.dependencies (populated from introspection).\n *\n * Returns verification nodes for the tree.\n */\nexport function verifyDatabaseDependencies(\n dependencies: ReadonlyArray<ComponentDatabaseDependency<unknown>>,\n schema: SqlSchemaIR,\n issues: SchemaIssue[],\n): SchemaVerificationNode[] {\n const nodes: SchemaVerificationNode[] = [];\n const installedIds = new Set(schema.dependencies.map((d) => d.id));\n\n for (const dependency of dependencies) {\n const isSatisfied = installedIds.has(dependency.id);\n const depPath = `dependencies.${dependency.id}`;\n\n if (!isSatisfied) {\n const depIssue: SchemaIssue = {\n kind: 'dependency_missing',\n dependencyId: dependency.id,\n message: `Dependency \"${dependency.id}\" is missing from database`,\n };\n issues.push(depIssue);\n const nodeMessage = depIssue.message;\n nodes.push({\n status: 'fail',\n kind: 'databaseDependency',\n name: dependency.label,\n contractPath: depPath,\n code: 'dependency_missing',\n message: nodeMessage,\n expected: undefined,\n actual: undefined,\n children: [],\n });\n } else {\n // Dependency is satisfied\n nodes.push({\n status: 'pass',\n kind: 'databaseDependency',\n name: dependency.label,\n contractPath: depPath,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n\n return nodes;\n}\n\n/**\n * Computes counts of pass/warn/fail nodes by traversing the tree.\n */\nexport function computeCounts(node: SchemaVerificationNode): {\n pass: number;\n warn: number;\n fail: number;\n totalNodes: number;\n} {\n let pass = 0;\n let warn = 0;\n let fail = 0;\n\n function traverse(n: SchemaVerificationNode): void {\n if (n.status === 'pass') {\n pass++;\n } else if (n.status === 'warn') {\n warn++;\n } else if (n.status === 'fail') {\n fail++;\n }\n\n if (n.children) {\n for (const child of n.children) {\n traverse(child);\n }\n }\n }\n\n traverse(node);\n\n return {\n pass,\n warn,\n fail,\n totalNodes: pass + warn + fail,\n };\n}\n\n/**\n * Compares referential actions between a contract FK and a schema FK.\n * Only compares when the contract FK explicitly specifies onDelete or onUpdate.\n * Returns all mismatches (both onDelete and onUpdate) so both are reported at once.\n *\n * Note: 'noAction' in the contract is semantically equivalent to undefined in the\n * schema IR, because the introspection adapter omits 'NO ACTION' (the database default)\n * to keep the IR sparse. We normalize both sides before comparing.\n */\nfunction getReferentialActionMismatches(\n contractFK: ForeignKey,\n schemaFK: SqlForeignKeyIR,\n): ReadonlyArray<{ expected: string; actual: string; message: string }> {\n const mismatches: Array<{ expected: string; actual: string; message: string }> = [];\n\n const contractOnDelete = normalizeReferentialAction(contractFK.onDelete);\n const schemaOnDelete = normalizeReferentialAction(schemaFK.onDelete);\n if (contractOnDelete !== undefined && contractOnDelete !== schemaOnDelete) {\n mismatches.push({\n expected: `onDelete: ${contractFK.onDelete}`,\n actual: `onDelete: ${schemaFK.onDelete ?? 'noAction (default)'}`,\n message: `onDelete mismatch: expected ${contractFK.onDelete}, got ${schemaFK.onDelete ?? 'noAction (default)'}`,\n });\n }\n\n const contractOnUpdate = normalizeReferentialAction(contractFK.onUpdate);\n const schemaOnUpdate = normalizeReferentialAction(schemaFK.onUpdate);\n if (contractOnUpdate !== undefined && contractOnUpdate !== schemaOnUpdate) {\n mismatches.push({\n expected: `onUpdate: ${contractFK.onUpdate}`,\n actual: `onUpdate: ${schemaFK.onUpdate ?? 'noAction (default)'}`,\n message: `onUpdate mismatch: expected ${contractFK.onUpdate}, got ${schemaFK.onUpdate ?? 'noAction (default)'}`,\n });\n }\n\n return mismatches;\n}\n\n/**\n * Normalizes a referential action value for comparison.\n * 'noAction' is the database default and equivalent to undefined (omitted) in the sparse IR.\n */\nfunction normalizeReferentialAction(action: string | undefined): string | undefined {\n return action === 'noAction' ? undefined : action;\n}\n","/**\n * Pure SQL schema verification function.\n *\n * This module provides a pure function that verifies a SqlSchemaIR against\n * a Contract without requiring a database connection. It can be reused\n * by migration planners and other tools that need to compare schema states.\n */\n\nimport type { ColumnDefault, Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n OperationContext,\n SchemaIssue,\n SchemaVerificationNode,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport type {\n SqlStorage,\n StorageColumn,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { extractCodecControlHooks } from '../assembly';\nimport { type CodecControlHooks, collectInitDependencies } from '../migrations/types';\nimport {\n arraysEqual,\n computeCounts,\n verifyDatabaseDependencies,\n verifyForeignKeys,\n verifyIndexes,\n verifyPrimaryKey,\n verifyUniqueConstraints,\n} from './verify-helpers';\n\n/**\n * Function type for normalizing raw database default expressions into ColumnDefault.\n * Target-specific implementations handle database dialect differences.\n */\nexport type DefaultNormalizer = (\n rawDefault: string,\n nativeType: string,\n) => ColumnDefault | undefined;\n\n/**\n * Function type for normalizing schema native types to canonical form for comparison.\n * Target-specific implementations handle dialect-specific type name variations\n * (e.g., Postgres 'varchar' → 'character varying', 'timestamptz' normalization).\n */\nexport type NativeTypeNormalizer = (nativeType: string) => string;\n\n/**\n * Options for the pure schema verification function.\n */\nexport interface VerifySqlSchemaOptions {\n /** The validated SQL contract to verify against */\n readonly contract: Contract<SqlStorage>;\n /** The schema IR from introspection (or another source) */\n readonly schema: SqlSchemaIR;\n /** Whether to run in strict mode (detects extra tables/columns) */\n readonly strict: boolean;\n /** Optional operation context for metadata */\n readonly context?: OperationContext;\n /** Type metadata registry for codec consistency warnings */\n readonly typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n /**\n * Active framework components participating in this composition.\n * All components must have matching familyId ('sql') and targetId.\n */\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Optional target-specific normalizer for raw database default expressions.\n * When provided, schema defaults (raw strings) are normalized before comparison\n * with contract defaults (ColumnDefault objects).\n */\n readonly normalizeDefault?: DefaultNormalizer;\n /**\n * Optional target-specific normalizer for schema native type names.\n * When provided, schema native types are normalized before comparison\n * with contract native types (e.g., Postgres 'varchar' → 'character varying').\n */\n readonly normalizeNativeType?: NativeTypeNormalizer;\n}\n\n/**\n * Verifies that a SqlSchemaIR matches a Contract.\n *\n * This is a pure function that does NOT perform any database I/O.\n * It takes an already-introspected schema IR and compares it against\n * the contract requirements.\n *\n * @param options - Verification options\n * @returns VerifyDatabaseSchemaResult with verification tree and issues\n */\nexport function verifySqlSchema(options: VerifySqlSchemaOptions): VerifyDatabaseSchemaResult {\n const {\n contract,\n schema,\n strict,\n context,\n typeMetadataRegistry,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const startTime = Date.now();\n\n // Extract codec control hooks once at entry point for reuse\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n\n const { contractStorageHash, contractProfileHash, contractTarget } =\n extractContractMetadata(contract);\n const storageTypes = contract.storage.types ?? {};\n const { issues, rootChildren } = verifySchemaTables({\n contract,\n schema,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n });\n\n validateFrameworkComponentsForExtensions(contract, options.frameworkComponents);\n\n // Verify storage type instances via codec control hooks (pure, deterministic)\n const storageTypeEntries = Object.entries(storageTypes);\n if (storageTypeEntries.length > 0) {\n const typeNodes: SchemaVerificationNode[] = [];\n for (const [typeName, typeInstance] of storageTypeEntries) {\n const hook = codecHooks.get(typeInstance.codecId);\n const typeIssues = hook?.verifyType\n ? hook.verifyType({ typeName, typeInstance, schema })\n : [];\n if (typeIssues.length > 0) {\n issues.push(...typeIssues);\n }\n const typeStatus = typeIssues.length > 0 ? 'fail' : 'pass';\n const typeCode = typeIssues.length > 0 ? (typeIssues[0]?.kind ?? '') : '';\n typeNodes.push({\n status: typeStatus,\n kind: 'storageType',\n name: `type ${typeName}`,\n contractPath: `storage.types.${typeName}`,\n code: typeCode,\n message:\n typeIssues.length > 0\n ? `${typeIssues.length} issue${typeIssues.length === 1 ? '' : 's'}`\n : '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n const typesStatus = typeNodes.some((n) => n.status === 'fail') ? 'fail' : 'pass';\n rootChildren.push({\n status: typesStatus,\n kind: 'storageTypes',\n name: 'types',\n contractPath: 'storage.types',\n code: typesStatus === 'fail' ? 'type_mismatch' : '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: typeNodes,\n });\n }\n\n const databaseDependencies = collectInitDependencies(options.frameworkComponents);\n const dependencyStatuses = verifyDatabaseDependencies(databaseDependencies, schema, issues);\n rootChildren.push(...dependencyStatuses);\n\n const root = buildRootNode(rootChildren);\n\n // Compute counts\n const counts = computeCounts(root);\n\n // Set ok flag\n const ok = counts.fail === 0;\n\n // Set code\n const code = ok ? undefined : 'PN-SCHEMA-0001';\n\n // Set summary\n const summary = ok\n ? 'Database schema satisfies contract'\n : `Database schema does not satisfy contract (${counts.fail} failure${counts.fail === 1 ? '' : 's'})`;\n\n const totalTime = Date.now() - startTime;\n\n return {\n ok,\n ...ifDefined('code', code),\n summary,\n contract: {\n storageHash: contractStorageHash,\n ...ifDefined('profileHash', contractProfileHash),\n },\n target: {\n expected: contractTarget,\n actual: contractTarget,\n },\n schema: {\n issues,\n root,\n counts,\n },\n meta: {\n strict,\n ...ifDefined('contractPath', context?.contractPath),\n ...ifDefined('configPath', context?.configPath),\n },\n timings: {\n total: totalTime,\n },\n };\n}\n\ntype VerificationStatus = 'pass' | 'warn' | 'fail';\n\nfunction extractContractMetadata(contract: Contract<SqlStorage>): {\n contractStorageHash: SqlStorage['storageHash'];\n contractProfileHash?: Contract<SqlStorage>['profileHash'] | undefined;\n contractTarget: Contract<SqlStorage>['target'];\n} {\n return {\n contractStorageHash: contract.storage.storageHash,\n contractProfileHash:\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : undefined,\n contractTarget: contract.target,\n };\n}\n\nfunction verifySchemaTables(options: {\n contract: Contract<SqlStorage>;\n schema: SqlSchemaIR;\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Record<string, StorageTypeInstance>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n}): { issues: SchemaIssue[]; rootChildren: SchemaVerificationNode[] } {\n const {\n contract,\n schema,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const issues: SchemaIssue[] = [];\n const rootChildren: SchemaVerificationNode[] = [];\n const contractTables = contract.storage.tables;\n const schemaTables = schema.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 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 const tableChildren = verifyTableChildren({\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n });\n rootChildren.push(buildTableNode(tableName, tablePath, tableChildren));\n }\n\n if (strict) {\n for (const tableName of Object.keys(schemaTables)) {\n if (!contractTables[tableName]) {\n issues.push({\n kind: 'extra_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 return { issues, rootChildren };\n}\n\nfunction verifyTableChildren(options: {\n contractTable: Contract<SqlStorage>['storage']['tables'][string];\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n tablePath: string;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Record<string, StorageTypeInstance>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n}): SchemaVerificationNode[] {\n const {\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const tableChildren: SchemaVerificationNode[] = [];\n const columnNodes = collectContractColumnNodes({\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n });\n if (columnNodes.length > 0) {\n tableChildren.push(buildColumnsNode(tablePath, columnNodes));\n }\n if (strict) {\n appendExtraColumnNodes({\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n columnNodes,\n });\n }\n\n if (contractTable.primaryKey) {\n const pkStatus = verifyPrimaryKey(\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 issues.push({\n kind: 'extra_primary_key',\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 // Verify FK constraints only for FKs with constraint: true.\n // Always call when strict mode is on so extra-FK detection runs even if\n // the contract has no FKs for this table.\n const constraintFks = contractTable.foreignKeys.filter((fk) => fk.constraint === true);\n if (constraintFks.length > 0 || strict) {\n const fkStatuses = verifyForeignKeys(\n constraintFks,\n schemaTable.foreignKeys,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...fkStatuses);\n }\n\n const uniqueStatuses = verifyUniqueConstraints(\n contractTable.uniques,\n schemaTable.uniques,\n schemaTable.indexes,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...uniqueStatuses);\n\n // Combine user-declared indexes with FK-backing indexes (from FKs with index: true)\n // so the verifier treats FK-backing indexes as expected, not \"extra\".\n // Deduplicate: skip FK-backing indexes already covered by a user-declared index.\n const fkBackingIndexes = contractTable.foreignKeys\n .filter(\n (fk) =>\n fk.index === true &&\n !contractTable.indexes.some((idx) => arraysEqual(idx.columns, fk.columns)),\n )\n .map((fk) => ({ columns: fk.columns }));\n const allExpectedIndexes = [...contractTable.indexes, ...fkBackingIndexes];\n\n const indexStatuses = verifyIndexes(\n allExpectedIndexes,\n schemaTable.indexes,\n schemaTable.uniques,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...indexStatuses);\n\n return tableChildren;\n}\n\nfunction collectContractColumnNodes(options: {\n contractTable: Contract<SqlStorage>['storage']['tables'][string];\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n tablePath: string;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Record<string, StorageTypeInstance>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n}): SchemaVerificationNode[] {\n const {\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const columnNodes: SchemaVerificationNode[] = [];\n\n for (const [columnName, contractColumn] of Object.entries(contractTable.columns)) {\n const schemaColumn = schemaTable.columns[columnName];\n const columnPath = `${tablePath}.columns.${columnName}`;\n\n if (!schemaColumn) {\n 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 columnNodes.push(\n verifyColumn({\n tableName,\n columnName,\n contractColumn,\n schemaColumn,\n columnPath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n }),\n );\n }\n\n return columnNodes;\n}\n\nfunction appendExtraColumnNodes(options: {\n contractTable: Contract<SqlStorage>['storage']['tables'][string];\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n tablePath: string;\n issues: SchemaIssue[];\n columnNodes: SchemaVerificationNode[];\n}): void {\n const { contractTable, schemaTable, tableName, tablePath, issues, columnNodes } = options;\n for (const [columnName, { nativeType }] of Object.entries(schemaTable.columns)) {\n if (!contractTable.columns[columnName]) {\n issues.push({\n kind: 'extra_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: nativeType,\n children: [],\n });\n }\n }\n}\n\nfunction verifyColumn(options: {\n tableName: string;\n columnName: string;\n contractColumn: Contract<SqlStorage>['storage']['tables'][string]['columns'][string];\n schemaColumn: SqlSchemaIR['tables'][string]['columns'][string];\n columnPath: string;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Record<string, StorageTypeInstance>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n}): SchemaVerificationNode {\n const {\n tableName,\n columnName,\n contractColumn,\n schemaColumn,\n columnPath,\n issues,\n strict,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const columnChildren: SchemaVerificationNode[] = [];\n let columnStatus: VerificationStatus = 'pass';\n\n const resolvedContractColumn = resolveContractColumnTypeMetadata(contractColumn, storageTypes, {\n tableName,\n columnName,\n });\n const contractNativeType = renderExpectedNativeType(contractColumn, storageTypes, codecHooks, {\n tableName,\n columnName,\n });\n const schemaNativeType =\n normalizeNativeType?.(schemaColumn.nativeType) ?? schemaColumn.nativeType;\n\n if (contractNativeType !== schemaNativeType) {\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 if (resolvedContractColumn.codecId) {\n const typeMetadata = options.typeMetadataRegistry.get(resolvedContractColumn.codecId);\n if (!typeMetadata) {\n columnChildren.push({\n status: 'warn',\n kind: 'type',\n name: 'type_metadata_missing',\n contractPath: `${columnPath}.codecId`,\n code: 'type_metadata_missing',\n message: `codecId \"${resolvedContractColumn.codecId}\" not found in type metadata registry`,\n expected: resolvedContractColumn.codecId,\n actual: undefined,\n children: [],\n });\n } else if (\n typeMetadata.nativeType &&\n typeMetadata.nativeType !== resolvedContractColumn.nativeType\n ) {\n columnChildren.push({\n status: 'warn',\n kind: 'type',\n name: 'type_consistency',\n contractPath: `${columnPath}.codecId`,\n code: 'type_consistency_warning',\n message: `codecId \"${resolvedContractColumn.codecId}\" maps to nativeType \"${typeMetadata.nativeType}\" in registry, but contract has \"${resolvedContractColumn.nativeType}\"`,\n expected: typeMetadata.nativeType,\n actual: resolvedContractColumn.nativeType,\n children: [],\n });\n }\n }\n\n if (contractColumn.nullable !== schemaColumn.nullable) {\n 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 if (contractColumn.default) {\n if (!schemaColumn.default) {\n const defaultDescription = describeColumnDefault(contractColumn.default);\n issues.push({\n kind: 'default_missing',\n table: tableName,\n column: columnName,\n expected: defaultDescription,\n message: `Column \"${tableName}\".\"${columnName}\" should have default ${defaultDescription} but database has no default`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'default_missing',\n message: `Default missing: expected ${defaultDescription}`,\n expected: defaultDescription,\n actual: undefined,\n children: [],\n });\n columnStatus = 'fail';\n } else if (\n !columnDefaultsEqual(\n contractColumn.default,\n schemaColumn.default,\n normalizeDefault,\n schemaNativeType,\n )\n ) {\n const expectedDescription = describeColumnDefault(contractColumn.default);\n // schemaColumn.default is now a raw string, describe it as-is\n const actualDescription = schemaColumn.default;\n issues.push({\n kind: 'default_mismatch',\n table: tableName,\n column: columnName,\n expected: expectedDescription,\n actual: actualDescription,\n message: `Column \"${tableName}\".\"${columnName}\" has default mismatch: expected ${expectedDescription}, got ${actualDescription}`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'default_mismatch',\n message: `Default mismatch: expected ${expectedDescription}, got ${actualDescription}`,\n expected: expectedDescription,\n actual: actualDescription,\n children: [],\n });\n columnStatus = 'fail';\n }\n } else if (strict && schemaColumn.default) {\n issues.push({\n kind: 'extra_default',\n table: tableName,\n column: columnName,\n actual: schemaColumn.default,\n message: `Column \"${tableName}\".\"${columnName}\" has default ${schemaColumn.default} in database but contract specifies no default`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'extra_default',\n message: `Extra default: ${schemaColumn.default}`,\n expected: undefined,\n actual: schemaColumn.default,\n children: [],\n });\n columnStatus = 'fail';\n }\n\n // Single-pass aggregation for better performance\n const aggregated = aggregateChildState(columnChildren, columnStatus);\n const nullableText = contractColumn.nullable ? 'nullable' : 'not nullable';\n const columnTypeDisplay = resolvedContractColumn.codecId\n ? `${contractNativeType} (${resolvedContractColumn.codecId})`\n : contractNativeType;\n const columnMessage = aggregated.failureMessages.join('; ');\n\n return {\n status: aggregated.status,\n kind: 'column',\n name: `${columnName}: ${columnTypeDisplay} (${nullableText})`,\n contractPath: columnPath,\n code: aggregated.firstCode,\n message: columnMessage,\n expected: undefined,\n actual: undefined,\n children: columnChildren,\n };\n}\n\nfunction buildColumnsNode(\n tablePath: string,\n columnNodes: SchemaVerificationNode[],\n): SchemaVerificationNode {\n return {\n status: aggregateChildState(columnNodes, 'pass').status,\n kind: 'columns',\n name: 'columns',\n contractPath: `${tablePath}.columns`,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: columnNodes,\n };\n}\n\nfunction buildTableNode(\n tableName: string,\n tablePath: string,\n tableChildren: SchemaVerificationNode[],\n): SchemaVerificationNode {\n const tableStatus = aggregateChildState(tableChildren, 'pass').status;\n const tableFailureMessages = tableChildren\n .filter((child) => child.status === 'fail' && child.message)\n .map((child) => child.message)\n .filter((msg): msg is string => typeof msg === 'string' && msg.length > 0);\n const tableMessage =\n tableStatus === 'fail' && tableFailureMessages.length > 0\n ? `${tableFailureMessages.length} issue${tableFailureMessages.length === 1 ? '' : 's'}`\n : '';\n const tableCode =\n tableStatus === 'fail' && tableChildren.length > 0 && tableChildren[0]\n ? tableChildren[0].code\n : '';\n\n return {\n status: tableStatus,\n kind: 'table',\n name: `table ${tableName}`,\n contractPath: tablePath,\n code: tableCode,\n message: tableMessage,\n expected: undefined,\n actual: undefined,\n children: tableChildren,\n };\n}\n\nfunction buildRootNode(rootChildren: SchemaVerificationNode[]): SchemaVerificationNode {\n return {\n status: aggregateChildState(rootChildren, 'pass').status,\n kind: 'contract',\n name: 'contract',\n contractPath: '',\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: rootChildren,\n };\n}\n\n/**\n * Aggregated state from child nodes, computed in a single pass.\n */\ninterface AggregatedChildState {\n readonly status: VerificationStatus;\n readonly failureMessages: readonly string[];\n readonly firstCode: string;\n}\n\n/**\n * Aggregates status, failure messages, and code from children in a single pass.\n * This is more efficient than calling separate functions that each iterate the array.\n */\nfunction aggregateChildState(\n children: SchemaVerificationNode[],\n fallback: VerificationStatus,\n): AggregatedChildState {\n let status: VerificationStatus = fallback;\n const failureMessages: string[] = [];\n let firstCode = '';\n\n for (const child of children) {\n if (child.status === 'fail') {\n status = 'fail';\n if (!firstCode) {\n firstCode = child.code;\n }\n if (child.message && typeof child.message === 'string' && child.message.length > 0) {\n failureMessages.push(child.message);\n }\n } else if (child.status === 'warn' && status !== 'fail') {\n status = 'warn';\n if (!firstCode) {\n firstCode = child.code;\n }\n }\n }\n\n return { status, failureMessages, firstCode };\n}\n\nfunction validateFrameworkComponentsForExtensions(\n contract: Contract<SqlStorage>,\n frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n): void {\n const contractExtensionPacks = contract.extensionPacks ?? {};\n for (const extensionNamespace of Object.keys(contractExtensionPacks)) {\n const hasComponent = frameworkComponents.some(\n (component) =>\n component.id === extensionNamespace &&\n (component.kind === 'extension' ||\n component.kind === 'adapter' ||\n component.kind === 'target'),\n );\n if (!hasComponent) {\n throw new Error(\n `Extension pack '${extensionNamespace}' is declared in the contract but not found in framework components. ` +\n 'This indicates a configuration mismatch - the contract was emitted with this extension pack, ' +\n 'but it is not provided in the current configuration.',\n );\n }\n }\n}\n\n/**\n * Renders the expected native type for a contract column, expanding parameterized types\n * using codec control hooks when available.\n *\n * This function delegates to the `expandNativeType` hook if the codec provides one,\n * ensuring that the SQL family layer remains dialect-agnostic while allowing\n * target-specific adapters (like Postgres) to provide their own expansion logic.\n */\nfunction renderExpectedNativeType(\n contractColumn: Contract<SqlStorage>['storage']['tables'][string]['columns'][string],\n storageTypes: Record<string, StorageTypeInstance>,\n codecHooks: Map<string, CodecControlHooks>,\n context?: {\n readonly tableName: string;\n readonly columnName: string;\n },\n): string {\n const { codecId, nativeType, typeParams } = resolveContractColumnTypeMetadata(\n contractColumn,\n storageTypes,\n context,\n );\n\n // If no typeParams or codecId, return the base native type\n if (!typeParams || !codecId) {\n return nativeType;\n }\n\n // Try to use the codec's expandNativeType hook if available\n const hooks = codecHooks.get(codecId);\n if (hooks?.expandNativeType) {\n return hooks.expandNativeType({ nativeType, codecId, typeParams });\n }\n\n // Fallback: return base native type if no hook is available\n return nativeType;\n}\n\nfunction resolveContractColumnTypeMetadata(\n contractColumn: StorageColumn,\n storageTypes: Record<string, StorageTypeInstance>,\n context?: {\n readonly tableName: string;\n readonly columnName: string;\n },\n): Pick<StorageColumn, 'codecId' | 'nativeType' | 'typeParams'> {\n if (!contractColumn.typeRef) {\n return contractColumn;\n }\n\n const referencedType = storageTypes[contractColumn.typeRef];\n if (!referencedType) {\n const columnLabel = context\n ? `Column \"${context.tableName}\".\"${context.columnName}\"`\n : 'Column';\n throw new Error(\n `${columnLabel} references storage type \"${contractColumn.typeRef}\" but it is not defined in storage.types.`,\n );\n }\n\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: referencedType.typeParams,\n };\n}\n\n/**\n * Describes a column default for display purposes.\n */\nfunction describeColumnDefault(columnDefault: ColumnDefault): string {\n switch (columnDefault.kind) {\n case 'literal':\n return `literal(${formatLiteralValue(columnDefault.value)})`;\n case 'function':\n return columnDefault.expression;\n }\n}\n\n/**\n * Compares a contract ColumnDefault against a schema raw default string for semantic equality.\n *\n * When a normalizer is provided, the raw schema default is first normalized to a ColumnDefault\n * before comparison. Without a normalizer, falls back to direct string comparison against\n * the contract expression.\n *\n * @param contractDefault - The expected default from the contract (normalized ColumnDefault)\n * @param schemaDefault - The raw default expression from the database (string)\n * @param normalizer - Optional target-specific normalizer to convert raw defaults\n * @param nativeType - The column's native type, passed to normalizer for context\n */\nfunction columnDefaultsEqual(\n contractDefault: ColumnDefault,\n schemaDefault: string,\n normalizer?: DefaultNormalizer,\n nativeType?: string,\n): boolean {\n // If no normalizer provided, fall back to direct string comparison\n if (!normalizer) {\n if (contractDefault.kind === 'function') {\n return contractDefault.expression === schemaDefault;\n }\n const normalizedValue = normalizeLiteralValue(contractDefault.value, nativeType);\n if (typeof normalizedValue === 'string') {\n return normalizedValue === schemaDefault || `'${normalizedValue}'` === schemaDefault;\n }\n return String(normalizedValue) === schemaDefault;\n }\n\n // Normalize the raw schema default using target-specific logic\n const normalizedSchema = normalizer(schemaDefault, nativeType ?? '');\n if (!normalizedSchema) {\n // Normalizer couldn't parse the expression - treat as mismatch\n return false;\n }\n\n // Compare normalized defaults\n if (contractDefault.kind !== normalizedSchema.kind) {\n return false;\n }\n if (contractDefault.kind === 'literal' && normalizedSchema.kind === 'literal') {\n const contractValue = normalizeLiteralValue(contractDefault.value, nativeType);\n const schemaValue = normalizeLiteralValue(normalizedSchema.value, nativeType);\n return literalValuesEqual(contractValue, schemaValue);\n }\n if (contractDefault.kind === 'function' && normalizedSchema.kind === 'function') {\n // Normalize function expressions for comparison (case-insensitive, whitespace-tolerant)\n const normalizeExpr = (expr: string) => expr.toLowerCase().replace(/\\s+/g, '');\n return normalizeExpr(contractDefault.expression) === normalizeExpr(normalizedSchema.expression);\n }\n return false;\n}\n\nfunction isTemporalNativeType(nativeType?: string): boolean {\n if (!nativeType) return false;\n const normalized = nativeType.toLowerCase();\n return normalized.includes('timestamp') || normalized === 'date';\n}\n\nfunction normalizeLiteralValue(value: unknown, nativeType?: string): unknown {\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'string' && isTemporalNativeType(nativeType)) {\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed.toISOString();\n }\n }\n return value;\n}\n\n/**\n * Recursively sorts object keys for deterministic JSON comparison.\n * Postgres jsonb may canonicalize key order, so two semantically equal\n * objects can have different key insertion order.\n */\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, (_key, val) => {\n if (val !== null && typeof val === 'object' && !Array.isArray(val)) {\n const sorted: Record<string, unknown> = {};\n for (const k of Object.keys(val as Record<string, unknown>).sort()) {\n sorted[k] = (val as Record<string, unknown>)[k];\n }\n return sorted;\n }\n return val;\n });\n}\n\nfunction literalValuesEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a === 'object' && a !== null && typeof b === 'object' && b !== null) {\n return stableStringify(a) === stableStringify(b);\n }\n if (typeof a === 'object' && a !== null && typeof b === 'string') {\n try {\n return stableStringify(a) === stableStringify(JSON.parse(b));\n } catch {\n return false;\n }\n }\n if (typeof a === 'string' && typeof b === 'object' && b !== null) {\n try {\n return stableStringify(JSON.parse(a)) === stableStringify(b);\n } catch {\n return false;\n }\n }\n return false;\n}\n\nfunction formatLiteralValue(value: unknown): string {\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'string') {\n return value;\n }\n return JSON.stringify(value);\n}\n"],"mappings":";;;;AAMA,SAAS,qBAAqB,YAO5B;AACA,KAAI,OAAO,eAAe,YAAY,eAAe,KACnD,QAAO;CAGT,MAAM,QADI,WACM,OAAO,YAAY;AACnC,QAAO,UAAU,QAAQ,UAAU,UAAa,OAAO,UAAU;;AAGnE,SAAgB,yBACd,aACgC;CAChC,MAAM,wBAAQ,IAAI,KAAgC;CAClD,MAAM,yBAAS,IAAI,KAAqB;AAExC,MAAK,MAAM,cAAc,aAAa;AACpC,MAAI,OAAO,eAAe,YAAY,eAAe,KACnD;AAEF,MAAI,CAAC,qBAAqB,WAAW,CACnC;EAEF,MAAM,oBAAoB,WAAW,MAAM,WAAW;AACtD,OAAK,MAAM,CAAC,SAAS,SAAS,OAAO,QAAQ,kBAAkB,EAAE;AAC/D,0BAAuB;IACrB;IACA;IACA,cAAc,WAAW;IACzB,aAAa;IACb,sBAAsB;IACvB,CAAC;AACF,SAAM,IAAI,SAAS,KAAK;AACxB,UAAO,IAAI,SAAS,WAAW,GAAG;;;AAItC,QAAO;;;;;ACPT,SAAgB,6BAA6B,OAAqD;AAChG,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,0BAA0B;;AAGlF,SAAgB,wBACd,YACiD;CACjD,MAAMA,SAAiD,EAAE;AACzD,MAAK,MAAM,aAAa,YAAY;AAClC,MAAI,CAAC,6BAA6B,UAAU,CAAE;EAC9C,MAAM,OAAO,UAAU,sBAAsB;AAC7C,MAAI,CAAC,KAAM;AACX,SAAO,KAAK,GAAG,KAAK;;AAEtB,QAAO;;;;;;;;AC9BT,SAAgB,YAAY,GAAsB,GAA+B;AAC/E,KAAI,EAAE,WAAW,EAAE,OACjB,QAAO;AAET,MAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAC5B,KAAI,EAAE,OAAO,EAAE,GACb,QAAO;AAGX,QAAO;;;;;;;;;;;;;;AAsBT,SAAgB,4BACd,SACA,SACA,SACS;AAGT,KADsB,QAAQ,MAAM,WAAW,YAAY,OAAO,SAAS,QAAQ,CAAC,CAElF,QAAO;AAGT,QAAO,QAAQ,MAAM,UAAU,MAAM,UAAU,YAAY,MAAM,SAAS,QAAQ,CAAC;;;;;;;;;;;;;;AAerF,SAAgB,iBACd,SACA,SACA,SACS;AAGT,KADyB,QAAQ,MAAM,UAAU,YAAY,MAAM,SAAS,QAAQ,CAAC,CAEnF,QAAO;AAGT,QAAO,QAAQ,MAAM,WAAW,YAAY,OAAO,SAAS,QAAQ,CAAC;;;;;;;;;AAUvE,SAAgB,iBACd,YACA,UACA,WACA,QACiB;AACjB,KAAI,CAAC,UAAU;AACb,SAAO,KAAK;GACV,MAAM;GACN,OAAO;GACP,UAAU,WAAW,QAAQ,KAAK,KAAK;GACvC,SAAS,UAAU,UAAU;GAC9B,CAAC;AACF,SAAO;;AAGT,KAAI,CAAC,YAAY,WAAW,SAAS,SAAS,QAAQ,EAAE;AACtD,SAAO,KAAK;GACV,MAAM;GACN,OAAO;GACP,UAAU,WAAW,QAAQ,KAAK,KAAK;GACvC,QAAQ,SAAS,QAAQ,KAAK,KAAK;GACnC,SAAS,UAAU,UAAU,gDAAgD,WAAW,QAAQ,KAAK,KAAK,CAAC,UAAU,SAAS,QAAQ,KAAK,KAAK,CAAC;GAClJ,CAAC;AACF,SAAO;;AAMT,QAAO;;;;;;;;;AAUT,SAAgB,kBACd,aACA,WACA,WACA,WACA,QACA,QAC0B;CAC1B,MAAMC,QAAkC,EAAE;AAG1C,MAAK,MAAM,cAAc,aAAa;EACpC,MAAM,SAAS,GAAG,UAAU,eAAe,WAAW,QAAQ,KAAK,IAAI,CAAC;EACxE,MAAM,aAAa,UAAU,MAAM,OAAO;AACxC,UACE,YAAY,GAAG,SAAS,WAAW,QAAQ,IAC3C,GAAG,oBAAoB,WAAW,WAAW,SAC7C,YAAY,GAAG,mBAAmB,WAAW,WAAW,QAAQ;IAElE;AAEF,MAAI,CAAC,YAAY;AACf,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,UAAU,GAAG,WAAW,QAAQ,KAAK,KAAK,CAAC,MAAM,WAAW,WAAW,MAAM,GAAG,WAAW,WAAW,QAAQ,KAAK,KAAK,CAAC;IACzH,SAAS,UAAU,UAAU,4BAA4B,WAAW,QAAQ,KAAK,KAAK,CAAC,MAAM,WAAW,WAAW,MAAM,GAAG,WAAW,WAAW,QAAQ,KAAK,KAAK,CAAC;IACtK,CAAC;AACF,SAAM,KAAK;IACT,QAAQ;IACR,MAAM;IACN,MAAM,cAAc,WAAW,QAAQ,KAAK,KAAK,CAAC;IAClD,cAAc;IACd,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;SACG;GACL,MAAM,mBAAmB,+BAA+B,YAAY,WAAW;AAC/E,OAAI,iBAAiB,SAAS,GAAG;IAC/B,MAAM,kBAAkB,iBAAiB,KAAK,MAAM,EAAE,QAAQ,CAAC,KAAK,KAAK;IACzE,MAAM,mBAAmB,iBAAiB,KAAK,MAAM,EAAE,SAAS,CAAC,KAAK,KAAK;IAC3E,MAAM,iBAAiB,iBAAiB,KAAK,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK;AACvE,WAAO,KAAK;KACV,MAAM;KACN,OAAO;KAGP,mBAAmB,WAAW,QAAQ,MAAM,WAAW,QAAQ,KAAK,IAAI,CAAC;KACzE,UAAU;KACV,QAAQ;KACR,SAAS,UAAU,UAAU,gBAAgB,WAAW,QAAQ,KAAK,KAAK,CAAC,MAAM,WAAW,WAAW,MAAM,IAAI;KAClH,CAAC;AACF,UAAM,KAAK;KACT,QAAQ;KACR,MAAM;KACN,MAAM,cAAc,WAAW,QAAQ,KAAK,KAAK,CAAC;KAClD,cAAc;KACd,MAAM;KACN,SAAS;KACT,UAAU;KACV,QAAQ;KACR,UAAU,EAAE;KACb,CAAC;SAEF,OAAM,KAAK;IACT,QAAQ;IACR,MAAM;IACN,MAAM,cAAc,WAAW,QAAQ,KAAK,KAAK,CAAC;IAClD,cAAc;IACd,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;;;AAMR,KAAI,QACF;OAAK,MAAM,YAAY,UASrB,KAAI,CARe,YAAY,MAAM,OAAO;AAC1C,UACE,YAAY,GAAG,SAAS,SAAS,QAAQ,IACzC,GAAG,WAAW,UAAU,SAAS,mBACjC,YAAY,GAAG,WAAW,SAAS,SAAS,kBAAkB;IAEhE,EAEe;AACf,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,mBAAmB,SAAS,QAAQ,MAAM,SAAS,QAAQ,KAAK,IAAI,CAAC;IACrE,SAAS,0DAA0D,SAAS,QAAQ,KAAK,KAAK,CAAC,MAAM,SAAS,gBAAgB,GAAG,SAAS,kBAAkB,KAAK,KAAK,CAAC;IACxK,CAAC;AACF,SAAM,KAAK;IACT,QAAQ;IACR,MAAM;IACN,MAAM,cAAc,SAAS,QAAQ,KAAK,KAAK,CAAC;IAChD,cAAc,GAAG,UAAU,eAAe,SAAS,QAAQ,KAAK,IAAI,CAAC;IACrE,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;;;AAKR,QAAO;;;;;;;;;;;;;AAcT,SAAgB,wBACd,iBACA,eACA,eACA,WACA,WACA,QACA,QAC0B;CAC1B,MAAMA,QAAkC,EAAE;AAG1C,MAAK,MAAM,kBAAkB,iBAAiB;EAC5C,MAAM,aAAa,GAAG,UAAU,WAAW,eAAe,QAAQ,KAAK,IAAI,CAAC;EAG5E,MAAM,iBAAiB,cAAc,MAAM,MACzC,YAAY,EAAE,SAAS,eAAe,QAAQ,CAC/C;EAGD,MAAM,sBACJ,CAAC,kBACD,cAAc,MAAM,QAAQ,IAAI,UAAU,YAAY,IAAI,SAAS,eAAe,QAAQ,CAAC;AAE7F,MAAI,CAAC,kBAAkB,CAAC,qBAAqB;AAC3C,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,UAAU,eAAe,QAAQ,KAAK,KAAK;IAC3C,SAAS,UAAU,UAAU,kCAAkC,eAAe,QAAQ,KAAK,KAAK;IACjG,CAAC;AACF,SAAM,KAAK;IACT,QAAQ;IACR,MAAM;IACN,MAAM,UAAU,eAAe,QAAQ,KAAK,KAAK,CAAC;IAClD,cAAc;IACd,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;QAIF,OAAM,KAAK;GACT,QAAQ;GACR,MAAM;GACN,MAAM,UAAU,eAAe,QAAQ,KAAK,KAAK,CAAC;GAClD,cAAc;GACd,MAAM;GACN,SAAS;GACT,UAAU;GACV,QAAQ;GACR,UAAU,EAAE;GACb,CAAC;;AAKN,KAAI,QACF;OAAK,MAAM,gBAAgB,cAKzB,KAAI,CAJmB,gBAAgB,MAAM,MAC3C,YAAY,EAAE,SAAS,aAAa,QAAQ,CAC7C,EAEoB;AACnB,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,mBAAmB,aAAa,QAAQ,UAAU,aAAa,QAAQ,KAAK,IAAI,CAAC;IACjF,SAAS,gEAAgE,aAAa,QAAQ,KAAK,KAAK;IACzG,CAAC;AACF,SAAM,KAAK;IACT,QAAQ;IACR,MAAM;IACN,MAAM,UAAU,aAAa,QAAQ,KAAK,KAAK,CAAC;IAChD,cAAc,GAAG,UAAU,WAAW,aAAa,QAAQ,KAAK,IAAI,CAAC;IACrE,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;;;AAKR,QAAO;;;;;;;;;;;;;AAcT,SAAgB,cACd,iBACA,eACA,eACA,WACA,WACA,QACA,QAC0B;CAC1B,MAAMA,QAAkC,EAAE;AAG1C,MAAK,MAAM,iBAAiB,iBAAiB;EAC3C,MAAM,YAAY,GAAG,UAAU,WAAW,cAAc,QAAQ,KAAK,IAAI,CAAC;EAI1E,MAAM,gBAAgB,cAAc,MAAM,QACxC,YAAY,IAAI,SAAS,cAAc,QAAQ,CAChD;EAGD,MAAM,2BACJ,CAAC,iBAAiB,cAAc,MAAM,MAAM,YAAY,EAAE,SAAS,cAAc,QAAQ,CAAC;AAE5F,MAAI,CAAC,iBAAiB,CAAC,0BAA0B;AAC/C,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,UAAU,cAAc,QAAQ,KAAK,KAAK;IAC1C,SAAS,UAAU,UAAU,sBAAsB,cAAc,QAAQ,KAAK,KAAK;IACpF,CAAC;AACF,SAAM,KAAK;IACT,QAAQ;IACR,MAAM;IACN,MAAM,SAAS,cAAc,QAAQ,KAAK,KAAK,CAAC;IAChD,cAAc;IACd,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;QAIF,OAAM,KAAK;GACT,QAAQ;GACR,MAAM;GACN,MAAM,SAAS,cAAc,QAAQ,KAAK,KAAK,CAAC;GAChD,cAAc;GACd,MAAM;GACN,SAAS;GACT,UAAU;GACV,QAAQ;GACR,UAAU,EAAE;GACb,CAAC;;AAKN,KAAI,OACF,MAAK,MAAM,eAAe,eAAe;AAEvC,MAAI,YAAY,OACd;AAOF,MAAI,CAJkB,gBAAgB,MAAM,QAC1C,YAAY,IAAI,SAAS,YAAY,QAAQ,CAC9C,EAEmB;AAClB,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,mBAAmB,YAAY,QAAQ,OAAO,YAAY,QAAQ,KAAK,IAAI,CAAC;IAC5E,SAAS,oDAAoD,YAAY,QAAQ,KAAK,KAAK;IAC5F,CAAC;AACF,SAAM,KAAK;IACT,QAAQ;IACR,MAAM;IACN,MAAM,SAAS,YAAY,QAAQ,KAAK,KAAK,CAAC;IAC9C,cAAc,GAAG,UAAU,WAAW,YAAY,QAAQ,KAAK,IAAI,CAAC;IACpE,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;;;AAKR,QAAO;;;;;;;;;AAUT,SAAgB,2BACd,cACA,QACA,QAC0B;CAC1B,MAAMA,QAAkC,EAAE;CAC1C,MAAM,eAAe,IAAI,IAAI,OAAO,aAAa,KAAK,MAAM,EAAE,GAAG,CAAC;AAElE,MAAK,MAAM,cAAc,cAAc;EACrC,MAAM,cAAc,aAAa,IAAI,WAAW,GAAG;EACnD,MAAM,UAAU,gBAAgB,WAAW;AAE3C,MAAI,CAAC,aAAa;GAChB,MAAMC,WAAwB;IAC5B,MAAM;IACN,cAAc,WAAW;IACzB,SAAS,eAAe,WAAW,GAAG;IACvC;AACD,UAAO,KAAK,SAAS;GACrB,MAAM,cAAc,SAAS;AAC7B,SAAM,KAAK;IACT,QAAQ;IACR,MAAM;IACN,MAAM,WAAW;IACjB,cAAc;IACd,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;QAGF,OAAM,KAAK;GACT,QAAQ;GACR,MAAM;GACN,MAAM,WAAW;GACjB,cAAc;GACd,MAAM;GACN,SAAS;GACT,UAAU;GACV,QAAQ;GACR,UAAU,EAAE;GACb,CAAC;;AAIN,QAAO;;;;;AAMT,SAAgB,cAAc,MAK5B;CACA,IAAI,OAAO;CACX,IAAI,OAAO;CACX,IAAI,OAAO;CAEX,SAAS,SAAS,GAAiC;AACjD,MAAI,EAAE,WAAW,OACf;WACS,EAAE,WAAW,OACtB;WACS,EAAE,WAAW,OACtB;AAGF,MAAI,EAAE,SACJ,MAAK,MAAM,SAAS,EAAE,SACpB,UAAS,MAAM;;AAKrB,UAAS,KAAK;AAEd,QAAO;EACL;EACA;EACA;EACA,YAAY,OAAO,OAAO;EAC3B;;;;;;;;;;;AAYH,SAAS,+BACP,YACA,UACsE;CACtE,MAAMC,aAA2E,EAAE;CAEnF,MAAM,mBAAmB,2BAA2B,WAAW,SAAS;CACxE,MAAM,iBAAiB,2BAA2B,SAAS,SAAS;AACpE,KAAI,qBAAqB,UAAa,qBAAqB,eACzD,YAAW,KAAK;EACd,UAAU,aAAa,WAAW;EAClC,QAAQ,aAAa,SAAS,YAAY;EAC1C,SAAS,+BAA+B,WAAW,SAAS,QAAQ,SAAS,YAAY;EAC1F,CAAC;CAGJ,MAAM,mBAAmB,2BAA2B,WAAW,SAAS;CACxE,MAAM,iBAAiB,2BAA2B,SAAS,SAAS;AACpE,KAAI,qBAAqB,UAAa,qBAAqB,eACzD,YAAW,KAAK;EACd,UAAU,aAAa,WAAW;EAClC,QAAQ,aAAa,SAAS,YAAY;EAC1C,SAAS,+BAA+B,WAAW,SAAS,QAAQ,SAAS,YAAY;EAC1F,CAAC;AAGJ,QAAO;;;;;;AAOT,SAAS,2BAA2B,QAAgD;AAClF,QAAO,WAAW,aAAa,SAAY;;;;;;;;;;;;;;;ACtgB7C,SAAgB,gBAAgB,SAA6D;CAC3F,MAAM,EACJ,UACA,QACA,QACA,SACA,sBACA,kBACA,wBACE;CACJ,MAAM,YAAY,KAAK,KAAK;CAG5B,MAAM,aAAa,yBAAyB,QAAQ,oBAAoB;CAExE,MAAM,EAAE,qBAAqB,qBAAqB,mBAChD,wBAAwB,SAAS;CACnC,MAAM,eAAe,SAAS,QAAQ,SAAS,EAAE;CACjD,MAAM,EAAE,QAAQ,iBAAiB,mBAAmB;EAClD;EACA;EACA;EACA;EACA;EACA;EACA,GAAG,UAAU,oBAAoB,iBAAiB;EAClD,GAAG,UAAU,uBAAuB,oBAAoB;EACzD,CAAC;AAEF,0CAAyC,UAAU,QAAQ,oBAAoB;CAG/E,MAAM,qBAAqB,OAAO,QAAQ,aAAa;AACvD,KAAI,mBAAmB,SAAS,GAAG;EACjC,MAAMC,YAAsC,EAAE;AAC9C,OAAK,MAAM,CAAC,UAAU,iBAAiB,oBAAoB;GACzD,MAAM,OAAO,WAAW,IAAI,aAAa,QAAQ;GACjD,MAAM,aAAa,MAAM,aACrB,KAAK,WAAW;IAAE;IAAU;IAAc;IAAQ,CAAC,GACnD,EAAE;AACN,OAAI,WAAW,SAAS,EACtB,QAAO,KAAK,GAAG,WAAW;GAE5B,MAAM,aAAa,WAAW,SAAS,IAAI,SAAS;GACpD,MAAM,WAAW,WAAW,SAAS,IAAK,WAAW,IAAI,QAAQ,KAAM;AACvE,aAAU,KAAK;IACb,QAAQ;IACR,MAAM;IACN,MAAM,QAAQ;IACd,cAAc,iBAAiB;IAC/B,MAAM;IACN,SACE,WAAW,SAAS,IAChB,GAAG,WAAW,OAAO,QAAQ,WAAW,WAAW,IAAI,KAAK,QAC5D;IACN,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;;EAEJ,MAAM,cAAc,UAAU,MAAM,MAAM,EAAE,WAAW,OAAO,GAAG,SAAS;AAC1E,eAAa,KAAK;GAChB,QAAQ;GACR,MAAM;GACN,MAAM;GACN,cAAc;GACd,MAAM,gBAAgB,SAAS,kBAAkB;GACjD,SAAS;GACT,UAAU;GACV,QAAQ;GACR,UAAU;GACX,CAAC;;CAIJ,MAAM,qBAAqB,2BADE,wBAAwB,QAAQ,oBAAoB,EACL,QAAQ,OAAO;AAC3F,cAAa,KAAK,GAAG,mBAAmB;CAExC,MAAM,OAAO,cAAc,aAAa;CAGxC,MAAM,SAAS,cAAc,KAAK;CAGlC,MAAM,KAAK,OAAO,SAAS;CAG3B,MAAM,OAAO,KAAK,SAAY;CAG9B,MAAM,UAAU,KACZ,uCACA,8CAA8C,OAAO,KAAK,UAAU,OAAO,SAAS,IAAI,KAAK,IAAI;CAErG,MAAM,YAAY,KAAK,KAAK,GAAG;AAE/B,QAAO;EACL;EACA,GAAG,UAAU,QAAQ,KAAK;EAC1B;EACA,UAAU;GACR,aAAa;GACb,GAAG,UAAU,eAAe,oBAAoB;GACjD;EACD,QAAQ;GACN,UAAU;GACV,QAAQ;GACT;EACD,QAAQ;GACN;GACA;GACA;GACD;EACD,MAAM;GACJ;GACA,GAAG,UAAU,gBAAgB,SAAS,aAAa;GACnD,GAAG,UAAU,cAAc,SAAS,WAAW;GAChD;EACD,SAAS,EACP,OAAO,WACR;EACF;;AAKH,SAAS,wBAAwB,UAI/B;AACA,QAAO;EACL,qBAAqB,SAAS,QAAQ;EACtC,qBACE,iBAAiB,YAAY,OAAO,SAAS,gBAAgB,WACzD,SAAS,cACT;EACN,gBAAgB,SAAS;EAC1B;;AAGH,SAAS,mBAAmB,SAS0C;CACpE,MAAM,EACJ,UACA,QACA,QACA,sBACA,YACA,cACA,kBACA,wBACE;CACJ,MAAMC,SAAwB,EAAE;CAChC,MAAMC,eAAyC,EAAE;CACjD,MAAM,iBAAiB,SAAS,QAAQ;CACxC,MAAM,eAAe,OAAO;AAE5B,MAAK,MAAM,CAAC,WAAW,kBAAkB,OAAO,QAAQ,eAAe,EAAE;EACvE,MAAM,cAAc,aAAa;EACjC,MAAM,YAAY,kBAAkB;AAEpC,MAAI,CAAC,aAAa;AAChB,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,SAAS,UAAU,UAAU;IAC9B,CAAC;AACF,gBAAa,KAAK;IAChB,QAAQ;IACR,MAAM;IACN,MAAM,SAAS;IACf,cAAc;IACd,MAAM;IACN,SAAS,UAAU,UAAU;IAC7B,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;AACF;;EAGF,MAAM,gBAAgB,oBAAoB;GACxC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,GAAG,UAAU,oBAAoB,iBAAiB;GAClD,GAAG,UAAU,uBAAuB,oBAAoB;GACzD,CAAC;AACF,eAAa,KAAK,eAAe,WAAW,WAAW,cAAc,CAAC;;AAGxE,KAAI,QACF;OAAK,MAAM,aAAa,OAAO,KAAK,aAAa,CAC/C,KAAI,CAAC,eAAe,YAAY;AAC9B,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,SAAS,gBAAgB,UAAU;IACpC,CAAC;AACF,gBAAa,KAAK;IAChB,QAAQ;IACR,MAAM;IACN,MAAM,SAAS;IACf,cAAc,kBAAkB;IAChC,MAAM;IACN,SAAS,gBAAgB,UAAU;IACnC,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;;;AAKR,QAAO;EAAE;EAAQ;EAAc;;AAGjC,SAAS,oBAAoB,SAYA;CAC3B,MAAM,EACJ,eACA,aACA,WACA,WACA,QACA,QACA,sBACA,YACA,cACA,kBACA,wBACE;CACJ,MAAMC,gBAA0C,EAAE;CAClD,MAAM,cAAc,2BAA2B;EAC7C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,GAAG,UAAU,oBAAoB,iBAAiB;EAClD,GAAG,UAAU,uBAAuB,oBAAoB;EACzD,CAAC;AACF,KAAI,YAAY,SAAS,EACvB,eAAc,KAAK,iBAAiB,WAAW,YAAY,CAAC;AAE9D,KAAI,OACF,wBAAuB;EACrB;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAGJ,KAAI,cAAc,WAOhB,KANiB,iBACf,cAAc,YACd,YAAY,YACZ,WACA,OACD,KACgB,OACf,eAAc,KAAK;EACjB,QAAQ;EACR,MAAM;EACN,MAAM,gBAAgB,cAAc,WAAW,QAAQ,KAAK,KAAK;EACjE,cAAc,GAAG,UAAU;EAC3B,MAAM;EACN,SAAS;EACT,UAAU,cAAc;EACxB,QAAQ,YAAY;EACpB,UAAU,EAAE;EACb,CAAC;KAEF,eAAc,KAAK;EACjB,QAAQ;EACR,MAAM;EACN,MAAM,gBAAgB,cAAc,WAAW,QAAQ,KAAK,KAAK;EACjE,cAAc,GAAG,UAAU;EAC3B,MAAM;EACN,SAAS;EACT,UAAU;EACV,QAAQ;EACR,UAAU,EAAE;EACb,CAAC;UAEK,YAAY,cAAc,QAAQ;AAC3C,SAAO,KAAK;GACV,MAAM;GACN,OAAO;GACP,SAAS;GACV,CAAC;AACF,gBAAc,KAAK;GACjB,QAAQ;GACR,MAAM;GACN,MAAM,gBAAgB,YAAY,WAAW,QAAQ,KAAK,KAAK;GAC/D,cAAc,GAAG,UAAU;GAC3B,MAAM;GACN,SAAS;GACT,UAAU;GACV,QAAQ,YAAY;GACpB,UAAU,EAAE;GACb,CAAC;;CAMJ,MAAM,gBAAgB,cAAc,YAAY,QAAQ,OAAO,GAAG,eAAe,KAAK;AACtF,KAAI,cAAc,SAAS,KAAK,QAAQ;EACtC,MAAM,aAAa,kBACjB,eACA,YAAY,aACZ,WACA,WACA,QACA,OACD;AACD,gBAAc,KAAK,GAAG,WAAW;;CAGnC,MAAM,iBAAiB,wBACrB,cAAc,SACd,YAAY,SACZ,YAAY,SACZ,WACA,WACA,QACA,OACD;AACD,eAAc,KAAK,GAAG,eAAe;CAKrC,MAAM,mBAAmB,cAAc,YACpC,QACE,OACC,GAAG,UAAU,QACb,CAAC,cAAc,QAAQ,MAAM,QAAQ,YAAY,IAAI,SAAS,GAAG,QAAQ,CAAC,CAC7E,CACA,KAAK,QAAQ,EAAE,SAAS,GAAG,SAAS,EAAE;CAGzC,MAAM,gBAAgB,cAFK,CAAC,GAAG,cAAc,SAAS,GAAG,iBAAiB,EAIxE,YAAY,SACZ,YAAY,SACZ,WACA,WACA,QACA,OACD;AACD,eAAc,KAAK,GAAG,cAAc;AAEpC,QAAO;;AAGT,SAAS,2BAA2B,SAYP;CAC3B,MAAM,EACJ,eACA,aACA,WACA,WACA,QACA,QACA,sBACA,YACA,cACA,kBACA,wBACE;CACJ,MAAMC,cAAwC,EAAE;AAEhD,MAAK,MAAM,CAAC,YAAY,mBAAmB,OAAO,QAAQ,cAAc,QAAQ,EAAE;EAChF,MAAM,eAAe,YAAY,QAAQ;EACzC,MAAM,aAAa,GAAG,UAAU,WAAW;AAE3C,MAAI,CAAC,cAAc;AACjB,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS,WAAW,UAAU,KAAK,WAAW;IAC/C,CAAC;AACF,eAAY,KAAK;IACf,QAAQ;IACR,MAAM;IACN,MAAM,GAAG,WAAW;IACpB,cAAc;IACd,MAAM;IACN,SAAS,WAAW,WAAW;IAC/B,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;AACF;;AAGF,cAAY,KACV,aAAa;GACX;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,GAAG,UAAU,oBAAoB,iBAAiB;GAClD,GAAG,UAAU,uBAAuB,oBAAoB;GACzD,CAAC,CACH;;AAGH,QAAO;;AAGT,SAAS,uBAAuB,SAOvB;CACP,MAAM,EAAE,eAAe,aAAa,WAAW,WAAW,QAAQ,gBAAgB;AAClF,MAAK,MAAM,CAAC,YAAY,EAAE,iBAAiB,OAAO,QAAQ,YAAY,QAAQ,CAC5E,KAAI,CAAC,cAAc,QAAQ,aAAa;AACtC,SAAO,KAAK;GACV,MAAM;GACN,OAAO;GACP,QAAQ;GACR,SAAS,iBAAiB,UAAU,KAAK,WAAW;GACrD,CAAC;AACF,cAAY,KAAK;GACf,QAAQ;GACR,MAAM;GACN,MAAM,GAAG,WAAW;GACpB,cAAc,GAAG,UAAU,WAAW;GACtC,MAAM;GACN,SAAS,iBAAiB,WAAW;GACrC,UAAU;GACV,QAAQ;GACR,UAAU,EAAE;GACb,CAAC;;;AAKR,SAAS,aAAa,SAaK;CACzB,MAAM,EACJ,WACA,YACA,gBACA,cACA,YACA,QACA,QACA,YACA,cACA,kBACA,wBACE;CACJ,MAAMC,iBAA2C,EAAE;CACnD,IAAIC,eAAmC;CAEvC,MAAM,yBAAyB,kCAAkC,gBAAgB,cAAc;EAC7F;EACA;EACD,CAAC;CACF,MAAM,qBAAqB,yBAAyB,gBAAgB,cAAc,YAAY;EAC5F;EACA;EACD,CAAC;CACF,MAAM,mBACJ,sBAAsB,aAAa,WAAW,IAAI,aAAa;AAEjE,KAAI,uBAAuB,kBAAkB;AAC3C,SAAO,KAAK;GACV,MAAM;GACN,OAAO;GACP,QAAQ;GACR,UAAU;GACV,QAAQ;GACR,SAAS,WAAW,UAAU,KAAK,WAAW,iCAAiC,mBAAmB,UAAU,iBAAiB;GAC9H,CAAC;AACF,iBAAe,KAAK;GAClB,QAAQ;GACR,MAAM;GACN,MAAM;GACN,cAAc,GAAG,WAAW;GAC5B,MAAM;GACN,SAAS,2BAA2B,mBAAmB,QAAQ;GAC/D,UAAU;GACV,QAAQ;GACR,UAAU,EAAE;GACb,CAAC;AACF,iBAAe;;AAGjB,KAAI,uBAAuB,SAAS;EAClC,MAAM,eAAe,QAAQ,qBAAqB,IAAI,uBAAuB,QAAQ;AACrF,MAAI,CAAC,aACH,gBAAe,KAAK;GAClB,QAAQ;GACR,MAAM;GACN,MAAM;GACN,cAAc,GAAG,WAAW;GAC5B,MAAM;GACN,SAAS,YAAY,uBAAuB,QAAQ;GACpD,UAAU,uBAAuB;GACjC,QAAQ;GACR,UAAU,EAAE;GACb,CAAC;WAEF,aAAa,cACb,aAAa,eAAe,uBAAuB,WAEnD,gBAAe,KAAK;GAClB,QAAQ;GACR,MAAM;GACN,MAAM;GACN,cAAc,GAAG,WAAW;GAC5B,MAAM;GACN,SAAS,YAAY,uBAAuB,QAAQ,wBAAwB,aAAa,WAAW,mCAAmC,uBAAuB,WAAW;GACzK,UAAU,aAAa;GACvB,QAAQ,uBAAuB;GAC/B,UAAU,EAAE;GACb,CAAC;;AAIN,KAAI,eAAe,aAAa,aAAa,UAAU;AACrD,SAAO,KAAK;GACV,MAAM;GACN,OAAO;GACP,QAAQ;GACR,UAAU,OAAO,eAAe,SAAS;GACzC,QAAQ,OAAO,aAAa,SAAS;GACrC,SAAS,WAAW,UAAU,KAAK,WAAW,uCAAuC,eAAe,WAAW,aAAa,WAAW,QAAQ,aAAa,WAAW,aAAa;GACrL,CAAC;AACF,iBAAe,KAAK;GAClB,QAAQ;GACR,MAAM;GACN,MAAM;GACN,cAAc,GAAG,WAAW;GAC5B,MAAM;GACN,SAAS,kCAAkC,eAAe,WAAW,aAAa,WAAW,QAAQ,aAAa,WAAW,aAAa;GAC1I,UAAU,eAAe;GACzB,QAAQ,aAAa;GACrB,UAAU,EAAE;GACb,CAAC;AACF,iBAAe;;AAGjB,KAAI,eAAe,SACjB;MAAI,CAAC,aAAa,SAAS;GACzB,MAAM,qBAAqB,sBAAsB,eAAe,QAAQ;AACxE,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV,SAAS,WAAW,UAAU,KAAK,WAAW,wBAAwB,mBAAmB;IAC1F,CAAC;AACF,kBAAe,KAAK;IAClB,QAAQ;IACR,MAAM;IACN,MAAM;IACN,cAAc,GAAG,WAAW;IAC5B,MAAM;IACN,SAAS,6BAA6B;IACtC,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;AACF,kBAAe;aAEf,CAAC,oBACC,eAAe,SACf,aAAa,SACb,kBACA,iBACD,EACD;GACA,MAAM,sBAAsB,sBAAsB,eAAe,QAAQ;GAEzE,MAAM,oBAAoB,aAAa;AACvC,UAAO,KAAK;IACV,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,SAAS,WAAW,UAAU,KAAK,WAAW,mCAAmC,oBAAoB,QAAQ;IAC9G,CAAC;AACF,kBAAe,KAAK;IAClB,QAAQ;IACR,MAAM;IACN,MAAM;IACN,cAAc,GAAG,WAAW;IAC5B,MAAM;IACN,SAAS,8BAA8B,oBAAoB,QAAQ;IACnE,UAAU;IACV,QAAQ;IACR,UAAU,EAAE;IACb,CAAC;AACF,kBAAe;;YAER,UAAU,aAAa,SAAS;AACzC,SAAO,KAAK;GACV,MAAM;GACN,OAAO;GACP,QAAQ;GACR,QAAQ,aAAa;GACrB,SAAS,WAAW,UAAU,KAAK,WAAW,gBAAgB,aAAa,QAAQ;GACpF,CAAC;AACF,iBAAe,KAAK;GAClB,QAAQ;GACR,MAAM;GACN,MAAM;GACN,cAAc,GAAG,WAAW;GAC5B,MAAM;GACN,SAAS,kBAAkB,aAAa;GACxC,UAAU;GACV,QAAQ,aAAa;GACrB,UAAU,EAAE;GACb,CAAC;AACF,iBAAe;;CAIjB,MAAM,aAAa,oBAAoB,gBAAgB,aAAa;CACpE,MAAM,eAAe,eAAe,WAAW,aAAa;CAC5D,MAAM,oBAAoB,uBAAuB,UAC7C,GAAG,mBAAmB,IAAI,uBAAuB,QAAQ,KACzD;CACJ,MAAM,gBAAgB,WAAW,gBAAgB,KAAK,KAAK;AAE3D,QAAO;EACL,QAAQ,WAAW;EACnB,MAAM;EACN,MAAM,GAAG,WAAW,IAAI,kBAAkB,IAAI,aAAa;EAC3D,cAAc;EACd,MAAM,WAAW;EACjB,SAAS;EACT,UAAU;EACV,QAAQ;EACR,UAAU;EACX;;AAGH,SAAS,iBACP,WACA,aACwB;AACxB,QAAO;EACL,QAAQ,oBAAoB,aAAa,OAAO,CAAC;EACjD,MAAM;EACN,MAAM;EACN,cAAc,GAAG,UAAU;EAC3B,MAAM;EACN,SAAS;EACT,UAAU;EACV,QAAQ;EACR,UAAU;EACX;;AAGH,SAAS,eACP,WACA,WACA,eACwB;CACxB,MAAM,cAAc,oBAAoB,eAAe,OAAO,CAAC;CAC/D,MAAM,uBAAuB,cAC1B,QAAQ,UAAU,MAAM,WAAW,UAAU,MAAM,QAAQ,CAC3D,KAAK,UAAU,MAAM,QAAQ,CAC7B,QAAQ,QAAuB,OAAO,QAAQ,YAAY,IAAI,SAAS,EAAE;CAC5E,MAAM,eACJ,gBAAgB,UAAU,qBAAqB,SAAS,IACpD,GAAG,qBAAqB,OAAO,QAAQ,qBAAqB,WAAW,IAAI,KAAK,QAChF;CACN,MAAM,YACJ,gBAAgB,UAAU,cAAc,SAAS,KAAK,cAAc,KAChE,cAAc,GAAG,OACjB;AAEN,QAAO;EACL,QAAQ;EACR,MAAM;EACN,MAAM,SAAS;EACf,cAAc;EACd,MAAM;EACN,SAAS;EACT,UAAU;EACV,QAAQ;EACR,UAAU;EACX;;AAGH,SAAS,cAAc,cAAgE;AACrF,QAAO;EACL,QAAQ,oBAAoB,cAAc,OAAO,CAAC;EAClD,MAAM;EACN,MAAM;EACN,cAAc;EACd,MAAM;EACN,SAAS;EACT,UAAU;EACV,QAAQ;EACR,UAAU;EACX;;;;;;AAgBH,SAAS,oBACP,UACA,UACsB;CACtB,IAAIC,SAA6B;CACjC,MAAMC,kBAA4B,EAAE;CACpC,IAAI,YAAY;AAEhB,MAAK,MAAM,SAAS,SAClB,KAAI,MAAM,WAAW,QAAQ;AAC3B,WAAS;AACT,MAAI,CAAC,UACH,aAAY,MAAM;AAEpB,MAAI,MAAM,WAAW,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,SAAS,EAC/E,iBAAgB,KAAK,MAAM,QAAQ;YAE5B,MAAM,WAAW,UAAU,WAAW,QAAQ;AACvD,WAAS;AACT,MAAI,CAAC,UACH,aAAY,MAAM;;AAKxB,QAAO;EAAE;EAAQ;EAAiB;EAAW;;AAG/C,SAAS,yCACP,UACA,qBACM;CACN,MAAM,yBAAyB,SAAS,kBAAkB,EAAE;AAC5D,MAAK,MAAM,sBAAsB,OAAO,KAAK,uBAAuB,CAQlE,KAAI,CAPiB,oBAAoB,MACtC,cACC,UAAU,OAAO,uBAChB,UAAU,SAAS,eAClB,UAAU,SAAS,aACnB,UAAU,SAAS,UACxB,CAEC,OAAM,IAAI,MACR,mBAAmB,mBAAmB,wNAGvC;;;;;;;;;;AAaP,SAAS,yBACP,gBACA,cACA,YACA,SAIQ;CACR,MAAM,EAAE,SAAS,YAAY,eAAe,kCAC1C,gBACA,cACA,QACD;AAGD,KAAI,CAAC,cAAc,CAAC,QAClB,QAAO;CAIT,MAAM,QAAQ,WAAW,IAAI,QAAQ;AACrC,KAAI,OAAO,iBACT,QAAO,MAAM,iBAAiB;EAAE;EAAY;EAAS;EAAY,CAAC;AAIpE,QAAO;;AAGT,SAAS,kCACP,gBACA,cACA,SAI8D;AAC9D,KAAI,CAAC,eAAe,QAClB,QAAO;CAGT,MAAM,iBAAiB,aAAa,eAAe;AACnD,KAAI,CAAC,gBAAgB;EACnB,MAAM,cAAc,UAChB,WAAW,QAAQ,UAAU,KAAK,QAAQ,WAAW,KACrD;AACJ,QAAM,IAAI,MACR,GAAG,YAAY,4BAA4B,eAAe,QAAQ,2CACnE;;AAGH,QAAO;EACL,SAAS,eAAe;EACxB,YAAY,eAAe;EAC3B,YAAY,eAAe;EAC5B;;;;;AAMH,SAAS,sBAAsB,eAAsC;AACnE,SAAQ,cAAc,MAAtB;EACE,KAAK,UACH,QAAO,WAAW,mBAAmB,cAAc,MAAM,CAAC;EAC5D,KAAK,WACH,QAAO,cAAc;;;;;;;;;;;;;;;AAgB3B,SAAS,oBACP,iBACA,eACA,YACA,YACS;AAET,KAAI,CAAC,YAAY;AACf,MAAI,gBAAgB,SAAS,WAC3B,QAAO,gBAAgB,eAAe;EAExC,MAAM,kBAAkB,sBAAsB,gBAAgB,OAAO,WAAW;AAChF,MAAI,OAAO,oBAAoB,SAC7B,QAAO,oBAAoB,iBAAiB,IAAI,gBAAgB,OAAO;AAEzE,SAAO,OAAO,gBAAgB,KAAK;;CAIrC,MAAM,mBAAmB,WAAW,eAAe,cAAc,GAAG;AACpE,KAAI,CAAC,iBAEH,QAAO;AAIT,KAAI,gBAAgB,SAAS,iBAAiB,KAC5C,QAAO;AAET,KAAI,gBAAgB,SAAS,aAAa,iBAAiB,SAAS,UAGlE,QAAO,mBAFe,sBAAsB,gBAAgB,OAAO,WAAW,EAC1D,sBAAsB,iBAAiB,OAAO,WAAW,CACxB;AAEvD,KAAI,gBAAgB,SAAS,cAAc,iBAAiB,SAAS,YAAY;EAE/E,MAAM,iBAAiB,SAAiB,KAAK,aAAa,CAAC,QAAQ,QAAQ,GAAG;AAC9E,SAAO,cAAc,gBAAgB,WAAW,KAAK,cAAc,iBAAiB,WAAW;;AAEjG,QAAO;;AAGT,SAAS,qBAAqB,YAA8B;AAC1D,KAAI,CAAC,WAAY,QAAO;CACxB,MAAM,aAAa,WAAW,aAAa;AAC3C,QAAO,WAAW,SAAS,YAAY,IAAI,eAAe;;AAG5D,SAAS,sBAAsB,OAAgB,YAA8B;AAC3E,KAAI,iBAAiB,KACnB,QAAO,MAAM,aAAa;AAE5B,KAAI,OAAO,UAAU,YAAY,qBAAqB,WAAW,EAAE;EACjE,MAAM,SAAS,IAAI,KAAK,MAAM;AAC9B,MAAI,CAAC,OAAO,MAAM,OAAO,SAAS,CAAC,CACjC,QAAO,OAAO,aAAa;;AAG/B,QAAO;;;;;;;AAQT,SAAS,gBAAgB,OAAwB;AAC/C,QAAO,KAAK,UAAU,QAAQ,MAAM,QAAQ;AAC1C,MAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,IAAI,EAAE;GAClE,MAAMC,SAAkC,EAAE;AAC1C,QAAK,MAAM,KAAK,OAAO,KAAK,IAA+B,CAAC,MAAM,CAChE,QAAO,KAAM,IAAgC;AAE/C,UAAO;;AAET,SAAO;GACP;;AAGJ,SAAS,mBAAmB,GAAY,GAAqB;AAC3D,KAAI,MAAM,EAAG,QAAO;AACpB,KAAI,OAAO,MAAM,YAAY,MAAM,QAAQ,OAAO,MAAM,YAAY,MAAM,KACxE,QAAO,gBAAgB,EAAE,KAAK,gBAAgB,EAAE;AAElD,KAAI,OAAO,MAAM,YAAY,MAAM,QAAQ,OAAO,MAAM,SACtD,KAAI;AACF,SAAO,gBAAgB,EAAE,KAAK,gBAAgB,KAAK,MAAM,EAAE,CAAC;SACtD;AACN,SAAO;;AAGX,KAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,MAAM,KAC1D,KAAI;AACF,SAAO,gBAAgB,KAAK,MAAM,EAAE,CAAC,KAAK,gBAAgB,EAAE;SACtD;AACN,SAAO;;AAGX,QAAO;;AAGT,SAAS,mBAAmB,OAAwB;AAClD,KAAI,iBAAiB,KACnB,QAAO,MAAM,aAAa;AAE5B,KAAI,OAAO,UAAU,SACnB,QAAO;AAET,QAAO,KAAK,UAAU,MAAM"}
|
|
1
|
+
{"version":3,"file":"verify-sql-schema-Ovz7RXR5.mjs","names":["result: ComponentDatabaseDependency<unknown>[]","nodes: SchemaVerificationNode[]","depIssue: SchemaIssue","mismatches: Array<{ expected: string; actual: string; message: string }>","typeNodes: SchemaVerificationNode[]","issues: SchemaIssue[]","rootChildren: SchemaVerificationNode[]","tableChildren: SchemaVerificationNode[]","columnNodes: SchemaVerificationNode[]","columnChildren: SchemaVerificationNode[]","columnStatus: VerificationStatus","status: VerificationStatus","failureMessages: string[]","sorted: Record<string, unknown>"],"sources":["../src/core/assembly.ts","../src/core/migrations/types.ts","../src/core/schema-verify/verify-helpers.ts","../src/core/schema-verify/verify-sql-schema.ts"],"sourcesContent":["import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport { assertUniqueCodecOwner } from '@prisma-next/framework-components/control';\nimport type { CodecControlHooks } from './migrations/types';\n\ntype CodecControlHooksMap = Record<string, CodecControlHooks>;\n\nfunction hasCodecControlHooks(descriptor: unknown): descriptor is {\n readonly id: string;\n readonly types: {\n readonly codecTypes: {\n readonly controlPlaneHooks: CodecControlHooksMap;\n };\n };\n} {\n if (typeof descriptor !== 'object' || descriptor === null) {\n return false;\n }\n const d = descriptor as { types?: { codecTypes?: { controlPlaneHooks?: unknown } } };\n const hooks = d.types?.codecTypes?.controlPlaneHooks;\n return hooks !== null && hooks !== undefined && typeof hooks === 'object';\n}\n\nexport function extractCodecControlHooks(\n descriptors: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n): Map<string, CodecControlHooks> {\n const hooks = new Map<string, CodecControlHooks>();\n const owners = new Map<string, string>();\n\n for (const descriptor of descriptors) {\n if (typeof descriptor !== 'object' || descriptor === null) {\n continue;\n }\n if (!hasCodecControlHooks(descriptor)) {\n continue;\n }\n const controlPlaneHooks = descriptor.types.codecTypes.controlPlaneHooks;\n for (const [codecId, hook] of Object.entries(controlPlaneHooks)) {\n assertUniqueCodecOwner({\n codecId,\n owners,\n descriptorId: descriptor.id,\n entityLabel: 'control hooks',\n entityOwnershipLabel: 'owner',\n });\n hooks.set(codecId, hook);\n owners.set(codecId, descriptor.id);\n }\n }\n\n return hooks;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n DataTransformOperation,\n MigratableTargetDescriptor,\n MigrationOperationPolicy,\n MigrationPlan,\n MigrationPlannerConflict,\n MigrationPlannerFailureResult,\n MigrationPlannerSuccessResult,\n MigrationPlanOperation,\n MigrationRunnerExecutionChecks,\n MigrationRunnerFailure,\n MigrationRunnerSuccessValue,\n OperationContext,\n SchemaIssue,\n} from '@prisma-next/framework-components/control';\nimport type { SqlStorage, StorageTypeInstance } from '@prisma-next/sql-contract/types';\nimport type { SqlOperationDescriptor } from '@prisma-next/sql-operations';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport type { Result } from '@prisma-next/utils/result';\nimport type { SqlControlFamilyInstance } from '../control-instance';\n\nexport type AnyRecord = Readonly<Record<string, unknown>>;\n\nexport interface ComponentDatabaseDependency<TTargetDetails> {\n readonly id: string;\n readonly label: string;\n readonly install: readonly SqlMigrationPlanOperation<TTargetDetails>[];\n}\n\nexport interface ComponentDatabaseDependencies<TTargetDetails> {\n readonly init?: readonly ComponentDatabaseDependency<TTargetDetails>[];\n}\n\nexport interface DatabaseDependencyProvider {\n readonly databaseDependencies?: ComponentDatabaseDependencies<unknown>;\n}\n\nexport function isDatabaseDependencyProvider(value: unknown): value is DatabaseDependencyProvider {\n return typeof value === 'object' && value !== null && 'databaseDependencies' in value;\n}\n\nexport function collectInitDependencies(\n components: ReadonlyArray<unknown>,\n): readonly ComponentDatabaseDependency<unknown>[] {\n const result: ComponentDatabaseDependency<unknown>[] = [];\n for (const component of components) {\n if (!isDatabaseDependencyProvider(component)) continue;\n const deps = component.databaseDependencies?.init;\n if (!deps) continue;\n result.push(...deps);\n }\n return result;\n}\n\nexport interface StorageTypePlanResult<TTargetDetails> {\n readonly operations: readonly SqlMigrationPlanOperation<TTargetDetails>[];\n}\n\n/**\n * Input for expanding parameterized native types.\n */\nexport interface ExpandNativeTypeInput {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n}\n\n/**\n * Input for resolving an identity-value SQL literal used to backfill existing rows when\n * adding a NOT NULL column without an explicit default.\n *\n * \"Identity value\" in the algebraic (monoid) sense: the neutral element for the type\n * (0 for numbers, '' for strings, false for booleans, etc.).\n */\nexport interface ResolveIdentityValueInput {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n}\n\nexport interface CodecControlHooks<TTargetDetails = unknown> {\n planTypeOperations?: (options: {\n readonly typeName: string;\n readonly typeInstance: StorageTypeInstance;\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIR;\n readonly schemaName?: string;\n readonly policy: MigrationOperationPolicy;\n }) => StorageTypePlanResult<TTargetDetails>;\n verifyType?: (options: {\n readonly typeName: string;\n readonly typeInstance: StorageTypeInstance;\n readonly schema: SqlSchemaIR;\n readonly schemaName?: string;\n }) => readonly SchemaIssue[];\n introspectTypes?: (options: {\n readonly driver: ControlDriverInstance<'sql', string>;\n readonly schemaName?: string;\n }) => Promise<Record<string, StorageTypeInstance>>;\n /**\n * Expands a parameterized native type to its full SQL representation.\n * Used by schema verification to compare contract types against database types.\n *\n * For example, expands:\n * - { nativeType: 'character varying', typeParams: { length: 255 } } -> 'character varying(255)'\n * - { nativeType: 'numeric', typeParams: { precision: 10, scale: 2 } } -> 'numeric(10,2)'\n *\n * Returns the expanded type string, or the original nativeType if no expansion is needed.\n */\n expandNativeType?: (input: ExpandNativeTypeInput) => string;\n /**\n * Resolves the identity value (monoid neutral element) as a SQL literal for safely adding\n * a NOT NULL column without an explicit default to a non-empty table.\n *\n * Return semantics:\n * - string: use this literal\n * - null: explicitly no safe identity value is known; fall back to another strategy\n * - undefined: no opinion; planner may use built-in fallbacks\n */\n resolveIdentityValue?: (input: ResolveIdentityValueInput) => string | null | undefined;\n}\n\nexport interface SqlControlExtensionDescriptor<TTargetId extends string>\n extends ControlExtensionDescriptor<'sql', TTargetId> {\n readonly databaseDependencies?: ComponentDatabaseDependencies<unknown>;\n readonly queryOperations?: () => ReadonlyArray<SqlOperationDescriptor>;\n}\n\nexport interface SqlControlAdapterDescriptor<TTargetId extends string>\n extends ControlAdapterDescriptor<'sql', TTargetId> {\n readonly queryOperations?: () => ReadonlyArray<SqlOperationDescriptor>;\n}\n\nexport interface SqlMigrationPlanOperationStep {\n readonly description: string;\n readonly sql: string;\n readonly meta?: AnyRecord;\n}\n\n/**\n * Minimal shape every SQL-family target must conform to for its per-operation\n * `target.details` payload. Each SQL operation addresses a named database\n * object in some schema; targets (Postgres, MySQL, SQLite, …) extend this\n * shape with their own fields (e.g. Postgres adds `objectType` and optional\n * `table`).\n */\nexport interface SqlPlanTargetDetails {\n readonly schema: string;\n readonly name: string;\n}\n\nexport interface SqlMigrationPlanOperationTarget<TTargetDetails> {\n readonly id: string;\n readonly details?: TTargetDetails;\n}\n\nexport interface SqlMigrationPlanOperation<TTargetDetails> extends MigrationPlanOperation {\n readonly summary?: string;\n readonly target: SqlMigrationPlanOperationTarget<TTargetDetails>;\n readonly precheck: readonly SqlMigrationPlanOperationStep[];\n readonly execute: readonly SqlMigrationPlanOperationStep[];\n readonly postcheck: readonly SqlMigrationPlanOperationStep[];\n readonly meta?: AnyRecord;\n}\n\n/**\n * Union of all operation shapes a SQL-family migration may emit: schema-facing\n * `SqlMigrationPlanOperation`s and family-agnostic `DataTransformOperation`s.\n *\n * Mirrors `AnyMongoMigrationOperation` in shape — the runner already handles\n * both branches via `isDataTransformOperation`, and authored `migration.ts`\n * files must be able to intermix `dataTransform(endContract, …)` calls with\n * DDL factory calls (e.g. `setNotNull(…)`) in a single `operations` array.\n */\nexport type AnySqlMigrationOperation<TTargetDetails> =\n | SqlMigrationPlanOperation<TTargetDetails>\n | DataTransformOperation;\n\nexport interface SqlMigrationPlanContractInfo {\n readonly storageHash: string;\n readonly profileHash?: string;\n}\n\nexport interface SqlMigrationPlan<TTargetDetails> extends MigrationPlan {\n /**\n * Origin contract identity that the plan expects the database to currently be at.\n * If omitted or null, the runner skips origin validation entirely.\n */\n readonly origin?: SqlMigrationPlanContractInfo | null;\n /**\n * Destination contract identity that the plan intends to reach.\n */\n readonly destination: SqlMigrationPlanContractInfo;\n readonly operations: readonly SqlMigrationPlanOperation<TTargetDetails>[];\n readonly meta?: AnyRecord;\n}\n\nexport type SqlPlannerConflictKind =\n | 'typeMismatch'\n | 'nullabilityConflict'\n | 'indexIncompatible'\n | 'foreignKeyConflict'\n | 'missingButNonAdditive'\n | 'unsupportedOperation';\n\nexport interface SqlPlannerConflictLocation {\n readonly table?: string;\n readonly column?: string;\n readonly index?: string;\n readonly constraint?: string;\n readonly type?: string;\n}\n\nexport interface SqlPlannerConflict extends MigrationPlannerConflict {\n readonly kind: SqlPlannerConflictKind;\n readonly location?: SqlPlannerConflictLocation;\n readonly meta?: AnyRecord;\n}\n\nexport interface SqlPlannerSuccessResult<TTargetDetails>\n extends Omit<MigrationPlannerSuccessResult, 'plan'> {\n readonly kind: 'success';\n readonly plan: SqlMigrationPlan<TTargetDetails>;\n}\n\nexport interface SqlPlannerFailureResult extends Omit<MigrationPlannerFailureResult, 'conflicts'> {\n readonly kind: 'failure';\n readonly conflicts: readonly SqlPlannerConflict[];\n}\n\nexport type SqlPlannerResult<TTargetDetails> =\n | SqlPlannerSuccessResult<TTargetDetails>\n | SqlPlannerFailureResult;\n\nexport interface SqlMigrationPlannerPlanOptions {\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIR;\n readonly policy: MigrationOperationPolicy;\n readonly schemaName?: string;\n /**\n * The \"from\" contract (state the planner assumes the database starts at),\n * or `null` for reconciliation flows that have no prior contract.\n *\n * Required at every call site so the structural fact \"I have a prior\n * contract / I don't\" is visible in the type. `migration plan` supplies\n * the previous bundle's `metadata.toContract`; `db update` / `db init`\n * reconcile against the live schema and pass `null`. Strategies that\n * need from/to column-shape comparisons (unsafe type change, nullability\n * tightening) use this to decide whether to emit `dataTransform`\n * placeholders; they short-circuit when it is `null`.\n *\n * Planners also derive the \"from\" identity they stamp onto the produced\n * plan's `describe()` as `fromContract?.storage.storageHash ?? null`.\n */\n readonly fromContract: Contract<SqlStorage> | null;\n /**\n * Active framework components participating in this composition.\n * SQL targets can interpret this list to derive database dependencies.\n * All components must have matching familyId ('sql') and targetId.\n */\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n}\n\nexport interface SqlMigrationPlanner<TTargetDetails> {\n plan(options: SqlMigrationPlannerPlanOptions): SqlPlannerResult<TTargetDetails>;\n}\n\nexport interface SqlMigrationRunnerExecuteCallbacks<TTargetDetails> {\n onOperationStart?(operation: SqlMigrationPlanOperation<TTargetDetails>): void;\n onOperationComplete?(operation: SqlMigrationPlanOperation<TTargetDetails>): void;\n}\n\nexport interface SqlMigrationRunnerExecuteOptions<TTargetDetails> {\n readonly plan: SqlMigrationPlan<TTargetDetails>;\n readonly driver: ControlDriverInstance<'sql', string>;\n /**\n * Destination contract IR.\n * Must correspond to `plan.destination` and is used for schema verification and marker/ledger writes.\n */\n readonly destinationContract: Contract<SqlStorage>;\n /**\n * Execution-time policy that defines which operation classes are allowed.\n * The runner validates each operation against this policy before execution.\n */\n readonly policy: MigrationOperationPolicy;\n readonly schemaName?: string;\n readonly strictVerification?: boolean;\n readonly callbacks?: SqlMigrationRunnerExecuteCallbacks<TTargetDetails>;\n readonly context?: OperationContext;\n /**\n * Execution-time checks configuration.\n * All checks default to `true` (enabled) when omitted.\n */\n readonly executionChecks?: MigrationRunnerExecutionChecks;\n /**\n * Active framework components participating in this composition.\n * SQL targets can interpret this list to derive database dependencies.\n * All components must have matching familyId ('sql') and targetId.\n */\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Invariant ids contributed by this apply (the migration's `providedInvariants`).\n * The runner unions these into `marker.invariants` atomically with the marker write.\n * Defaults to `[]` for marker-only flows (`db update`, `db init`).\n */\n readonly invariants?: readonly string[];\n}\n\nexport type SqlMigrationRunnerErrorCode =\n | 'DESTINATION_CONTRACT_MISMATCH'\n | 'MARKER_ORIGIN_MISMATCH'\n | 'POLICY_VIOLATION'\n | 'PRECHECK_FAILED'\n | 'POSTCHECK_FAILED'\n | 'SCHEMA_VERIFY_FAILED'\n | 'FOREIGN_KEY_VIOLATION'\n | 'EXECUTION_FAILED';\n\nexport interface SqlMigrationRunnerFailure extends MigrationRunnerFailure {\n readonly code: SqlMigrationRunnerErrorCode;\n readonly meta?: AnyRecord;\n}\n\nexport interface SqlMigrationRunnerSuccessValue extends MigrationRunnerSuccessValue {}\n\nexport type SqlMigrationRunnerResult = Result<\n SqlMigrationRunnerSuccessValue,\n SqlMigrationRunnerFailure\n>;\n\nexport interface SqlMigrationRunner<TTargetDetails> {\n execute(\n options: SqlMigrationRunnerExecuteOptions<TTargetDetails>,\n ): Promise<SqlMigrationRunnerResult>;\n}\n\nexport interface SqlControlTargetDescriptor<TTargetId extends string, TTargetDetails>\n extends MigratableTargetDescriptor<'sql', TTargetId, SqlControlFamilyInstance> {\n readonly queryOperations?: () => ReadonlyArray<SqlOperationDescriptor>;\n createPlanner(family: SqlControlFamilyInstance): SqlMigrationPlanner<TTargetDetails>;\n createRunner(family: SqlControlFamilyInstance): SqlMigrationRunner<TTargetDetails>;\n}\n\nexport interface CreateSqlMigrationPlanOptions<TTargetDetails> {\n readonly targetId: string;\n readonly origin?: SqlMigrationPlanContractInfo | null;\n readonly destination: SqlMigrationPlanContractInfo;\n readonly operations: readonly SqlMigrationPlanOperation<TTargetDetails>[];\n readonly meta?: AnyRecord;\n}\n","/**\n * Pure verification helper functions for SQL schema verification.\n * These functions verify schema IR against contract requirements.\n */\n\nimport type {\n SchemaIssue,\n SchemaVerificationNode,\n} from '@prisma-next/framework-components/control';\nimport type {\n ForeignKey,\n Index,\n PrimaryKey,\n UniqueConstraint,\n} from '@prisma-next/sql-contract/types';\nimport type {\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlSchemaIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\nimport type { ComponentDatabaseDependency } from '../migrations/types';\n\n/**\n * Compares two arrays of strings for equality (order-sensitive).\n */\nexport function arraysEqual(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n// ============================================================================\n// Semantic Satisfaction Predicates\n// ============================================================================\n// These predicates implement the \"stronger satisfies weaker\" logic for storage\n// objects. They are used by both verification and migration planning to ensure\n// consistent behavior across the control plane.\n\n/**\n * Checks if a unique constraint requirement is satisfied by the given columns.\n *\n * Semantic satisfaction: a unique constraint requirement can be satisfied by:\n * - A unique constraint with the same columns, OR\n * - A unique index with the same columns\n *\n * @param uniques - The unique constraints in the schema table\n * @param indexes - The indexes in the schema table\n * @param columns - The columns required by the unique constraint\n * @returns true if the requirement is satisfied\n */\nexport function isUniqueConstraintSatisfied(\n uniques: readonly SqlUniqueIR[],\n indexes: readonly SqlIndexIR[],\n columns: readonly string[],\n): boolean {\n // Check for matching unique constraint\n const hasConstraint = uniques.some((unique) => arraysEqual(unique.columns, columns));\n if (hasConstraint) {\n return true;\n }\n // Check for matching unique index (semantic satisfaction)\n return indexes.some((index) => index.unique && arraysEqual(index.columns, columns));\n}\n\n/**\n * Checks if an index requirement is satisfied by the given columns.\n *\n * Semantic satisfaction: a non-unique index requirement can be satisfied by:\n * - Any index (unique or non-unique) with the same columns, OR\n * - A unique constraint with the same columns (stronger satisfies weaker)\n *\n * @param indexes - The indexes in the schema table\n * @param uniques - The unique constraints in the schema table\n * @param columns - The columns required by the index\n * @returns true if the requirement is satisfied\n */\nexport function isIndexSatisfied(\n indexes: readonly SqlIndexIR[],\n uniques: readonly SqlUniqueIR[],\n columns: readonly string[],\n): boolean {\n // Check for any matching index (unique or non-unique)\n const hasMatchingIndex = indexes.some((index) => arraysEqual(index.columns, columns));\n if (hasMatchingIndex) {\n return true;\n }\n // Check for matching unique constraint (semantic satisfaction)\n return uniques.some((unique) => arraysEqual(unique.columns, columns));\n}\n\n/**\n * Verifies primary key matches between contract and schema.\n * Returns 'pass' or 'fail'.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyPrimaryKey(\n contractPK: PrimaryKey,\n schemaPK: PrimaryKey | undefined,\n tableName: string,\n 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 // Name differences are ignored for semantic satisfaction.\n // Names are persisted for deterministic DDL and diagnostics but are not identity.\n\n return 'pass';\n}\n\n/**\n * Verifies foreign keys match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + columns + referenced table + referenced columns).\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyForeignKeys(\n contractFKs: readonly ForeignKey[],\n schemaFKs: readonly SqlForeignKeyIR[],\n tableName: string,\n 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 const actionMismatches = getReferentialActionMismatches(contractFK, matchingFK);\n if (actionMismatches.length > 0) {\n const combinedMessage = actionMismatches.map((m) => m.message).join('; ');\n const combinedExpected = actionMismatches.map((m) => m.expected).join(', ');\n const combinedActual = actionMismatches.map((m) => m.actual).join(', ');\n issues.push({\n kind: 'foreign_key_mismatch',\n table: tableName,\n // Set indexOrConstraint so the planner classifies this as a non-additive\n // conflict (existing FK with wrong actions cannot be fixed additively).\n indexOrConstraint: matchingFK.name ?? `fk(${contractFK.columns.join(',')})`,\n expected: combinedExpected,\n actual: combinedActual,\n message: `Table \"${tableName}\" foreign key ${contractFK.columns.join(', ')} -> ${contractFK.references.table}: ${combinedMessage}`,\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: combinedMessage,\n expected: contractFK,\n actual: matchingFK,\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: 'extra_foreign_key',\n table: tableName,\n indexOrConstraint: schemaFK.name ?? `fk(${schemaFK.columns.join(',')})`,\n message: `Extra foreign key found in database (not in contract): ${schemaFK.columns.join(', ')} -> ${schemaFK.referencedTable}(${schemaFK.referencedColumns.join(', ')})`,\n });\n 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 * Verifies unique constraints match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * A unique constraint requirement can be satisfied by either:\n * - A unique constraint with the same columns, or\n * - A unique index with the same columns\n *\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyUniqueConstraints(\n contractUniques: readonly UniqueConstraint[],\n schemaUniques: readonly SqlUniqueIR[],\n schemaIndexes: readonly SqlIndexIR[],\n tableName: string,\n 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\n // First check for a matching unique constraint\n const matchingUnique = schemaUniques.find((u) =>\n arraysEqual(u.columns, contractUnique.columns),\n );\n\n // If no matching constraint, check for a unique index with the same columns\n const matchingUniqueIndex =\n !matchingUnique &&\n schemaIndexes.find((idx) => idx.unique && arraysEqual(idx.columns, contractUnique.columns));\n\n if (!matchingUnique && !matchingUniqueIndex) {\n 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 // Name differences are ignored for semantic satisfaction.\n // Names are persisted for deterministic DDL and diagnostics but are not identity.\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 // 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: 'extra_unique_constraint',\n table: tableName,\n indexOrConstraint: schemaUnique.name ?? `unique(${schemaUnique.columns.join(',')})`,\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 * Verifies indexes match between contract and schema.\n * Returns verification nodes for the tree.\n *\n * Uses semantic satisfaction: identity is based on (table + kind + columns).\n * A non-unique index requirement can be satisfied by either:\n * - A non-unique index with the same columns, or\n * - A unique index with the same columns (stronger satisfies weaker)\n *\n * Name differences are ignored by default (names are for DDL/diagnostics, not identity).\n */\nexport function verifyIndexes(\n contractIndexes: readonly Index[],\n schemaIndexes: readonly SqlIndexIR[],\n schemaUniques: readonly SqlUniqueIR[],\n tableName: string,\n 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\n // Check for any matching index (unique or non-unique)\n // A unique index can satisfy a non-unique index requirement (stronger satisfies weaker)\n const matchingIndex = schemaIndexes.find((idx) =>\n arraysEqual(idx.columns, contractIndex.columns),\n );\n\n // Also check if a unique constraint satisfies the index requirement\n const matchingUniqueConstraint =\n !matchingIndex && schemaUniques.find((u) => arraysEqual(u.columns, contractIndex.columns));\n\n if (!matchingIndex && !matchingUniqueConstraint) {\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 // Name differences are ignored for semantic satisfaction.\n // Names are persisted for deterministic DDL and diagnostics but are not identity.\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 // 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: 'extra_index',\n table: tableName,\n indexOrConstraint: schemaIndex.name ?? `idx(${schemaIndex.columns.join(',')})`,\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 * Verifies database dependencies are installed using component-owned verification hooks.\n * Checks whether each dependency is satisfied by verifying its id is present in\n * schema.dependencies (populated from introspection).\n *\n * Returns verification nodes for the tree.\n */\nexport function verifyDatabaseDependencies(\n dependencies: ReadonlyArray<ComponentDatabaseDependency<unknown>>,\n schema: SqlSchemaIR,\n issues: SchemaIssue[],\n): SchemaVerificationNode[] {\n const nodes: SchemaVerificationNode[] = [];\n const installedIds = new Set(schema.dependencies.map((d) => d.id));\n\n for (const dependency of dependencies) {\n const isSatisfied = installedIds.has(dependency.id);\n const depPath = `dependencies.${dependency.id}`;\n\n if (!isSatisfied) {\n const depIssue: SchemaIssue = {\n kind: 'dependency_missing',\n dependencyId: dependency.id,\n message: `Dependency \"${dependency.id}\" is missing from database`,\n };\n issues.push(depIssue);\n const nodeMessage = depIssue.message;\n nodes.push({\n status: 'fail',\n kind: 'databaseDependency',\n name: dependency.label,\n contractPath: depPath,\n code: 'dependency_missing',\n message: nodeMessage,\n expected: undefined,\n actual: undefined,\n children: [],\n });\n } else {\n // Dependency is satisfied\n nodes.push({\n status: 'pass',\n kind: 'databaseDependency',\n name: dependency.label,\n contractPath: depPath,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n }\n\n return nodes;\n}\n\n/**\n * Computes counts of pass/warn/fail nodes by traversing the tree.\n */\nexport function computeCounts(node: SchemaVerificationNode): {\n pass: number;\n warn: number;\n fail: number;\n totalNodes: number;\n} {\n let pass = 0;\n let warn = 0;\n let fail = 0;\n\n function traverse(n: SchemaVerificationNode): void {\n if (n.status === 'pass') {\n pass++;\n } else if (n.status === 'warn') {\n warn++;\n } else if (n.status === 'fail') {\n fail++;\n }\n\n if (n.children) {\n for (const child of n.children) {\n traverse(child);\n }\n }\n }\n\n traverse(node);\n\n return {\n pass,\n warn,\n fail,\n totalNodes: pass + warn + fail,\n };\n}\n\n/**\n * Compares referential actions between a contract FK and a schema FK.\n * Only compares when the contract FK explicitly specifies onDelete or onUpdate.\n * Returns all mismatches (both onDelete and onUpdate) so both are reported at once.\n *\n * Note: 'noAction' in the contract is semantically equivalent to undefined in the\n * schema IR, because the introspection adapter omits 'NO ACTION' (the database default)\n * to keep the IR sparse. We normalize both sides before comparing.\n */\nfunction getReferentialActionMismatches(\n contractFK: ForeignKey,\n schemaFK: SqlForeignKeyIR,\n): ReadonlyArray<{ expected: string; actual: string; message: string }> {\n const mismatches: Array<{ expected: string; actual: string; message: string }> = [];\n\n const contractOnDelete = normalizeReferentialAction(contractFK.onDelete);\n const schemaOnDelete = normalizeReferentialAction(schemaFK.onDelete);\n if (contractOnDelete !== undefined && contractOnDelete !== schemaOnDelete) {\n mismatches.push({\n expected: `onDelete: ${contractFK.onDelete}`,\n actual: `onDelete: ${schemaFK.onDelete ?? 'noAction (default)'}`,\n message: `onDelete mismatch: expected ${contractFK.onDelete}, got ${schemaFK.onDelete ?? 'noAction (default)'}`,\n });\n }\n\n const contractOnUpdate = normalizeReferentialAction(contractFK.onUpdate);\n const schemaOnUpdate = normalizeReferentialAction(schemaFK.onUpdate);\n if (contractOnUpdate !== undefined && contractOnUpdate !== schemaOnUpdate) {\n mismatches.push({\n expected: `onUpdate: ${contractFK.onUpdate}`,\n actual: `onUpdate: ${schemaFK.onUpdate ?? 'noAction (default)'}`,\n message: `onUpdate mismatch: expected ${contractFK.onUpdate}, got ${schemaFK.onUpdate ?? 'noAction (default)'}`,\n });\n }\n\n return mismatches;\n}\n\n/**\n * Normalizes a referential action value for comparison.\n * 'noAction' is the database default and equivalent to undefined (omitted) in the sparse IR.\n */\nfunction normalizeReferentialAction(action: string | undefined): string | undefined {\n return action === 'noAction' ? undefined : action;\n}\n","/**\n * Pure SQL schema verification function.\n *\n * This module provides a pure function that verifies a SqlSchemaIR against\n * a Contract without requiring a database connection. It can be reused\n * by migration planners and other tools that need to compare schema states.\n */\n\nimport type { ColumnDefault, Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n OperationContext,\n SchemaIssue,\n SchemaVerificationNode,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport type {\n SqlStorage,\n StorageColumn,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { extractCodecControlHooks } from '../assembly';\nimport { type CodecControlHooks, collectInitDependencies } from '../migrations/types';\nimport {\n arraysEqual,\n computeCounts,\n verifyDatabaseDependencies,\n verifyForeignKeys,\n verifyIndexes,\n verifyPrimaryKey,\n verifyUniqueConstraints,\n} from './verify-helpers';\n\n/**\n * Function type for normalizing raw database default expressions into ColumnDefault.\n * Target-specific implementations handle database dialect differences.\n */\nexport type DefaultNormalizer = (\n rawDefault: string,\n nativeType: string,\n) => ColumnDefault | undefined;\n\n/**\n * Function type for normalizing schema native types to canonical form for comparison.\n * Target-specific implementations handle dialect-specific type name variations\n * (e.g., Postgres 'varchar' → 'character varying', 'timestamptz' normalization).\n */\nexport type NativeTypeNormalizer = (nativeType: string) => string;\n\n/**\n * Options for the pure schema verification function.\n */\nexport interface VerifySqlSchemaOptions {\n /** The validated SQL contract to verify against */\n readonly contract: Contract<SqlStorage>;\n /** The schema IR from introspection (or another source) */\n readonly schema: SqlSchemaIR;\n /** Whether to run in strict mode (detects extra tables/columns) */\n readonly strict: boolean;\n /** Optional operation context for metadata */\n readonly context?: OperationContext;\n /** Type metadata registry for codec consistency warnings */\n readonly typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n /**\n * Active framework components participating in this composition.\n * All components must have matching familyId ('sql') and targetId.\n */\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Optional target-specific normalizer for raw database default expressions.\n * When provided, schema defaults (raw strings) are normalized before comparison\n * with contract defaults (ColumnDefault objects).\n */\n readonly normalizeDefault?: DefaultNormalizer;\n /**\n * Optional target-specific normalizer for schema native type names.\n * When provided, schema native types are normalized before comparison\n * with contract native types (e.g., Postgres 'varchar' → 'character varying').\n */\n readonly normalizeNativeType?: NativeTypeNormalizer;\n}\n\n/**\n * Verifies that a SqlSchemaIR matches a Contract.\n *\n * This is a pure function that does NOT perform any database I/O.\n * It takes an already-introspected schema IR and compares it against\n * the contract requirements.\n *\n * @param options - Verification options\n * @returns VerifyDatabaseSchemaResult with verification tree and issues\n */\nexport function verifySqlSchema(options: VerifySqlSchemaOptions): VerifyDatabaseSchemaResult {\n const {\n contract,\n schema,\n strict,\n context,\n typeMetadataRegistry,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const startTime = Date.now();\n\n // Extract codec control hooks once at entry point for reuse\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n\n const { contractStorageHash, contractProfileHash, contractTarget } =\n extractContractMetadata(contract);\n const storageTypes = contract.storage.types ?? {};\n const { issues, rootChildren } = verifySchemaTables({\n contract,\n schema,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n });\n\n validateFrameworkComponentsForExtensions(contract, options.frameworkComponents);\n\n // Verify storage type instances via codec control hooks (pure, deterministic)\n const storageTypeEntries = Object.entries(storageTypes);\n if (storageTypeEntries.length > 0) {\n const typeNodes: SchemaVerificationNode[] = [];\n for (const [typeName, typeInstance] of storageTypeEntries) {\n const hook = codecHooks.get(typeInstance.codecId);\n const typeIssues = hook?.verifyType\n ? hook.verifyType({ typeName, typeInstance, schema })\n : [];\n if (typeIssues.length > 0) {\n issues.push(...typeIssues);\n }\n const typeStatus = typeIssues.length > 0 ? 'fail' : 'pass';\n const typeCode = typeIssues.length > 0 ? (typeIssues[0]?.kind ?? '') : '';\n typeNodes.push({\n status: typeStatus,\n kind: 'storageType',\n name: `type ${typeName}`,\n contractPath: `storage.types.${typeName}`,\n code: typeCode,\n message:\n typeIssues.length > 0\n ? `${typeIssues.length} issue${typeIssues.length === 1 ? '' : 's'}`\n : '',\n expected: undefined,\n actual: undefined,\n children: [],\n });\n }\n const typesStatus = typeNodes.some((n) => n.status === 'fail') ? 'fail' : 'pass';\n rootChildren.push({\n status: typesStatus,\n kind: 'storageTypes',\n name: 'types',\n contractPath: 'storage.types',\n code: typesStatus === 'fail' ? 'type_mismatch' : '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: typeNodes,\n });\n }\n\n const databaseDependencies = collectInitDependencies(options.frameworkComponents);\n const dependencyStatuses = verifyDatabaseDependencies(databaseDependencies, schema, issues);\n rootChildren.push(...dependencyStatuses);\n\n const root = buildRootNode(rootChildren);\n\n // Compute counts\n const counts = computeCounts(root);\n\n // Set ok flag\n const ok = counts.fail === 0;\n\n // Set code\n const code = ok ? undefined : 'PN-SCHEMA-0001';\n\n // Set summary\n const summary = ok\n ? 'Database schema satisfies contract'\n : `Database schema does not satisfy contract (${counts.fail} failure${counts.fail === 1 ? '' : 's'})`;\n\n const totalTime = Date.now() - startTime;\n\n return {\n ok,\n ...ifDefined('code', code),\n summary,\n contract: {\n storageHash: contractStorageHash,\n ...ifDefined('profileHash', contractProfileHash),\n },\n target: {\n expected: contractTarget,\n actual: contractTarget,\n },\n schema: {\n issues,\n root,\n counts,\n },\n meta: {\n strict,\n ...ifDefined('contractPath', context?.contractPath),\n ...ifDefined('configPath', context?.configPath),\n },\n timings: {\n total: totalTime,\n },\n };\n}\n\ntype VerificationStatus = 'pass' | 'warn' | 'fail';\n\nfunction extractContractMetadata(contract: Contract<SqlStorage>): {\n contractStorageHash: SqlStorage['storageHash'];\n contractProfileHash?: Contract<SqlStorage>['profileHash'] | undefined;\n contractTarget: Contract<SqlStorage>['target'];\n} {\n return {\n contractStorageHash: contract.storage.storageHash,\n contractProfileHash:\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : undefined,\n contractTarget: contract.target,\n };\n}\n\nfunction verifySchemaTables(options: {\n contract: Contract<SqlStorage>;\n schema: SqlSchemaIR;\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Record<string, StorageTypeInstance>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n}): { issues: SchemaIssue[]; rootChildren: SchemaVerificationNode[] } {\n const {\n contract,\n schema,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const issues: SchemaIssue[] = [];\n const rootChildren: SchemaVerificationNode[] = [];\n const contractTables = contract.storage.tables;\n const schemaTables = schema.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 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 const tableChildren = verifyTableChildren({\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n });\n rootChildren.push(buildTableNode(tableName, tablePath, tableChildren));\n }\n\n if (strict) {\n for (const tableName of Object.keys(schemaTables)) {\n if (!contractTables[tableName]) {\n issues.push({\n kind: 'extra_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 return { issues, rootChildren };\n}\n\nfunction verifyTableChildren(options: {\n contractTable: Contract<SqlStorage>['storage']['tables'][string];\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n tablePath: string;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Record<string, StorageTypeInstance>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n}): SchemaVerificationNode[] {\n const {\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const tableChildren: SchemaVerificationNode[] = [];\n const columnNodes = collectContractColumnNodes({\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n });\n if (columnNodes.length > 0) {\n tableChildren.push(buildColumnsNode(tablePath, columnNodes));\n }\n if (strict) {\n appendExtraColumnNodes({\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n columnNodes,\n });\n }\n\n if (contractTable.primaryKey) {\n const pkStatus = verifyPrimaryKey(\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 issues.push({\n kind: 'extra_primary_key',\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 // Verify FK constraints only for FKs with constraint: true.\n // Always call when strict mode is on so extra-FK detection runs even if\n // the contract has no FKs for this table.\n const constraintFks = contractTable.foreignKeys.filter((fk) => fk.constraint === true);\n if (constraintFks.length > 0 || strict) {\n const fkStatuses = verifyForeignKeys(\n constraintFks,\n schemaTable.foreignKeys,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...fkStatuses);\n }\n\n const uniqueStatuses = verifyUniqueConstraints(\n contractTable.uniques,\n schemaTable.uniques,\n schemaTable.indexes,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...uniqueStatuses);\n\n // Combine user-declared indexes with FK-backing indexes (from FKs with index: true)\n // so the verifier treats FK-backing indexes as expected, not \"extra\".\n // Deduplicate: skip FK-backing indexes already covered by a user-declared index.\n const fkBackingIndexes = contractTable.foreignKeys\n .filter(\n (fk) =>\n fk.index === true &&\n !contractTable.indexes.some((idx) => arraysEqual(idx.columns, fk.columns)),\n )\n .map((fk) => ({ columns: fk.columns }));\n const allExpectedIndexes = [...contractTable.indexes, ...fkBackingIndexes];\n\n const indexStatuses = verifyIndexes(\n allExpectedIndexes,\n schemaTable.indexes,\n schemaTable.uniques,\n tableName,\n tablePath,\n issues,\n strict,\n );\n tableChildren.push(...indexStatuses);\n\n return tableChildren;\n}\n\nfunction collectContractColumnNodes(options: {\n contractTable: Contract<SqlStorage>['storage']['tables'][string];\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n tablePath: string;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Record<string, StorageTypeInstance>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n}): SchemaVerificationNode[] {\n const {\n contractTable,\n schemaTable,\n tableName,\n tablePath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const columnNodes: SchemaVerificationNode[] = [];\n\n for (const [columnName, contractColumn] of Object.entries(contractTable.columns)) {\n const schemaColumn = schemaTable.columns[columnName];\n const columnPath = `${tablePath}.columns.${columnName}`;\n\n if (!schemaColumn) {\n 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 columnNodes.push(\n verifyColumn({\n tableName,\n columnName,\n contractColumn,\n schemaColumn,\n columnPath,\n issues,\n strict,\n typeMetadataRegistry,\n codecHooks,\n storageTypes,\n ...ifDefined('normalizeDefault', normalizeDefault),\n ...ifDefined('normalizeNativeType', normalizeNativeType),\n }),\n );\n }\n\n return columnNodes;\n}\n\nfunction appendExtraColumnNodes(options: {\n contractTable: Contract<SqlStorage>['storage']['tables'][string];\n schemaTable: SqlSchemaIR['tables'][string];\n tableName: string;\n tablePath: string;\n issues: SchemaIssue[];\n columnNodes: SchemaVerificationNode[];\n}): void {\n const { contractTable, schemaTable, tableName, tablePath, issues, columnNodes } = options;\n for (const [columnName, { nativeType }] of Object.entries(schemaTable.columns)) {\n if (!contractTable.columns[columnName]) {\n issues.push({\n kind: 'extra_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: nativeType,\n children: [],\n });\n }\n }\n}\n\nfunction verifyColumn(options: {\n tableName: string;\n columnName: string;\n contractColumn: Contract<SqlStorage>['storage']['tables'][string]['columns'][string];\n schemaColumn: SqlSchemaIR['tables'][string]['columns'][string];\n columnPath: string;\n issues: SchemaIssue[];\n strict: boolean;\n typeMetadataRegistry: ReadonlyMap<string, { nativeType?: string }>;\n codecHooks: Map<string, CodecControlHooks>;\n storageTypes: Record<string, StorageTypeInstance>;\n normalizeDefault?: DefaultNormalizer;\n normalizeNativeType?: NativeTypeNormalizer;\n}): SchemaVerificationNode {\n const {\n tableName,\n columnName,\n contractColumn,\n schemaColumn,\n columnPath,\n issues,\n strict,\n codecHooks,\n storageTypes,\n normalizeDefault,\n normalizeNativeType,\n } = options;\n const columnChildren: SchemaVerificationNode[] = [];\n let columnStatus: VerificationStatus = 'pass';\n\n const resolvedContractColumn = resolveContractColumnTypeMetadata(contractColumn, storageTypes, {\n tableName,\n columnName,\n });\n const contractNativeType = renderExpectedNativeType(contractColumn, storageTypes, codecHooks, {\n tableName,\n columnName,\n });\n const schemaNativeType =\n normalizeNativeType?.(schemaColumn.nativeType) ?? schemaColumn.nativeType;\n\n if (contractNativeType !== schemaNativeType) {\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 if (resolvedContractColumn.codecId) {\n const typeMetadata = options.typeMetadataRegistry.get(resolvedContractColumn.codecId);\n if (!typeMetadata) {\n columnChildren.push({\n status: 'warn',\n kind: 'type',\n name: 'type_metadata_missing',\n contractPath: `${columnPath}.codecId`,\n code: 'type_metadata_missing',\n message: `codecId \"${resolvedContractColumn.codecId}\" not found in type metadata registry`,\n expected: resolvedContractColumn.codecId,\n actual: undefined,\n children: [],\n });\n } else if (\n typeMetadata.nativeType &&\n typeMetadata.nativeType !== resolvedContractColumn.nativeType\n ) {\n columnChildren.push({\n status: 'warn',\n kind: 'type',\n name: 'type_consistency',\n contractPath: `${columnPath}.codecId`,\n code: 'type_consistency_warning',\n message: `codecId \"${resolvedContractColumn.codecId}\" maps to nativeType \"${typeMetadata.nativeType}\" in registry, but contract has \"${resolvedContractColumn.nativeType}\"`,\n expected: typeMetadata.nativeType,\n actual: resolvedContractColumn.nativeType,\n children: [],\n });\n }\n }\n\n if (contractColumn.nullable !== schemaColumn.nullable) {\n 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 if (contractColumn.default) {\n if (!schemaColumn.default) {\n const defaultDescription = describeColumnDefault(contractColumn.default);\n issues.push({\n kind: 'default_missing',\n table: tableName,\n column: columnName,\n expected: defaultDescription,\n message: `Column \"${tableName}\".\"${columnName}\" should have default ${defaultDescription} but database has no default`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'default_missing',\n message: `Default missing: expected ${defaultDescription}`,\n expected: defaultDescription,\n actual: undefined,\n children: [],\n });\n columnStatus = 'fail';\n } else if (\n !columnDefaultsEqual(\n contractColumn.default,\n schemaColumn.default,\n normalizeDefault,\n schemaNativeType,\n )\n ) {\n const expectedDescription = describeColumnDefault(contractColumn.default);\n // schemaColumn.default is now a raw string, describe it as-is\n const actualDescription = schemaColumn.default;\n issues.push({\n kind: 'default_mismatch',\n table: tableName,\n column: columnName,\n expected: expectedDescription,\n actual: actualDescription,\n message: `Column \"${tableName}\".\"${columnName}\" has default mismatch: expected ${expectedDescription}, got ${actualDescription}`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'default_mismatch',\n message: `Default mismatch: expected ${expectedDescription}, got ${actualDescription}`,\n expected: expectedDescription,\n actual: actualDescription,\n children: [],\n });\n columnStatus = 'fail';\n }\n } else if (strict && schemaColumn.default) {\n issues.push({\n kind: 'extra_default',\n table: tableName,\n column: columnName,\n actual: schemaColumn.default,\n message: `Column \"${tableName}\".\"${columnName}\" has default ${schemaColumn.default} in database but contract specifies no default`,\n });\n columnChildren.push({\n status: 'fail',\n kind: 'default',\n name: 'default',\n contractPath: `${columnPath}.default`,\n code: 'extra_default',\n message: `Extra default: ${schemaColumn.default}`,\n expected: undefined,\n actual: schemaColumn.default,\n children: [],\n });\n columnStatus = 'fail';\n }\n\n // Single-pass aggregation for better performance\n const aggregated = aggregateChildState(columnChildren, columnStatus);\n const nullableText = contractColumn.nullable ? 'nullable' : 'not nullable';\n const columnTypeDisplay = resolvedContractColumn.codecId\n ? `${contractNativeType} (${resolvedContractColumn.codecId})`\n : contractNativeType;\n const columnMessage = aggregated.failureMessages.join('; ');\n\n return {\n status: aggregated.status,\n kind: 'column',\n name: `${columnName}: ${columnTypeDisplay} (${nullableText})`,\n contractPath: columnPath,\n code: aggregated.firstCode,\n message: columnMessage,\n expected: undefined,\n actual: undefined,\n children: columnChildren,\n };\n}\n\nfunction buildColumnsNode(\n tablePath: string,\n columnNodes: SchemaVerificationNode[],\n): SchemaVerificationNode {\n return {\n status: aggregateChildState(columnNodes, 'pass').status,\n kind: 'columns',\n name: 'columns',\n contractPath: `${tablePath}.columns`,\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: columnNodes,\n };\n}\n\nfunction buildTableNode(\n tableName: string,\n tablePath: string,\n tableChildren: SchemaVerificationNode[],\n): SchemaVerificationNode {\n const tableStatus = aggregateChildState(tableChildren, 'pass').status;\n const tableFailureMessages = tableChildren\n .filter((child) => child.status === 'fail' && child.message)\n .map((child) => child.message)\n .filter((msg): msg is string => typeof msg === 'string' && msg.length > 0);\n const tableMessage =\n tableStatus === 'fail' && tableFailureMessages.length > 0\n ? `${tableFailureMessages.length} issue${tableFailureMessages.length === 1 ? '' : 's'}`\n : '';\n const tableCode =\n tableStatus === 'fail' && tableChildren.length > 0 && tableChildren[0]\n ? tableChildren[0].code\n : '';\n\n return {\n status: tableStatus,\n kind: 'table',\n name: `table ${tableName}`,\n contractPath: tablePath,\n code: tableCode,\n message: tableMessage,\n expected: undefined,\n actual: undefined,\n children: tableChildren,\n };\n}\n\nfunction buildRootNode(rootChildren: SchemaVerificationNode[]): SchemaVerificationNode {\n return {\n status: aggregateChildState(rootChildren, 'pass').status,\n kind: 'contract',\n name: 'contract',\n contractPath: '',\n code: '',\n message: '',\n expected: undefined,\n actual: undefined,\n children: rootChildren,\n };\n}\n\n/**\n * Aggregated state from child nodes, computed in a single pass.\n */\ninterface AggregatedChildState {\n readonly status: VerificationStatus;\n readonly failureMessages: readonly string[];\n readonly firstCode: string;\n}\n\n/**\n * Aggregates status, failure messages, and code from children in a single pass.\n * This is more efficient than calling separate functions that each iterate the array.\n */\nfunction aggregateChildState(\n children: SchemaVerificationNode[],\n fallback: VerificationStatus,\n): AggregatedChildState {\n let status: VerificationStatus = fallback;\n const failureMessages: string[] = [];\n let firstCode = '';\n\n for (const child of children) {\n if (child.status === 'fail') {\n status = 'fail';\n if (!firstCode) {\n firstCode = child.code;\n }\n if (child.message && typeof child.message === 'string' && child.message.length > 0) {\n failureMessages.push(child.message);\n }\n } else if (child.status === 'warn' && status !== 'fail') {\n status = 'warn';\n if (!firstCode) {\n firstCode = child.code;\n }\n }\n }\n\n return { status, failureMessages, firstCode };\n}\n\nfunction validateFrameworkComponentsForExtensions(\n contract: Contract<SqlStorage>,\n frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n): void {\n const contractExtensionPacks = contract.extensionPacks ?? {};\n for (const extensionNamespace of Object.keys(contractExtensionPacks)) {\n const hasComponent = frameworkComponents.some(\n (component) =>\n component.id === extensionNamespace &&\n (component.kind === 'extension' ||\n component.kind === 'adapter' ||\n component.kind === 'target'),\n );\n if (!hasComponent) {\n throw new Error(\n `Extension pack '${extensionNamespace}' is declared in the contract but not found in framework components. ` +\n 'This indicates a configuration mismatch - the contract was emitted with this extension pack, ' +\n 'but it is not provided in the current configuration.',\n );\n }\n }\n}\n\n/**\n * Renders the expected native type for a contract column, expanding parameterized types\n * using codec control hooks when available.\n *\n * This function delegates to the `expandNativeType` hook if the codec provides one,\n * ensuring that the SQL family layer remains dialect-agnostic while allowing\n * target-specific adapters (like Postgres) to provide their own expansion logic.\n */\nfunction renderExpectedNativeType(\n contractColumn: Contract<SqlStorage>['storage']['tables'][string]['columns'][string],\n storageTypes: Record<string, StorageTypeInstance>,\n codecHooks: Map<string, CodecControlHooks>,\n context?: {\n readonly tableName: string;\n readonly columnName: string;\n },\n): string {\n const { codecId, nativeType, typeParams } = resolveContractColumnTypeMetadata(\n contractColumn,\n storageTypes,\n context,\n );\n\n // If no typeParams or codecId, return the base native type\n if (!typeParams || !codecId) {\n return nativeType;\n }\n\n // Try to use the codec's expandNativeType hook if available\n const hooks = codecHooks.get(codecId);\n if (hooks?.expandNativeType) {\n return hooks.expandNativeType({ nativeType, codecId, typeParams });\n }\n\n // Fallback: return base native type if no hook is available\n return nativeType;\n}\n\nfunction resolveContractColumnTypeMetadata(\n contractColumn: StorageColumn,\n storageTypes: Record<string, StorageTypeInstance>,\n context?: {\n readonly tableName: string;\n readonly columnName: string;\n },\n): Pick<StorageColumn, 'codecId' | 'nativeType' | 'typeParams'> {\n if (!contractColumn.typeRef) {\n return contractColumn;\n }\n\n const referencedType = storageTypes[contractColumn.typeRef];\n if (!referencedType) {\n const columnLabel = context\n ? `Column \"${context.tableName}\".\"${context.columnName}\"`\n : 'Column';\n throw new Error(\n `${columnLabel} references storage type \"${contractColumn.typeRef}\" but it is not defined in storage.types.`,\n );\n }\n\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: referencedType.typeParams,\n };\n}\n\n/**\n * Describes a column default for display purposes.\n */\nfunction describeColumnDefault(columnDefault: ColumnDefault): string {\n switch (columnDefault.kind) {\n case 'literal':\n return `literal(${formatLiteralValue(columnDefault.value)})`;\n case 'function':\n return columnDefault.expression;\n }\n}\n\n/**\n * Compares a contract ColumnDefault against a schema raw default string for semantic equality.\n *\n * When a normalizer is provided, the raw schema default is first normalized to a ColumnDefault\n * before comparison. Without a normalizer, falls back to direct string comparison against\n * the contract expression.\n *\n * @param contractDefault - The expected default from the contract (normalized ColumnDefault)\n * @param schemaDefault - The raw default expression from the database (string)\n * @param normalizer - Optional target-specific normalizer to convert raw defaults\n * @param nativeType - The column's native type, passed to normalizer for context\n */\nfunction columnDefaultsEqual(\n contractDefault: ColumnDefault,\n schemaDefault: string,\n normalizer?: DefaultNormalizer,\n nativeType?: string,\n): boolean {\n // If no normalizer provided, fall back to direct string comparison\n if (!normalizer) {\n if (contractDefault.kind === 'function') {\n return contractDefault.expression === schemaDefault;\n }\n const normalizedValue = normalizeLiteralValue(contractDefault.value, nativeType);\n if (typeof normalizedValue === 'string') {\n return normalizedValue === schemaDefault || `'${normalizedValue}'` === schemaDefault;\n }\n return String(normalizedValue) === schemaDefault;\n }\n\n // Normalize the raw schema default using target-specific logic\n const normalizedSchema = normalizer(schemaDefault, nativeType ?? '');\n if (!normalizedSchema) {\n // Normalizer couldn't parse the expression - treat as mismatch\n return false;\n }\n\n // Compare normalized defaults\n if (contractDefault.kind !== normalizedSchema.kind) {\n return false;\n }\n if (contractDefault.kind === 'literal' && normalizedSchema.kind === 'literal') {\n const contractValue = normalizeLiteralValue(contractDefault.value, nativeType);\n const schemaValue = normalizeLiteralValue(normalizedSchema.value, nativeType);\n return literalValuesEqual(contractValue, schemaValue);\n }\n if (contractDefault.kind === 'function' && normalizedSchema.kind === 'function') {\n // Normalize function expressions for comparison (case-insensitive, whitespace-tolerant)\n const normalizeExpr = (expr: string) => expr.toLowerCase().replace(/\\s+/g, '');\n return normalizeExpr(contractDefault.expression) === normalizeExpr(normalizedSchema.expression);\n }\n return false;\n}\n\nfunction isTemporalNativeType(nativeType?: string): boolean {\n if (!nativeType) return false;\n const normalized = nativeType.toLowerCase();\n return normalized.includes('timestamp') || normalized === 'date';\n}\n\nfunction normalizeLiteralValue(value: unknown, nativeType?: string): unknown {\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'string' && isTemporalNativeType(nativeType)) {\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed.toISOString();\n }\n }\n return value;\n}\n\n/**\n * Recursively sorts object keys for deterministic JSON comparison.\n * Postgres jsonb may canonicalize key order, so two semantically equal\n * objects can have different key insertion order.\n */\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, (_key, val) => {\n if (val !== null && typeof val === 'object' && !Array.isArray(val)) {\n const sorted: Record<string, unknown> = {};\n for (const k of Object.keys(val as Record<string, unknown>).sort()) {\n sorted[k] = (val as Record<string, unknown>)[k];\n }\n return sorted;\n }\n return val;\n });\n}\n\nfunction literalValuesEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a === 'object' && a !== null && typeof b === 'object' && b !== null) {\n return stableStringify(a) === stableStringify(b);\n }\n if (typeof a === 'object' && a !== null && typeof b === 'string') {\n try {\n return stableStringify(a) === stableStringify(JSON.parse(b));\n } catch {\n return false;\n }\n }\n if (typeof a === 'string' && typeof b === 'object' && b !== null) {\n try {\n return stableStringify(JSON.parse(a)) === stableStringify(b);\n } catch {\n return false;\n }\n }\n return false;\n}\n\nfunction formatLiteralValue(value: unknown): string {\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'string') {\n return value;\n }\n return JSON.stringify(value);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/family-sql",
|
|
3
|
-
"version": "0.5.0-dev.
|
|
3
|
+
"version": "0.5.0-dev.35",
|
|
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/contract": "0.5.0-dev.
|
|
10
|
-
"@prisma-next/emitter": "0.5.0-dev.
|
|
11
|
-
"@prisma-next/framework-components": "0.5.0-dev.
|
|
12
|
-
"@prisma-next/migration-tools": "0.5.0-dev.
|
|
13
|
-
"@prisma-next/
|
|
14
|
-
"@prisma-next/sql-contract-emitter": "0.5.0-dev.
|
|
15
|
-
"@prisma-next/sql-contract
|
|
16
|
-
"@prisma-next/
|
|
17
|
-
"@prisma-next/sql-
|
|
18
|
-
"@prisma-next/sql-
|
|
19
|
-
"@prisma-next/sql-
|
|
20
|
-
"@prisma-next/
|
|
21
|
-
"@prisma-next/
|
|
9
|
+
"@prisma-next/contract": "0.5.0-dev.35",
|
|
10
|
+
"@prisma-next/emitter": "0.5.0-dev.35",
|
|
11
|
+
"@prisma-next/framework-components": "0.5.0-dev.35",
|
|
12
|
+
"@prisma-next/migration-tools": "0.5.0-dev.35",
|
|
13
|
+
"@prisma-next/operations": "0.5.0-dev.35",
|
|
14
|
+
"@prisma-next/sql-contract-emitter": "0.5.0-dev.35",
|
|
15
|
+
"@prisma-next/sql-contract": "0.5.0-dev.35",
|
|
16
|
+
"@prisma-next/sql-contract-ts": "0.5.0-dev.35",
|
|
17
|
+
"@prisma-next/sql-operations": "0.5.0-dev.35",
|
|
18
|
+
"@prisma-next/sql-runtime": "0.5.0-dev.35",
|
|
19
|
+
"@prisma-next/sql-schema-ir": "0.5.0-dev.35",
|
|
20
|
+
"@prisma-next/utils": "0.5.0-dev.35",
|
|
21
|
+
"@prisma-next/sql-relational-core": "0.5.0-dev.35"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"tsdown": "0.18.4",
|
|
25
25
|
"typescript": "5.9.3",
|
|
26
26
|
"vitest": "4.0.17",
|
|
27
|
-
"@prisma-next/driver-postgres": "0.5.0-dev.
|
|
28
|
-
"@prisma-next/psl-
|
|
29
|
-
"@prisma-next/psl-
|
|
30
|
-
"@prisma-next/sql-contract-psl": "0.5.0-dev.
|
|
27
|
+
"@prisma-next/driver-postgres": "0.5.0-dev.35",
|
|
28
|
+
"@prisma-next/psl-parser": "0.5.0-dev.35",
|
|
29
|
+
"@prisma-next/psl-printer": "0.5.0-dev.35",
|
|
30
|
+
"@prisma-next/sql-contract-psl": "0.5.0-dev.35",
|
|
31
31
|
"@prisma-next/tsdown": "0.0.0",
|
|
32
|
-
"@prisma-next/
|
|
33
|
-
"@prisma-next/
|
|
32
|
+
"@prisma-next/test-utils": "0.0.1",
|
|
33
|
+
"@prisma-next/tsconfig": "0.0.0"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"dist",
|
|
@@ -243,14 +243,21 @@ export interface SqlMigrationPlannerPlanOptions {
|
|
|
243
243
|
readonly policy: MigrationOperationPolicy;
|
|
244
244
|
readonly schemaName?: string;
|
|
245
245
|
/**
|
|
246
|
-
* The "from" contract (state the planner assumes the database starts at)
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
246
|
+
* The "from" contract (state the planner assumes the database starts at),
|
|
247
|
+
* or `null` for reconciliation flows that have no prior contract.
|
|
248
|
+
*
|
|
249
|
+
* Required at every call site so the structural fact "I have a prior
|
|
250
|
+
* contract / I don't" is visible in the type. `migration plan` supplies
|
|
251
|
+
* the previous bundle's `metadata.toContract`; `db update` / `db init`
|
|
252
|
+
* reconcile against the live schema and pass `null`. Strategies that
|
|
253
|
+
* need from/to column-shape comparisons (unsafe type change, nullability
|
|
250
254
|
* tightening) use this to decide whether to emit `dataTransform`
|
|
251
|
-
* placeholders
|
|
255
|
+
* placeholders; they short-circuit when it is `null`.
|
|
256
|
+
*
|
|
257
|
+
* Planners also derive the "from" identity they stamp onto the produced
|
|
258
|
+
* plan's `describe()` as `fromContract?.storage.storageHash ?? null`.
|
|
252
259
|
*/
|
|
253
|
-
readonly fromContract
|
|
260
|
+
readonly fromContract: Contract<SqlStorage> | null;
|
|
254
261
|
/**
|
|
255
262
|
* Active framework components participating in this composition.
|
|
256
263
|
* SQL targets can interpret this list to derive database dependencies.
|