@prisma-next/family-sql 0.16.0-dev.30 → 0.16.0-dev.32
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.map +1 -1
- package/dist/control.mjs +84 -18
- package/dist/control.mjs.map +1 -1
- package/dist/errors-ZGKTAYsm.mjs +9 -0
- package/dist/errors-ZGKTAYsm.mjs.map +1 -0
- package/dist/ir.d.mts.map +1 -1
- package/dist/ir.mjs +1 -1
- package/dist/{sql-contract-serializer-C75cfMSS.mjs → sql-contract-serializer-othnJUZ_.mjs} +7 -2
- package/dist/sql-contract-serializer-othnJUZ_.mjs.map +1 -0
- package/dist/{verify-C-G0obRm.mjs → verify-DuuJFiTm.mjs} +7 -2
- package/dist/verify-DuuJFiTm.mjs.map +1 -0
- package/dist/verify.d.mts.map +1 -1
- package/dist/verify.mjs +1 -1
- package/package.json +21 -21
- package/src/core/control-instance.ts +43 -16
- package/src/core/errors.ts +22 -0
- package/src/core/ir/sql-contract-serializer-base.ts +8 -1
- package/src/core/migrations/contract-to-schema-ir.ts +56 -8
- package/src/core/verify.ts +10 -1
- package/dist/sql-contract-serializer-C75cfMSS.mjs.map +0 -1
- package/dist/verify-C-G0obRm.mjs.map +0 -1
package/dist/control.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.mjs","names":[],"sources":["../src/core/operation-preview.ts","../src/core/control-instance.ts","../src/core/control-descriptor.ts","../src/core/migrations/contract-to-schema-ir.ts","../src/core/migrations/control-policy.ts","../src/core/migrations/field-event-planner.ts","../src/core/migrations/native-type-expander.ts","../src/core/migrations/plan-helpers.ts","../src/core/migrations/policies.ts","../src/exports/control.ts"],"sourcesContent":["import type {\n MigrationPlanOperation,\n OperationPreview,\n} from '@prisma-next/framework-components/control';\n\n/**\n * Shape of an SQL execute step on `SqlMigrationPlanOperation`. Used for runtime\n * type narrowing without importing the concrete SQL type.\n */\ninterface SqlExecuteStep {\n readonly sql: string;\n}\n\nfunction isDdlStatement(sqlStatement: string): boolean {\n const trimmed = sqlStatement.trim().toLowerCase();\n return (\n trimmed.startsWith('create ') || trimmed.startsWith('alter ') || trimmed.startsWith('drop ')\n );\n}\n\nfunction hasExecuteSteps(\n operation: MigrationPlanOperation,\n): operation is MigrationPlanOperation & { readonly execute: readonly SqlExecuteStep[] } {\n const candidate = operation as unknown as Record<string, unknown>;\n if (!('execute' in candidate) || !Array.isArray(candidate['execute'])) {\n return false;\n }\n return candidate['execute'].every(\n (step: unknown) => typeof step === 'object' && step !== null && 'sql' in step,\n );\n}\n\n/**\n * Extracts a best-effort SQL DDL preview for CLI plan output.\n * Presentation-only: never used to decide migration correctness.\n */\nexport function extractSqlDdl(operations: readonly MigrationPlanOperation[]): string[] {\n const statements: string[] = [];\n for (const operation of operations) {\n if (!hasExecuteSteps(operation)) {\n continue;\n }\n for (const step of operation.execute) {\n if (typeof step.sql === 'string' && isDdlStatement(step.sql)) {\n statements.push(step.sql.trim());\n }\n }\n }\n return statements;\n}\n\n/**\n * Wraps `extractSqlDdl` into the family-agnostic `OperationPreview` shape.\n * Each statement carries `language: 'sql'`.\n */\nexport function sqlOperationsToPreview(\n operations: readonly MigrationPlanOperation[],\n): OperationPreview {\n return {\n statements: extractSqlDdl(operations).map((text) => ({ text, language: 'sql' })),\n };\n}\n","import type {\n Contract,\n ContractMarkerRecord,\n LedgerEntryRecord,\n} from '@prisma-next/contract/types';\nimport type {\n TargetBoundComponentDescriptor,\n TargetDescriptor,\n} from '@prisma-next/framework-components/components';\nimport type {\n ControlFamilyInstance,\n ControlStack,\n CoreSchemaView,\n DiffSubjectGranularity,\n MigrationPlanOperation,\n OperationPreview,\n OperationPreviewCapable,\n PslContractInferCapable,\n SchemaDiffIssue,\n SchemaViewCapable,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n APP_SPACE_ID,\n SchemaTreeNode,\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport type { TypesImportSpec } from '@prisma-next/framework-components/emission';\nimport { isPlainRecord } from '@prisma-next/framework-components/ir';\nimport type { PslDocumentAst } from '@prisma-next/framework-components/psl-ast';\nimport { assertDescriptorSelfConsistency } from '@prisma-next/migration-tools/spaces';\nimport { sqlContractCanonicalizationHooks } from '@prisma-next/sql-contract/canonicalization-hooks';\nimport type { SqlControlDriverInstance, SqlStorage } from '@prisma-next/sql-contract/types';\nimport type {\n AnyQueryAst,\n DdlNode,\n LowererContext,\n SqlExecuteRequest,\n} from '@prisma-next/sql-relational-core/ast';\nimport type { SqlSchemaIRNode, SqlTableIR } from '@prisma-next/sql-schema-ir/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { SqlControlAdapter } from './control-adapter';\nimport type {\n SqlControlTargetDescriptor,\n SqlDescribedContractSpace,\n} from './control-target-descriptor';\nimport {\n classifyDiffEntityKind,\n classifyDiffSubjectGranularity,\n verifySqlSchemaByDiff,\n} from './diff/schema-verify';\nimport { SqlContractSerializer } from './ir/sql-contract-serializer';\nimport type { SqlSchemaDiffFn } from './migrations/schema-differ';\nimport type {\n SqlControlAdapterDescriptor,\n SqlControlExtensionDescriptor,\n} from './migrations/types';\nimport { sqlOperationsToPreview } from './operation-preview';\nimport { collectSupportedCodecTypeIds } from './verify';\n\nfunction extractCodecTypeIdsFromContract(contract: unknown): readonly string[] {\n const typeIds = new Set<string>();\n\n // Type guard for SQL contract structure\n if (\n typeof contract === 'object' &&\n contract !== null &&\n 'storage' in contract &&\n typeof contract.storage === 'object' &&\n contract.storage !== null &&\n 'namespaces' in contract.storage &&\n typeof contract.storage.namespaces === 'object' &&\n contract.storage.namespaces !== null\n ) {\n const namespaces = contract.storage.namespaces as Record<\n string,\n { readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>> }\n >;\n for (const ns of Object.values(namespaces)) {\n const tbls = ns.entries['table'];\n if (typeof tbls !== 'object' || tbls === null) continue;\n for (const table of Object.values(tbls)) {\n if (\n typeof table === 'object' &&\n table !== null &&\n 'columns' in table &&\n typeof table.columns === 'object' &&\n table.columns !== null\n ) {\n const columns = table.columns as Record<string, { codecId: string } | undefined>;\n for (const column of Object.values(columns)) {\n if (\n column &&\n typeof column === 'object' &&\n 'codecId' in column &&\n typeof column.codecId === 'string'\n ) {\n typeIds.add(column.codecId);\n }\n }\n }\n }\n }\n }\n\n return Array.from(typeIds).sort();\n}\n\nfunction createVerifyResult(options: {\n ok: boolean;\n code?: string;\n summary: string;\n contractStorageHash: string;\n contractProfileHash?: string;\n marker?: ContractMarkerRecord;\n expectedTargetId: string;\n actualTargetId?: string;\n missingCodecs?: readonly string[];\n codecCoverageSkipped?: boolean;\n configPath?: string;\n contractPath: string;\n totalTime: number;\n}): VerifyDatabaseResult {\n const contract: { storageHash: string; profileHash?: string } = {\n storageHash: options.contractStorageHash,\n };\n if (options.contractProfileHash) {\n contract.profileHash = options.contractProfileHash;\n }\n\n const target: { expected: string; actual?: string } = {\n expected: options.expectedTargetId,\n };\n if (options.actualTargetId) {\n target.actual = options.actualTargetId;\n }\n\n const meta: { contractPath: string; configPath?: string } = {\n contractPath: options.contractPath,\n };\n if (options.configPath) {\n meta.configPath = options.configPath;\n }\n\n const result: VerifyDatabaseResult = {\n ok: options.ok,\n summary: options.summary,\n contract,\n target,\n meta,\n timings: {\n total: options.totalTime,\n },\n };\n\n if (options.code) {\n (result as { code?: string }).code = options.code;\n }\n\n if (options.marker) {\n (result as { marker?: { storageHash: string; profileHash: string } }).marker = {\n storageHash: options.marker.storageHash,\n profileHash: options.marker.profileHash,\n };\n }\n\n if (options.missingCodecs) {\n (result as { missingCodecs?: readonly string[] }).missingCodecs = options.missingCodecs;\n }\n\n if (options.codecCoverageSkipped) {\n (result as { codecCoverageSkipped?: boolean }).codecCoverageSkipped =\n options.codecCoverageSkipped;\n }\n\n return result;\n}\n\ninterface SqlTypeMetadata {\n readonly typeId: string;\n readonly familyId: 'sql';\n readonly targetId: string;\n readonly nativeType?: string;\n}\n\ntype SqlTypeMetadataRegistry = Map<string, SqlTypeMetadata>;\n\ninterface SqlFamilyInstanceState {\n readonly codecTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly extensionIds: ReadonlyArray<string>;\n readonly typeMetadataRegistry: SqlTypeMetadataRegistry;\n}\n\nexport interface SqlControlFamilyInstance\n extends ControlFamilyInstance<'sql', SqlSchemaIRNode>,\n SchemaViewCapable<SqlSchemaIRNode>,\n PslContractInferCapable<SqlSchemaIRNode>,\n OperationPreviewCapable,\n SqlFamilyInstanceState {\n /**\n * The family seam-of-record for on-disk contract reads. Structurally\n * validates the JSON envelope, then hydrates IR-class instances via\n * the per-target ContractSerializer. The single named entry point\n * every CLI on-disk read crosses (TML-2536) — `as Contract` casts\n * in production package sources are a serializer-bypass smell guarded\n * by `pnpm lint:no-contract-cast`.\n */\n deserializeContract(contractJson: unknown): Contract;\n\n verify(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult>;\n\n /**\n * Verify a contract against an already-introspected schema.\n *\n * Callers that need to verify against the live database compose\n * `introspect({ driver })` + `verifySchema({ contract, schema, ... })`.\n * The aggregate verifier hands in the full introspected schema and scopes\n * the returned result to each member's contract space afterwards — so\n * sibling-space tables never survive as `extras`.\n */\n verifySchema(options: {\n readonly contract: unknown;\n readonly schema: SqlSchemaIRNode;\n readonly strict: boolean;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n }): VerifyDatabaseSchemaResult;\n\n /**\n * Classifies a diff issue's subject granularity on demand, resolved from\n * its node's `nodeKind` via the target's classifier. Satisfies the\n * {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}\n * capability that framework consumers spanning contract spaces (the\n * migration aggregate's unclaimed-elements sweep) detect via\n * `hasSchemaSubjectClassifier` and call instead of reading family/target\n * node vocabulary. Nothing is stamped on the issue or the node.\n */\n classifySubjectGranularity(issue: SchemaDiffIssue): DiffSubjectGranularity | undefined;\n\n /**\n * Classifies a diff issue's subject storage `entityKind` on demand,\n * resolved from its node's `nodeKind` via the target's classifier —\n * sibling of `classifySubjectGranularity` above, part of the same\n * {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}\n * capability. Nothing is stamped on the issue or the node.\n */\n classifyEntityKind(issue: SchemaDiffIssue): string | undefined;\n\n sign(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult>;\n\n introspect(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract?: unknown;\n }): Promise<SqlSchemaIRNode>;\n\n inferPslContract(schemaIR: SqlSchemaIRNode): PslDocumentAst;\n\n lowerAst(\n ast: AnyQueryAst | DdlNode,\n context: LowererContext<unknown>,\n ): Promise<SqlExecuteRequest>;\n\n /**\n * Inserts the initial marker row for `space` (upsert on `space`).\n * Delegates to the target control adapter's write SPI; see\n * `SqlControlAdapter.initMarker`.\n */\n initMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n };\n }): Promise<void>;\n\n /**\n * Compare-and-swap advance of the marker row for `space`. Returns `true`\n * when the swap matched a row; see `SqlControlAdapter.updateMarker`.\n */\n updateMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly expectedFrom: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n };\n }): Promise<boolean>;\n\n /**\n * Appends a ledger entry for `space`; see\n * `SqlControlAdapter.writeLedgerEntry`.\n */\n writeLedgerEntry(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n readonly migrationName: string;\n readonly migrationHash: string;\n readonly operations: readonly unknown[];\n readonly destinationContractJson?: unknown;\n };\n }): Promise<void>;\n\n bootstrapControlTableQueries(): readonly DdlNode[];\n\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview;\n}\n\nexport type SqlFamilyInstance = SqlControlFamilyInstance;\n\ninterface DescriptorWithStorageTypes {\n readonly targetId?: string | undefined;\n readonly types?:\n | {\n readonly storage?:\n | ReadonlyArray<{\n readonly typeId: string;\n readonly familyId: string;\n readonly targetId: string;\n readonly nativeType?: string | undefined;\n }>\n | undefined;\n }\n | undefined;\n}\n\nfunction buildSqlTypeMetadataRegistry(options: {\n readonly target: DescriptorWithStorageTypes;\n readonly adapter: DescriptorWithStorageTypes & { readonly targetId: string };\n readonly extensions: readonly DescriptorWithStorageTypes[];\n}): SqlTypeMetadataRegistry {\n const { target, adapter, extensions } = options;\n const registry = new Map<string, SqlTypeMetadata>();\n const targetId = adapter.targetId;\n const descriptors = [target, adapter, ...extensions];\n\n for (const descriptor of descriptors) {\n const types = descriptor.types;\n const storageTypes = types?.storage;\n\n if (!storageTypes) {\n continue;\n }\n\n for (const storageType of storageTypes) {\n if (storageType.familyId === 'sql' && storageType.targetId === targetId) {\n registry.set(storageType.typeId, {\n typeId: storageType.typeId,\n familyId: 'sql',\n targetId: storageType.targetId,\n ...(storageType.nativeType !== undefined ? { nativeType: storageType.nativeType } : {}),\n });\n }\n }\n }\n\n return registry;\n}\n\ninterface CrossSpaceFkView {\n readonly id: string;\n readonly contractSpace?: {\n readonly contractJson?: {\n readonly extensions?: Readonly<Record<string, unknown>>;\n readonly storage?: {\n readonly namespaces?: Readonly<Record<string, unknown>>;\n };\n };\n };\n}\n\n/**\n * Builds a map from each extension id to the set of extension ids it\n * transitively depends on. Uses the same declared-dependency data that\n * `buildExtensionLoadOrder` in control-stack uses.\n */\nfunction buildTransitiveDependsOnMap(\n extensions: readonly CrossSpaceFkView[],\n): Map<string, Set<string>> {\n const directDeps = new Map<string, readonly string[]>();\n for (const ext of extensions) {\n const packs = ext.contractSpace?.contractJson?.extensions;\n const deps = packs !== null && typeof packs === 'object' ? Object.keys(packs) : [];\n directDeps.set(ext.id, deps);\n }\n\n const result = new Map<string, Set<string>>();\n const resolve = (id: string, visiting: Set<string>): Set<string> => {\n const cached = result.get(id);\n if (cached !== undefined) return cached;\n const set = new Set<string>();\n result.set(id, set);\n for (const depId of directDeps.get(id) ?? []) {\n set.add(depId);\n if (!visiting.has(depId)) {\n visiting.add(depId);\n for (const transitive of resolve(depId, visiting)) {\n set.add(transitive);\n }\n visiting.delete(depId);\n }\n }\n return set;\n };\n\n for (const ext of extensions) {\n resolve(ext.id, new Set([ext.id]));\n }\n return result;\n}\n\n/**\n * Asserts that no cross-space FK in any extension points against the\n * dependency direction.\n *\n * A cross-space FK (target.spaceId present) from extension A pointing at\n * space B is a violation when B depends on A (directly or transitively),\n * because that means A is pointing \"upward\" against the dependency arrows\n * established by the extension load order.\n *\n * Throws with a diagnostic naming the violating extension (source), the\n * target space, and the direction violation.\n */\nfunction isObjectRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null;\n}\n\nexport function assertNoCrossSpaceFkReverseReferences(\n extensions: readonly CrossSpaceFkView[],\n): void {\n const dependsOnMap = buildTransitiveDependsOnMap(extensions);\n\n for (const ext of extensions) {\n const namespaces = ext.contractSpace?.contractJson?.storage?.namespaces;\n if (!isObjectRecord(namespaces)) continue;\n for (const ns of Object.values(namespaces)) {\n if (!isObjectRecord(ns)) continue;\n const entries = ns['entries'];\n if (!isObjectRecord(entries)) continue;\n for (const slot of Object.values(entries)) {\n if (!isObjectRecord(slot)) continue;\n for (const table of Object.values(slot)) {\n if (!isObjectRecord(table)) continue;\n const foreignKeys = table['foreignKeys'];\n if (!Array.isArray(foreignKeys)) continue;\n for (const fk of foreignKeys) {\n if (!isObjectRecord(fk)) continue;\n const target = fk['target'];\n if (!isObjectRecord(target)) continue;\n if (target['spaceId'] === undefined) continue;\n const targetSpaceId = target['spaceId'];\n if (typeof targetSpaceId !== 'string') continue;\n // Check if targetSpaceId depends on ext.id (directly or transitively)\n const targetDeps = dependsOnMap.get(targetSpaceId);\n if (targetDeps?.has(ext.id)) {\n throw new Error(\n `Cross-space FK reverse-reference detected: extension \"${ext.id}\" has a cross-space FK targeting space \"${targetSpaceId}\", but \"${targetSpaceId}\" depends on \"${ext.id}\". Cross-space FKs must follow the dependency direction (a space can only reference spaces it depends on, not spaces that depend on it).`,\n );\n }\n }\n }\n }\n }\n }\n}\n\nexport function createSqlFamilyInstance<TTargetId extends string>(\n stack: ControlStack<'sql', TTargetId>,\n): SqlFamilyInstance {\n if (!stack.adapter) {\n throw new Error('SQL family requires an adapter descriptor in ControlStack');\n }\n\n const target = stack.target as unknown as TargetDescriptor<'sql', TTargetId> &\n DescriptorWithStorageTypes;\n const adapter = stack.adapter as unknown as SqlControlAdapterDescriptor<TTargetId> &\n DescriptorWithStorageTypes;\n const extensions =\n stack.extensions as unknown as readonly (SqlControlExtensionDescriptor<TTargetId> &\n DescriptorWithStorageTypes)[];\n\n // Descriptor self-consistency check.\n // Each extension that exposes a `contractSpace` must publish a\n // `headRef.hash` that matches the canonical hash recomputed from its\n // `contractJson`. A stale value would silently corrupt every downstream\n // boundary that trusts `headRef.hash` as the canonical identity (drift\n // detection, on-disk artefact emission, runner marker writes). Failing\n // fast at descriptor-load time turns \"extension author shipped an\n // inconsistent descriptor\" into an explicit, actionable error\n // (`MIGRATION.DESCRIPTOR_HEAD_HASH_MISMATCH`) rather than a confusing\n // mismatch surfacing several layers downstream.\n for (const extension of extensions) {\n if (extension.contractSpace) {\n const { contractJson, headRef } = extension.contractSpace;\n assertDescriptorSelfConsistency({\n extensionId: extension.id,\n target: contractJson.target,\n targetFamily: contractJson.targetFamily,\n storage: contractJson.storage,\n headRefHash: headRef.hash,\n ...sqlContractCanonicalizationHooks,\n });\n }\n }\n\n assertNoCrossSpaceFkReverseReferences(extensions);\n\n const { codecTypeImports, extensionIds } = stack;\n\n const typeMetadataRegistry = buildSqlTypeMetadataRegistry({\n target,\n adapter,\n extensions: extensions,\n });\n\n // Lazily construct the control adapter on first use, then memoize it.\n // Merely building a family instance must not instantiate the adapter —\n // that would change the load/instantiate semantics of the whole stack\n // wherever a family is created (every CLI command, emit, verify, …), not\n // just the migration paths that actually need it. Memoizing also avoids\n // the previous per-operation re-instantiation (a fresh adapter on every\n // call). Family-instance methods accept `SqlControlDriverInstance<string>`\n // (the family API isn't generic on the target id); the adapter\n // descriptor's `create` returns the concrete `SqlControlAdapter<TTargetId>`,\n // widened to `string` to match the family-level driver type without a\n // per-method probe.\n let controlAdapter: SqlControlAdapter<string> | undefined;\n const getControlAdapter = (): SqlControlAdapter<string> =>\n (controlAdapter ??= adapter.create(stack));\n\n const targetSerializer = (\n target as unknown as {\n contractSerializer?: {\n deserializeContract(json: unknown): Contract<SqlStorage>;\n serializeContract(contract: Contract<SqlStorage>): unknown;\n };\n }\n ).contractSerializer;\n // Database→PSL inference is target logic (it owns the dialect type/default\n // maps and walks its own schema tree), so it is read off the descriptor like\n // `contractSerializer`. Absent for targets without `contract infer` (Mongo).\n const targetInferPslContract = blindCast<\n SqlControlTargetDescriptor<TTargetId, unknown>,\n 'reading the optional target-descriptor inferPslContract hook'\n >(target).inferPslContract;\n // The full-tree node diff the verify VERDICT derives from. Read lazily so\n // construction-only stub descriptors (schema-view tests) keep working; the\n // throw happens at verify time.\n const diffSchema = blindCast<\n { readonly diffSchema?: SqlSchemaDiffFn },\n 'reading the target-descriptor diffSchema hook'\n >(target).diffSchema;\n // The target's nodeKind → granularity classifier, resolved on demand by the\n // verdict and by the instance's `classifySubjectGranularity` method below —\n // never stamped onto an issue. Read lazily for the same\n // construction-only-stub reason as `diffSchema`; the throw happens at call\n // time.\n const targetGranularityOf = blindCast<\n { readonly classifySubjectGranularity?: (nodeKind: string) => DiffSubjectGranularity },\n 'reading the target-descriptor classifySubjectGranularity hook'\n >(target).classifySubjectGranularity;\n // The target's nodeKind → storage entityKind classifier — sibling of\n // `targetGranularityOf` above, read the same lazy way for the same\n // construction-only-stub reason.\n const targetEntityKindOf = blindCast<\n { readonly classifyEntityKind?: (nodeKind: string) => string | undefined },\n 'reading the target-descriptor classifyEntityKind hook'\n >(target).classifyEntityKind;\n // `contract infer` needs each extension pack's already-assembled contract,\n // carried as-is (no merging — that is the contract-spaces machinery's\n // concern), paired with the `spaceId` its descriptor was registered under\n // (neither the contract JSON nor `ContractSpace` self-declares it), so the\n // target hook can omit elements those contracts describe and qualify a\n // cross-space relation with the owning pack's space id.\n const describedContracts: readonly SqlDescribedContractSpace[] = extensions.flatMap(\n (extension) =>\n extension.contractSpace\n ? [{ spaceId: extension.id, contract: extension.contractSpace.contractJson }]\n : [],\n );\n const deserializeWithTargetSerializer = (contractOrJson: unknown): Contract<SqlStorage> => {\n const serializer = targetSerializer ?? new SqlContractSerializer();\n const json =\n targetSerializer !== undefined && !isPlainRecord(contractOrJson)\n ? targetSerializer.serializeContract(\n blindCast<\n Contract<SqlStorage>,\n 'isPlainRecord returned false, so contractOrJson is a class instance, not raw JSON'\n >(contractOrJson),\n )\n : contractOrJson;\n return serializer.deserializeContract(json) as Contract<SqlStorage>;\n };\n\n return {\n familyId: 'sql',\n codecTypeImports,\n extensionIds,\n typeMetadataRegistry,\n\n deserializeContract(contractJson: unknown): Contract {\n return deserializeWithTargetSerializer(contractJson);\n },\n\n async verify(verifyOptions: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult> {\n const {\n driver,\n contract: rawContract,\n expectedTargetId,\n contractPath,\n configPath,\n } = verifyOptions;\n const startTime = Date.now();\n\n const contract = deserializeWithTargetSerializer(rawContract) as Contract<SqlStorage>;\n\n const contractStorageHash = contract.storage.storageHash;\n const contractProfileHash = contract.profileHash;\n const contractTarget = contract.target;\n\n const marker = await getControlAdapter().readMarker(driver, APP_SPACE_ID);\n\n let missingCodecs: readonly string[] | undefined;\n let codecCoverageSkipped = false;\n const supportedTypeIds = collectSupportedCodecTypeIds([adapter, target, ...extensions]);\n if (supportedTypeIds.length === 0) {\n codecCoverageSkipped = true;\n } else {\n const supportedSet = new Set(supportedTypeIds);\n const usedTypeIds = extractCodecTypeIdsFromContract(contract);\n const missing = usedTypeIds.filter((id) => !supportedSet.has(id));\n if (missing.length > 0) {\n missingCodecs = missing;\n }\n }\n\n if (!marker) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: VERIFY_CODE_MARKER_MISSING,\n summary: 'Marker missing',\n contractStorageHash,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n if (contractTarget !== expectedTargetId) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: VERIFY_CODE_TARGET_MISMATCH,\n summary: 'Target mismatch',\n contractStorageHash,\n marker,\n expectedTargetId,\n actualTargetId: contractTarget,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n if (marker.storageHash !== contractStorageHash) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: VERIFY_CODE_HASH_MISMATCH,\n summary: 'Hash mismatch',\n contractStorageHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n if (contractProfileHash && marker.profileHash !== contractProfileHash) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: VERIFY_CODE_HASH_MISMATCH,\n summary: 'Hash mismatch',\n contractStorageHash,\n contractProfileHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: true,\n summary: 'Database matches contract',\n contractStorageHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n },\n\n verifySchema(options: {\n readonly contract: unknown;\n readonly schema: SqlSchemaIRNode;\n readonly strict: boolean;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n }): VerifyDatabaseSchemaResult {\n const contract = deserializeWithTargetSerializer(options.contract) as Contract<SqlStorage>;\n if (!diffSchema) {\n throw new Error(\n `SQL target \"${target.targetId}\" is missing the required diffSchema descriptor operation`,\n );\n }\n if (!targetGranularityOf) {\n throw new Error(\n `SQL target \"${target.targetId}\" is missing the required classifySubjectGranularity descriptor operation`,\n );\n }\n // THE VERDICT: the target's full-tree node diff, graded by the\n // family's post-diff filters (strict gating + control-policy\n // disposition), plus the codec verifyType hook findings. The result\n // is issue-based — `ok` holds exactly when both issue lists are empty.\n return verifySqlSchemaByDiff({\n contract,\n schema: options.schema,\n strict: options.strict,\n frameworkComponents: options.frameworkComponents,\n diffSchema,\n granularityOf: targetGranularityOf,\n });\n },\n\n /**\n * Classifies a diff issue's subject granularity on demand, by resolving\n * its node's `nodeKind` through the target's classifier — the\n * {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}\n * capability. Framework consumers spanning contract spaces (the\n * migration aggregate's unclaimed-elements sweep) detect and call this\n * instead of reaching into the concrete schema-IR node, which they\n * cannot read; nothing is stamped on the issue or the node.\n */\n classifySubjectGranularity(issue: SchemaDiffIssue): DiffSubjectGranularity | undefined {\n if (!targetGranularityOf) {\n throw new Error(\n `SQL target \"${target.targetId}\" is missing the required classifySubjectGranularity descriptor operation`,\n );\n }\n return classifyDiffSubjectGranularity(issue, targetGranularityOf);\n },\n /**\n * Classifies a diff issue's subject storage `entityKind` on demand, by\n * resolving its node's `nodeKind` through the target's classifier —\n * the sibling of `classifySubjectGranularity` above, and part of the\n * same {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}\n * capability.\n */\n classifyEntityKind(issue: SchemaDiffIssue): string | undefined {\n if (!targetEntityKindOf) {\n throw new Error(\n `SQL target \"${target.targetId}\" is missing the required classifyEntityKind descriptor operation`,\n );\n }\n return classifyDiffEntityKind(issue, targetEntityKindOf);\n },\n async sign(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult> {\n const { driver, contract: contractInput, contractPath, configPath } = options;\n const startTime = Date.now();\n\n const contract = deserializeWithTargetSerializer(contractInput) as Contract<SqlStorage>;\n\n const contractStorageHash = contract.storage.storageHash;\n const contractProfileHash =\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : contractStorageHash;\n const contractTarget = contract.target;\n\n const controlAdapter = getControlAdapter();\n const lowererContext = { contract };\n for (const query of controlAdapter.bootstrapSignMarkerQueries()) {\n const lowered = await controlAdapter.lowerToExecuteRequest(query, lowererContext);\n await driver.query(lowered.sql, lowered.params);\n }\n\n const existingMarker = await controlAdapter.readMarker(driver, APP_SPACE_ID);\n\n let markerCreated = false;\n let markerUpdated = false;\n let previousHashes: { storageHash?: string; profileHash?: string } | undefined;\n\n if (!existingMarker) {\n await controlAdapter.insertMarker(driver, APP_SPACE_ID, {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n });\n markerCreated = true;\n } else {\n const existingStorageHash = existingMarker.storageHash;\n const existingProfileHash = existingMarker.profileHash;\n\n const storageHashMatches = existingStorageHash === contractStorageHash;\n const profileHashMatches = existingProfileHash === contractProfileHash;\n\n if (!storageHashMatches || !profileHashMatches) {\n previousHashes = {\n storageHash: existingStorageHash,\n profileHash: existingProfileHash,\n };\n const updated = await controlAdapter.updateMarker(\n driver,\n APP_SPACE_ID,\n existingStorageHash,\n {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n },\n );\n if (!updated) {\n throw new Error('CAS conflict: marker was modified by another process during sign');\n }\n markerUpdated = true;\n }\n }\n\n let summary: string;\n if (markerCreated) {\n summary = 'Database signed (marker created)';\n } else if (markerUpdated) {\n summary = `Database signed (marker updated from ${previousHashes?.storageHash ?? 'unknown'})`;\n } else {\n summary = 'Database already signed with this contract';\n }\n\n const totalTime = Date.now() - startTime;\n\n return {\n ok: true,\n summary,\n contract: {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n },\n target: {\n expected: contractTarget,\n actual: contractTarget,\n },\n marker: {\n created: markerCreated,\n updated: markerUpdated,\n ...(previousHashes ? { previous: previousHashes } : {}),\n },\n meta: {\n contractPath,\n ...(configPath ? { configPath } : {}),\n },\n timings: {\n total: totalTime,\n },\n };\n },\n async readMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n }): Promise<ContractMarkerRecord | null> {\n return getControlAdapter().readMarker(options.driver, options.space);\n },\n async readAllMarkers(options: {\n readonly driver: SqlControlDriverInstance<string>;\n }): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n return getControlAdapter().readAllMarkers(options.driver);\n },\n async readLedger(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space?: string;\n }): Promise<readonly LedgerEntryRecord[]> {\n return getControlAdapter().readLedger(options.driver, options.space);\n },\n async initMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n };\n }): Promise<void> {\n return getControlAdapter().initMarker(options.driver, options.space, options.destination);\n },\n async updateMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly expectedFrom: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n };\n }): Promise<boolean> {\n return getControlAdapter().updateMarker(\n options.driver,\n options.space,\n options.expectedFrom,\n options.destination,\n );\n },\n async writeLedgerEntry(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n readonly migrationName: string;\n readonly migrationHash: string;\n readonly operations: readonly unknown[];\n readonly destinationContractJson?: unknown;\n };\n }): Promise<void> {\n return getControlAdapter().writeLedgerEntry(options.driver, options.space, options.entry);\n },\n async introspect(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract?: unknown;\n }): Promise<SqlSchemaIRNode> {\n return getControlAdapter().introspect(options.driver, options.contract);\n },\n\n inferPslContract(schemaIR: SqlSchemaIRNode): PslDocumentAst {\n if (!targetInferPslContract) {\n throw new Error(\n `Target \"${target.targetId}\" does not support contract infer (no inferPslContract on its descriptor).`,\n );\n }\n return targetInferPslContract(schemaIR, describedContracts);\n },\n\n lowerAst(\n ast: AnyQueryAst | DdlNode,\n context: LowererContext<unknown>,\n ): Promise<SqlExecuteRequest> {\n return getControlAdapter().lowerToExecuteRequest(ast, context);\n },\n\n bootstrapControlTableQueries(): readonly DdlNode[] {\n return getControlAdapter().bootstrapControlTableQueries();\n },\n\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview {\n return sqlOperationsToPreview(operations);\n },\n\n toSchemaView(schema: SqlSchemaIRNode): CoreSchemaView {\n // Walk the schema-IR tree's own structure (root → namespaces → tables)\n // into one flat list of table nodes. A root that exposes a `namespaces`\n // record (Postgres) contributes each namespace's tables; a flat root\n // (SQLite) is its own single namespace. The single-schema common case\n // renders the same table-level view as today — no synthetic namespace\n // level.\n const root = blindCast<\n {\n readonly namespaces?: Readonly<\n Record<string, { readonly tables: Record<string, SqlTableIR> }>\n >;\n readonly tables?: Record<string, SqlTableIR>;\n },\n 'structural read of the schema-IR tree own namespaces/tables records'\n >(schema);\n // A multi-namespace root qualifies every table's display name with its\n // namespace key, so same-named tables in different namespaces (e.g.\n // public.thing and auth.thing) render distinct ids and labels. The\n // single-namespace case (and a flat SQLite root) keeps today's bare\n // names. Synthesized constraint/index fallback names keep the bare table\n // name — that is the name the database derives them from.\n const namespaceEntries: ReadonlyArray<[string | undefined, Record<string, SqlTableIR>]> =\n root.namespaces !== undefined\n ? Object.entries(root.namespaces).map(\n ([namespaceKey, namespace]): [string, Record<string, SqlTableIR>] => [\n namespaceKey,\n namespace.tables,\n ],\n )\n : [[undefined, root.tables ?? {}]];\n const qualify = namespaceEntries.length > 1;\n const tableEntries: ReadonlyArray<[string, string, SqlTableIR]> = namespaceEntries.flatMap(\n ([namespaceKey, tables]) =>\n Object.entries(tables).map(([tableName, table]): [string, string, SqlTableIR] => [\n qualify && namespaceKey !== undefined ? `${namespaceKey}.${tableName}` : tableName,\n tableName,\n table,\n ]),\n );\n const tableNodes: readonly SchemaTreeNode[] = tableEntries.map(\n ([displayName, tableName, table]: [string, string, SqlTableIR]) => {\n const children: SchemaTreeNode[] = [];\n\n const columnNodes: SchemaTreeNode[] = [];\n for (const [columnName, column] of Object.entries(table.columns)) {\n const typeDisplay = column.nativeType;\n const nullability = column.nullable ? 'nullable' : 'not nullable';\n const label = `${columnName}: ${typeDisplay} (${nullability})`;\n columnNodes.push(\n new SchemaTreeNode({\n kind: 'field',\n id: `column-${displayName}-${columnName}`,\n label,\n meta: {\n nativeType: column.nativeType,\n nullable: column.nullable,\n ...ifDefined('default', column.default),\n },\n }),\n );\n }\n\n if (columnNodes.length > 0) {\n children.push(\n new SchemaTreeNode({\n kind: 'collection',\n id: `columns-${displayName}`,\n label: 'columns',\n children: columnNodes,\n }),\n );\n }\n\n if (table.primaryKey) {\n const pkColumns = table.primaryKey.columns.join(', ');\n children.push(\n new SchemaTreeNode({\n kind: 'index',\n id: `primary-key-${displayName}`,\n label: `primary key: ${pkColumns}`,\n meta: {\n columns: table.primaryKey.columns,\n ...(table.primaryKey.name ? { name: table.primaryKey.name } : {}),\n },\n }),\n );\n }\n\n for (const unique of table.uniques) {\n const name = unique.name ?? `${tableName}_${unique.columns.join('_')}_unique`;\n const label = `unique ${name}`;\n children.push(\n new SchemaTreeNode({\n kind: 'index',\n id: `unique-${displayName}-${name}`,\n label,\n meta: {\n columns: unique.columns,\n unique: true,\n },\n }),\n );\n }\n\n for (const index of table.indexes) {\n const name = index.name;\n const label = index.unique ? `unique index ${name}` : `index ${name}`;\n children.push(\n new SchemaTreeNode({\n kind: 'index',\n id: `index-${displayName}-${name}`,\n label,\n meta: {\n columns: index.columns,\n unique: index.unique,\n },\n }),\n );\n }\n\n const tableMeta: Record<string, unknown> = {};\n if (table.primaryKey) {\n tableMeta['primaryKey'] = table.primaryKey.columns;\n if (table.primaryKey.name) {\n tableMeta['primaryKeyName'] = table.primaryKey.name;\n }\n }\n if (table.foreignKeys.length > 0) {\n tableMeta['foreignKeys'] = table.foreignKeys.map((fk) => ({\n columns: fk.columns,\n referencedTable: fk.referencedTable,\n referencedColumns: fk.referencedColumns,\n ...(fk.name ? { name: fk.name } : {}),\n }));\n }\n\n return new SchemaTreeNode({\n kind: 'entity',\n id: `table-${displayName}`,\n label: `table ${displayName}`,\n ...(Object.keys(tableMeta).length > 0 ? { meta: tableMeta } : {}),\n ...(children.length > 0 ? { children } : {}),\n });\n },\n );\n\n return {\n root: new SchemaTreeNode({\n kind: 'root',\n id: 'sql-schema',\n label: 'database',\n ...(tableNodes.length > 0 ? { children: tableNodes } : {}),\n }),\n };\n },\n };\n}\n","import type {\n ControlFamilyDescriptor,\n ControlStack,\n} from '@prisma-next/framework-components/control';\nimport type { EmissionSpi } from '@prisma-next/framework-components/emission';\nimport { sqlEmission } from '@prisma-next/sql-contract-emitter';\nimport { sqlFamilyEntityTypes, sqlFamilyPslBlockDescriptors } from './authoring-entity-types';\nimport { sqlFamilyAuthoringFieldPresets } from './authoring-field-presets';\nimport { sqlFamilyAuthoringTypes } from './authoring-type-constructors';\nimport { createSqlFamilyInstance, type SqlControlFamilyInstance } from './control-instance';\n\nexport class SqlFamilyDescriptor\n implements ControlFamilyDescriptor<'sql', SqlControlFamilyInstance>\n{\n readonly kind = 'family' as const;\n readonly id = 'sql';\n readonly familyId = 'sql' as const;\n readonly version = '0.0.1';\n readonly emission: EmissionSpi = sqlEmission;\n readonly authoring = {\n field: sqlFamilyAuthoringFieldPresets,\n type: sqlFamilyAuthoringTypes,\n entityTypes: sqlFamilyEntityTypes,\n pslBlockDescriptors: sqlFamilyPslBlockDescriptors,\n } as const;\n\n create<TTargetId extends string>(\n stack: ControlStack<'sql', TTargetId>,\n ): SqlControlFamilyInstance {\n return createSqlFamilyInstance(stack);\n }\n}\n","import type { ColumnDefault, Contract, JsonValue } from '@prisma-next/contract/types';\nimport type { CodecRef } from '@prisma-next/framework-components/codec';\nimport type {\n MigrationPlannerConflict,\n SchemaNodeRef,\n} from '@prisma-next/framework-components/control';\nimport {\n type CheckConstraint,\n type ForeignKey,\n type Index,\n isStorageTypeInstance,\n type SqlStorage,\n type StorageColumn,\n StorageTable,\n type StorageTypeInstance,\n type UniqueConstraint,\n} from '@prisma-next/sql-contract/types';\nimport {\n RelationalSchemaNodeKind,\n type SqlAnnotations,\n type SqlCheckConstraintIRInput,\n type SqlColumnIRInput,\n type SqlForeignKeyIRInput,\n type SqlIndexIRInput,\n SqlSchemaIR,\n SqlTableIR,\n type SqlUniqueIRInput,\n} from '@prisma-next/sql-schema-ir/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\n/**\n * Target-specific callback that expands a column's base `nativeType` and optional\n * `typeParams` into the fully-qualified type string used by the database\n * (e.g. `character` + `{ length: 36 }` → `character(36)`).\n *\n * This lives in the family layer as a callback rather than importing a concrete\n * implementation because each target (Postgres, MySQL, SQLite, …) has its own\n * parameterization syntax. The target wires its expander when calling\n * `contractToSchemaIR`, keeping the family layer target-agnostic.\n */\nexport type NativeTypeExpander = (input: {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n}) => string;\n\n/**\n * Target-specific callback that renders a `ColumnDefault` into the raw SQL literal\n * string stored in `SqlColumnIR.default`.\n *\n * Default value serialization is target-specific (quoting, casting, type syntax vary\n * between Postgres, MySQL, SQLite, …). This callback follows the same IoC pattern as\n * `NativeTypeExpander`: the target provides its renderer when calling\n * `contractToSchemaIR`, keeping the family layer target-agnostic.\n */\nexport type DefaultRenderer = (def: ColumnDefault, column: StorageColumn) => string;\n\n/**\n * Target-supplied hook (same IoC seam as `NativeTypeExpander`/`DefaultRenderer`)\n * that normalizes a contract-declared `ColumnDefault` into the resolved shape\n * the target's introspection parses from the live database — e.g. a\n * `dbgenerated(\"'{}'::jsonb\")` function call and the literal Postgres reports\n * are the same value in different shapes, and `resolvedDefaultsEqual`\n * compares `kind` before content. When omitted, the contract's raw default\n * is the resolved default unchanged.\n */\nexport type DefaultResolver = (def: ColumnDefault, resolvedNativeType: string) => ColumnDefault;\n\n/**\n * Target-supplied callback that resolves a contract namespace to the live\n * database schema its enums are stored under.\n *\n * The projected enum annotations are nested by schema\n * (`storageTypes[schema][nativeType]`) so two namespaces holding an enum with\n * the same native type resolve to distinct live-database types. Mapping a\n * namespace to its DDL schema is target-specific (Postgres schemas;\n * SQLite/MySQL differ), so the target injects it here rather than the family\n * importing a concrete `ddlSchemaName`. This keeps the family layer\n * target-agnostic while the projection nests under the same schema the\n * target's read side (`readExistingEnumValues`) looks up.\n */\nexport type EnumNamespaceSchemaResolver = (storage: SqlStorage, namespaceId: string) => string;\n\nfunction convertColumn(\n name: string,\n column: StorageColumn,\n storageTypes: ResolvedStorageTypes,\n expandNativeType: NativeTypeExpander | undefined,\n renderDefault: DefaultRenderer | undefined,\n resolveDefault: DefaultResolver | undefined,\n): SqlColumnIRInput {\n // Resolve `typeRef` so columns that delegate their `nativeType`/`codecId`/\n // `typeParams` to a named `storage.types` entry expand the same way as\n // columns that inline those fields. Without this resolution, a\n // `typeRef`-based column like `post.embedding → Embedding1536` would\n // render as the bare `\"vector\"` (dropping the `length` parameter), while\n // `verify-sql-schema.ts`'s `renderExpectedNativeType` resolves the\n // typeRef and produces `\"vector(1536)\"` — making diffs on the same\n // contract falsely report a `type_mismatch`.\n const resolved = resolveColumnTypeMetadata(column, storageTypes);\n const baseNativeType = expandNativeType\n ? expandNativeType({\n nativeType: resolved.nativeType,\n codecId: resolved.codecId,\n ...ifDefined('typeParams', resolved.typeParams),\n })\n : resolved.nativeType;\n // `many: true` columns keep `nativeType` as the bare element type (matching\n // how the introspected/\"actual\" side reports it — see the postgres control\n // adapter's own `many`-stripping normalization) and carry the array-ness in\n // the separate `many` field instead of baking `[]` into `nativeType`.\n // Baking it in here (`\"text[]\"`) made every `@@` list-typed column\n // permanently mismatch against a live introspected column reporting\n // `{ nativeType: \"text\", many: true }`, regardless of whether the two are\n // otherwise identical — `db verify` reported every such column\n // `not-equal`. `resolvedNativeType` still carries the full `\"text[]\"`\n // form: it is the side both this and the introspected column already\n // agree on as the comparable \"expanded\" type.\n const nativeType = baseNativeType;\n const resolvedNativeType = column.many ? `${baseNativeType}[]` : baseNativeType;\n const rawColumnDefault = column.default ?? undefined;\n const resolvedColumnDefault =\n rawColumnDefault !== undefined && resolveDefault\n ? resolveDefault(rawColumnDefault, resolvedNativeType)\n : rawColumnDefault;\n return {\n name,\n nativeType,\n nullable: column.nullable,\n ...ifDefined('many', column.many),\n ...ifDefined(\n 'default',\n column.default != null && renderDefault ? renderDefault(column.default, column) : undefined,\n ),\n // Contract-derived columns are resolved by construction: the computed\n // full native type doubles as the resolved value. The contract's raw\n // structured default becomes the resolved default after passing through\n // the target's `resolveDefault` hook (when supplied), so a default the\n // target's introspection side would normalize differently (e.g. a\n // `dbgenerated(...)` function call that is actually a literal) compares\n // equal instead of drifting on `kind` alone.\n resolvedNativeType,\n ...ifDefined('resolvedDefault', resolvedColumnDefault),\n // The column's codec identity, carried the same way the query AST\n // carries `CodecRef` (TML-2456) — the migration planner's op-builders\n // resolve DDL rendering from this at plan time (Decision 5), instead of\n // reading a derivation-precomputed render payload.\n codecRef: buildColumnCodecRef(resolved, column.many),\n codecBaseNativeType: resolved.nativeType,\n ...(column.typeRef !== undefined ? { codecNamedType: true } : {}),\n };\n}\n\n/**\n * Builds the column's `CodecRef` from its resolved (post-`typeRef`) codec\n * identity — the same construction the query AST and the migration DDL\n * renderer already use (TML-2456, TML-2918).\n */\nfunction buildColumnCodecRef(\n resolved: Pick<StorageColumn, 'codecId' | 'nativeType' | 'typeParams'>,\n many: boolean | undefined,\n): CodecRef {\n return {\n codecId: resolved.codecId,\n ...ifDefined(\n 'typeParams',\n resolved.typeParams !== undefined\n ? blindCast<\n JsonValue,\n 'resolved.typeParams is JsonValue-shaped storage metadata; the narrowed (non-undefined) value lands in CodecRef.typeParams which is JsonValue'\n >(resolved.typeParams)\n : undefined,\n ),\n ...ifDefined('many', many),\n };\n}\n\ntype ResolvedStorageTypes = Readonly<Record<string, StorageTypeInstance>>;\n\nfunction resolveColumnTypeMetadata(\n column: StorageColumn,\n storageTypes: ResolvedStorageTypes,\n): Pick<StorageColumn, 'codecId' | 'nativeType' | 'typeParams'> {\n if (!column.typeRef) {\n return column;\n }\n const referenced = storageTypes[column.typeRef];\n if (!referenced) {\n throw new Error(\n `Column references storage type \"${column.typeRef}\" but it is not defined in storage.types.`,\n );\n }\n if (isStorageTypeInstance(referenced)) {\n return {\n codecId: referenced.codecId,\n nativeType: referenced.nativeType,\n typeParams: referenced.typeParams,\n };\n }\n throw new Error(\n `Storage type \"${column.typeRef}\" has an unknown polymorphic kind; expected a codec-typed StorageTypeInstance.`,\n );\n}\n\n/**\n * Resolves a `ValueSetRef` to its permitted values from the contract storage.\n *\n * Throws when the referenced namespace or value-set is absent — this indicates\n * the contract was built incorrectly (the check and the value-set must be\n * co-emitted by the lowering step). Used by `convertCheck` (schema-IR\n * projection), `verifyCheckConstraints` (verification), and\n * `checkConstraintPlanCallStrategy` (migration planning) so all three agree on\n * the resolved values and the error behavior on a missing reference.\n */\nfunction allStrings(values: readonly JsonValue[]): values is readonly string[] {\n return values.every((value) => typeof value === 'string');\n}\n\nexport function resolveValueSetValues(\n ref: { readonly namespaceId: string; readonly entityName: string },\n storage: SqlStorage,\n contextLabel: string,\n): readonly string[] {\n const ns = storage.namespaces[ref.namespaceId];\n if (!ns) {\n throw new Error(\n `resolveValueSetValues: namespace \"${ref.namespaceId}\" not found in storage (${contextLabel})`,\n );\n }\n const valueSet = ns.entries.valueSet?.[ref.entityName];\n if (!valueSet) {\n throw new Error(\n `resolveValueSetValues: value-set \"${ref.entityName}\" not found in namespace \"${ref.namespaceId}\" (${contextLabel})`,\n );\n }\n // Only TEXT enums ship a CHECK-constraint round-trip in this slice. A\n // non-string value-set is a numeric enum, whose CHECK rendering/verification\n // is future work; fail loudly rather than emit a wrong numeric-as-text check.\n const values = valueSet.values;\n if (!allStrings(values)) {\n throw new Error(\n `resolveValueSetValues: value-set \"${ref.entityName}\" in namespace \"${ref.namespaceId}\" has a non-string value; numeric-enum CHECK constraints are not yet supported (${contextLabel})`,\n );\n }\n return values;\n}\n\n/**\n * Projects a `CheckConstraint` IR into an `SqlCheckConstraintIRInput` by\n * resolving the permitted values from the storage value-set it references.\n *\n * The `CheckConstraint.valueSet` ref points to\n * `storage.namespaces[namespaceId].entries.valueSet[name]`. The resolved\n * values are lifted directly from `StorageValueSet.values` so verification\n * compares value sets, not SQL predicate strings.\n *\n * Throws if the referenced namespace or value-set is absent — this\n * indicates the contract was built incorrectly (the check and the\n * value-set must be co-emitted by the lowering step).\n */\nfunction convertCheck(check: CheckConstraint, storage: SqlStorage): SqlCheckConstraintIRInput {\n const permittedValues = resolveValueSetValues(check.valueSet, storage, `check \"${check.name}\"`);\n return {\n name: check.name,\n column: check.column,\n permittedValues,\n };\n}\n\nfunction convertUnique(unique: UniqueConstraint, tableName: string): SqlUniqueIRInput {\n return {\n columns: unique.columns,\n ...ifDefined('name', unique.name),\n dependsOn: flatColumnDependsOn(tableName, unique.columns),\n };\n}\n\nfunction convertIndex(\n index: Index,\n tableName: string,\n tableColumns: readonly string[],\n): SqlIndexIRInput {\n const base = {\n name: index.name,\n prefix: index.prefix,\n where: index.where,\n unique: index.unique,\n partial: index.where !== undefined,\n // Carried so the derived index node compares type/options against the\n // introspected side (the legacy walk read them from the contract).\n type: index.type,\n options: index.options,\n annotations: undefined,\n // An expression index's chains cover every column of its table — the\n // opaque expression is never parsed, so this deterministic\n // over-approximation keeps drops ordered without a SQL parser.\n dependsOn: flatColumnDependsOn(tableName, index.columns ?? tableColumns),\n };\n return index.expression !== undefined\n ? { ...base, expression: index.expression }\n : { ...base, columns: index.columns ?? [] };\n}\n\n/**\n * The referenced table's chain in the flat (single-schema) tree\n * `contractToSchemaIR`/`contractNamespaceToSchemaIR` build: the root\n * (`SqlSchemaIR`, fixed `'database'` id) followed by the table's own id.\n * Postgres discards this when it re-derives the FK against its own\n * multi-schema tree shape (`contractToPostgresDatabaseSchemaNode`); SQLite's\n * flat tree uses it as-is.\n */\nfunction flatSchemaDependsOn(tableName: string): SchemaNodeRef {\n return [\n { nodeKind: RelationalSchemaNodeKind.schema, id: 'database' },\n { nodeKind: RelationalSchemaNodeKind.table, id: tableName },\n ];\n}\n\n/**\n * The chains from a table-child object (foreign key, index, unique, primary\n * key) to each of the own columns it is built on, in the flat tree. Dropping\n * a covered column auto-drops the object, so the object's drop must precede\n * the column's; the graph derives that direction from these edges.\n */\nfunction flatColumnDependsOn(\n tableName: string,\n columns: readonly string[],\n): readonly SchemaNodeRef[] {\n return columns.map((column) => [\n { nodeKind: RelationalSchemaNodeKind.schema, id: 'database' },\n { nodeKind: RelationalSchemaNodeKind.table, id: tableName },\n { nodeKind: RelationalSchemaNodeKind.column, id: `column:${column}` },\n ]);\n}\n\n/**\n * The FK's referenced-namespace identity comes from the target's namespace\n * node, not the raw namespace-id string. An unbound target namespace stamps\n * no `referencedSchema` at all — the FK node's id renders the absence as the\n * empty segment, which is what flat (single-schema) introspection produces,\n * so both diff sides' FK ids meet by construction. A bound namespace (or a\n * cross-space target whose namespace lives in another contract's storage)\n * stamps its coordinate verbatim; namespaced targets (Postgres) resolve the\n * real DDL schema downstream.\n *\n * `dependsOn` carries the referenced table (created before the FK, dropped\n * after it) plus the FK's own columns (dropped after the FK, since dropping a\n * column auto-drops the FK built on it).\n */\nfunction convertForeignKey(fk: ForeignKey, storage: SqlStorage): SqlForeignKeyIRInput {\n const targetNamespace = storage.namespaces[fk.target.namespaceId];\n const targetIsUnbound = targetNamespace?.isUnbound === true;\n return {\n columns: fk.source.columns,\n referencedTable: fk.target.tableName,\n ...(targetIsUnbound ? {} : { referencedSchema: fk.target.namespaceId }),\n referencedColumns: fk.target.columns,\n ...ifDefined('name', fk.name),\n ...ifDefined('onDelete', fk.onDelete),\n ...ifDefined('onUpdate', fk.onUpdate),\n dependsOn: [\n flatSchemaDependsOn(fk.target.tableName),\n ...flatColumnDependsOn(fk.source.tableName, fk.source.columns),\n ],\n };\n}\n\nfunction convertTable(\n name: string,\n table: StorageTable,\n storageTypes: ResolvedStorageTypes,\n expandNativeType: NativeTypeExpander | undefined,\n renderDefault: DefaultRenderer | undefined,\n resolveDefault: DefaultResolver | undefined,\n storage: SqlStorage,\n): SqlTableIR {\n const columns: Record<string, SqlColumnIRInput> = {};\n for (const [colName, colDef] of Object.entries(table.columns)) {\n columns[colName] = convertColumn(\n colName,\n colDef,\n storageTypes,\n expandNativeType,\n renderDefault,\n resolveDefault,\n );\n }\n\n const checks: SqlCheckConstraintIRInput[] | undefined =\n table.checks && table.checks.length > 0\n ? table.checks.map((c) => convertCheck(c, storage))\n : undefined;\n\n const primaryKey =\n table.primaryKey !== undefined\n ? {\n columns: table.primaryKey.columns,\n ...ifDefined('name', table.primaryKey.name),\n dependsOn: flatColumnDependsOn(name, table.primaryKey.columns),\n }\n : undefined;\n\n return new SqlTableIR({\n name,\n columns,\n ...ifDefined('primaryKey', primaryKey),\n // #989 persists a `constraint: false` FK's absence and its backing index as\n // discrete entities at contract construction, so every `foreignKeys[]` entry\n // is now constraint-bearing (no filter) and each FK-backing index is already\n // a `table.indexes[]` entry — it flows through `convertIndex` below, carrying\n // the object→own-column `dependsOn` edge like any other index.\n foreignKeys: table.foreignKeys.map((fk) => convertForeignKey(fk, storage)),\n uniques: table.uniques.map((u) => convertUnique(u, name)),\n indexes: table.indexes.map((i) => convertIndex(i, name, Object.keys(table.columns))),\n ...ifDefined('checks', checks),\n });\n}\n\n/**\n * Detects destructive changes between two contract storages.\n *\n * The additive-only planner silently ignores removals (tables, columns).\n * This function detects those removals so callers can report them as conflicts\n * rather than silently producing an empty plan.\n *\n * Returns an empty array if no destructive changes are found.\n */\nexport function detectDestructiveChanges(\n from: SqlStorage | null,\n to: SqlStorage,\n): readonly MigrationPlannerConflict[] {\n if (!from) return [];\n\n const hasOwn = (value: object, key: string): boolean => Object.hasOwn(value, key);\n\n const conflicts: MigrationPlannerConflict[] = [];\n\n const namespaceIds = [\n ...new Set([...Object.keys(from.namespaces), ...Object.keys(to.namespaces)]),\n ].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n\n for (const namespaceId of namespaceIds) {\n const fromNs = from.namespaces[namespaceId];\n const toNs = to.namespaces[namespaceId];\n const fromTables = fromNs?.entries.table;\n if (!fromTables) continue;\n\n for (const tableName of Object.keys(fromTables)) {\n const toTableRaw = toNs?.entries.table?.[tableName];\n if (!StorageTable.is(toTableRaw)) {\n conflicts.push({\n kind: 'tableRemoved',\n summary: `Table \"${tableName}\" was removed`,\n });\n continue;\n }\n const toTable = toTableRaw;\n\n const fromTableRaw = fromTables[tableName];\n if (!StorageTable.is(fromTableRaw)) continue;\n const fromTable = fromTableRaw;\n\n for (const columnName of Object.keys(fromTable.columns)) {\n if (!hasOwn(toTable.columns, columnName)) {\n conflicts.push({\n kind: 'columnRemoved',\n summary: `Column \"${tableName}\".\"${columnName}\" was removed`,\n });\n }\n }\n }\n }\n\n return conflicts;\n}\n\nexport interface ContractToSchemaIROptions {\n readonly annotationNamespace: string;\n readonly expandNativeType?: NativeTypeExpander;\n readonly renderDefault?: DefaultRenderer;\n readonly resolveDefault?: DefaultResolver;\n /**\n * Target-supplied resolver mapping a namespace to the live database schema\n * its enums are stored under. When provided (Postgres), namespace-scoped\n * enums are nested by that schema in `enumTypes` so the projection matches\n * the target's `readExistingEnumValues` lookup. Targets without\n * schema-scoped enum storage (SQLite) omit it; enums are absent there.\n */\n readonly resolveEnumNamespaceSchema?: EnumNamespaceSchemaResolver;\n}\n\n/**\n * Converts a `Contract` to `SqlSchemaIR`.\n *\n * Reads `contract.storage` for tables and `contract.storage.types` for type\n * annotations. Storage-type annotations are written under\n * `options.annotationNamespace`.\n *\n * Drops codec metadata (`codecId`, `typeRef`) since the schema IR only represents\n * structural information. When `expandNativeType` is provided, parameterized types\n * are expanded (e.g. `character` + `{ length: 36 }` → `character(36)`) so the\n * resulting IR compares correctly against the \"to\" contract during planning.\n *\n * Returns an empty schema IR when `contract` is `null` (new project).\n */\n/**\n * Converts the tables of a single namespace into a `SqlSchemaIR`, keyed by\n * table name within that namespace. Unlike {@link contractToSchemaIR}, which\n * flattens every namespace's tables into one bare-keyed record (and throws on a\n * cross-namespace name collision), this scopes the table iteration to one\n * namespace so the same table name can exist in two schemas.\n *\n * The full `storage` is still passed to `convertTable`, so value-set / enum /\n * type resolution that legitimately spans namespaces is unaffected. Foreign\n * keys are built purely from the FK descriptor (`fk.target`), so cross-namespace\n * FKs survive per-namespace conversion. The `annotations` block (storage-type\n * derived) is omitted here — the per-namespace tree consumer reads only the\n * per-table fields.\n */\nexport function contractNamespaceToSchemaIR(\n storage: SqlStorage,\n namespaceId: string,\n options: ContractToSchemaIROptions,\n): SqlSchemaIR {\n if (options.annotationNamespace.length === 0) {\n throw new Error('annotationNamespace must be a non-empty string');\n }\n const namespace = storage.namespaces[namespaceId];\n if (!namespace) {\n return new SqlSchemaIR({ tables: {} });\n }\n const storageTypes: ResolvedStorageTypes = { ...(storage.types ?? {}) };\n const tables: Record<string, SqlTableIR> = {};\n for (const [tableName, tableDefRaw] of Object.entries(namespace.entries.table ?? {})) {\n StorageTable.assert(tableDefRaw, `namespaces.${namespaceId}.entries.table.${tableName}`);\n tables[tableName] = convertTable(\n tableName,\n tableDefRaw,\n storageTypes,\n options.expandNativeType,\n options.renderDefault,\n options.resolveDefault,\n storage,\n );\n }\n return new SqlSchemaIR({ tables });\n}\n\nexport function contractToSchemaIR(\n contract: Contract<SqlStorage> | null,\n options: ContractToSchemaIROptions,\n): SqlSchemaIR {\n if (options.annotationNamespace.length === 0) {\n throw new Error('annotationNamespace must be a non-empty string');\n }\n\n if (!contract) {\n return new SqlSchemaIR({ tables: {} });\n }\n\n const storage = contract.storage;\n const storageTypes: ResolvedStorageTypes = { ...(storage.types ?? {}) };\n const tables: Record<string, SqlTableIR> = {};\n for (const ns of Object.values(storage.namespaces)) {\n for (const [tableName, tableDefRaw] of Object.entries(ns.entries.table ?? {})) {\n StorageTable.assert(tableDefRaw, `namespaces.${ns.id}.entries.table.${tableName}`);\n const tableDef = tableDefRaw;\n if (tables[tableName] !== undefined) {\n throw new Error(\n `contractToSchemaIR: duplicate SQL table name \"${tableName}\" across namespaces (ambiguous for flat SqlSchemaIR.tables).`,\n );\n }\n tables[tableName] = convertTable(\n tableName,\n tableDef,\n storageTypes,\n options.expandNativeType,\n options.renderDefault,\n options.resolveDefault,\n storage,\n );\n }\n }\n\n const annotations = deriveAnnotations(\n storage,\n options.annotationNamespace,\n options.resolveEnumNamespaceSchema,\n );\n\n return new SqlSchemaIR({\n tables,\n ...ifDefined('annotations', annotations),\n });\n}\n\nfunction deriveAnnotations(\n storage: SqlStorage,\n annotationNamespace: string,\n _resolveEnumNamespaceSchema: EnumNamespaceSchemaResolver | undefined,\n): SqlAnnotations | undefined {\n const storageTypes: Record<string, StorageTypeInstance> = {};\n\n for (const typeInstance of Object.values(storage.types ?? {})) {\n if (isStorageTypeInstance(typeInstance)) {\n storageTypes[typeInstance.nativeType] = typeInstance;\n }\n }\n\n const envelope = {\n ...(Object.keys(storageTypes).length > 0 ? { storageTypes } : {}),\n };\n if (Object.keys(envelope).length === 0) return undefined;\n return { [annotationNamespace]: envelope };\n}\n","import {\n type Contract,\n type ControlPolicy,\n effectiveControlPolicy,\n} from '@prisma-next/contract/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\n/**\n * The target object a control policy governs for a single planner call,\n * resolved from the target's own IR. `undefined` means the call's target\n * object could not be positively established — a fail-closed signal: any\n * policy stricter than `managed` drops such a call rather than emitting it.\n *\n * The object identity is a generic storage coordinate — `(entityKind,\n * entityName)`, absent for a whole-namespace subject — never a target-specific\n * `table`/`typeName` field. The family reasons about the coordinate for policy\n * and deduplication; the target owns any vocabulary (table vs enum) when it\n * renders a suppression.\n */\nexport interface ControlPolicySubject {\n readonly namespaceId: string;\n readonly entityKind?: string;\n readonly entityName?: string;\n readonly column?: string;\n readonly explicitNodeControlPolicy?: ControlPolicy;\n /**\n * Whether the call creates a whole, previously-absent top-level storage\n * object (e.g. a table or an enum/type), as opposed to modifying an\n * existing object. This is the only thing `tolerated` permits: it is a\n * create-if-absent policy, so an op that touches an existing object — add\n * column, add index/constraint, alter, drop — is never allowed under it.\n */\n readonly createsNewObject: boolean;\n}\n\n/**\n * The structured record a control-policy partition emits for one suppressed\n * subject or call. It carries only raw data — no strings, no vocabulary — so\n * the consumer (the target) renders the user-facing message itself:\n *\n * - `subject` — the suppressed subject (its coordinate + namespace), or\n * `undefined` when the subject could not be resolved (fail-closed).\n * - `policy` — the effective control policy that caused the suppression.\n * - `factoryName` — the resolved creation factory name if the suppressed thing\n * was a whole-object creation (e.g. `createTable`), else `undefined`. The\n * family never invents a verb for a modification that produced no call.\n * - `createsNewObject` — whether the suppressed thing was object creation.\n */\nexport interface SuppressionRecord {\n readonly subject: ControlPolicySubject | undefined;\n readonly policy: ControlPolicy;\n readonly factoryName: string | undefined;\n readonly createsNewObject: boolean;\n}\n\n/**\n * The control policy that governs a single call. The `external` default is an\n * un-overridable namespace floor: when the contract default is `external`, no\n * per-object `managed` override can escalate DDL above the floor, so the\n * policy is forced to `external` regardless of the node's own declaration.\n * Every other default defers to the node's effective control policy.\n */\nexport function controlPolicyForCall(\n subject: ControlPolicySubject | undefined,\n defaultControlPolicy: ControlPolicy | undefined,\n): ControlPolicy {\n if (defaultControlPolicy === 'external') {\n return 'external';\n }\n return effectiveControlPolicy(subject?.explicitNodeControlPolicy, defaultControlPolicy);\n}\n\n/**\n * Whether a call is allowed to emit under a given control policy.\n *\n * - `managed` — full lifecycle, every op allowed.\n * - `tolerated` — create-if-absent only: allowed iff the call creates a whole\n * new top-level object (and its subject was positively resolved). Anything\n * that modifies an existing object, and anything whose subject could not be\n * resolved, is suppressed.\n * - `external` / `observed` — no DDL at all.\n */\nfunction callAllowedUnderControlPolicy(\n policy: ControlPolicy,\n subject: ControlPolicySubject | undefined,\n): boolean {\n switch (policy) {\n case 'managed':\n return true;\n case 'tolerated':\n return subject?.createsNewObject === true;\n case 'external':\n case 'observed':\n return false;\n }\n}\n\n/**\n * Partition the calls produced for a single set of subjects into those the\n * effective control policy permits (`kept`) and a list of\n * {@link SuppressionRecord}s describing the suppressed calls.\n *\n * **Prefer {@link partitionIssuesByControlPolicy}** for the schema-issue\n * pipeline: it filters subjects out of the planner's *input* so the planner\n * never has to reason about un-modeled state on `external`/`observed`\n * subjects. This call-level helper remains for paths that bypass the issue\n * pipeline — currently the codec-emitted field-event ops, which originate\n * from declared contract fields rather than from introspected schema state\n * and therefore cannot trip the diff engine.\n */\nexport function partitionCallsByControlPolicy<TCall>(options: {\n readonly calls: readonly TCall[];\n readonly contract: Contract<SqlStorage>;\n readonly resolveControlPolicySubject: (call: TCall) => ControlPolicySubject | undefined;\n readonly resolveFactoryName: (call: TCall) => string;\n}): {\n readonly kept: readonly TCall[];\n readonly suppressions: readonly SuppressionRecord[];\n} {\n const defaultControlPolicy = options.contract.defaultControlPolicy;\n const kept: TCall[] = [];\n const suppressions: SuppressionRecord[] = [];\n\n for (const call of options.calls) {\n const subject = options.resolveControlPolicySubject(call);\n const policy = controlPolicyForCall(subject, defaultControlPolicy);\n if (callAllowedUnderControlPolicy(policy, subject)) {\n kept.push(call);\n } else {\n suppressions.push({\n subject,\n policy,\n factoryName: options.resolveFactoryName(call),\n createsNewObject: subject?.createsNewObject ?? false,\n });\n }\n }\n\n return Object.freeze({\n kept: Object.freeze(kept),\n suppressions: Object.freeze(suppressions),\n });\n}\n\n/**\n * Partition a list of schema-issue-shaped inputs by the effective control\n * policy of each issue's subject *before* the planner is invoked.\n *\n * `plannable` is the list of issues whose subject's effective policy permits\n * the planner to act on them (`managed`, or `tolerated` for whole-object\n * creation issues only). Issues for `external`/`observed` subjects, and\n * non-creation issues for `tolerated` subjects, are dropped from the planner's\n * input entirely — they never enter introspection-driven planning, never feed\n * the diff engine, and never produce DDL calls that would have to be\n * post-filtered. This sidesteps a class of failure where the diff engine\n * cannot reason about the live shape of a subject the user marked as\n * out-of-scope (`external`).\n *\n * `suppressions` is one {@link SuppressionRecord} per suppressed subject (not\n * per suppressed issue). Its `factoryName` is the creation factory name when any\n * of the subject's issues is whole-object creation (e.g. `createTable`), else\n * `undefined` — the family never invents a modification verb for an op that\n * produced no call; the target renders the message.\n *\n * Unresolved-subject issues (`resolveControlPolicySubject` returns\n * `undefined`) emit one record each; they cannot be deduplicated because they\n * carry no subject coordinate.\n */\nexport function partitionIssuesByControlPolicy<TIssue>(options: {\n readonly issues: readonly TIssue[];\n readonly contract: Contract<SqlStorage>;\n /**\n * Resolve the subject targeted by this issue (or `undefined` to fail-closed:\n * any policy stricter than `managed` drops the issue).\n */\n readonly resolveControlPolicySubject: (issue: TIssue) => ControlPolicySubject | undefined;\n /**\n * Resolve a creation factoryName for this issue if it represents the\n * absence of the whole top-level object (e.g. `'createTable'` for a\n * missing-table issue). When the issue describes a modification to an\n * existing object, return `undefined`. Both decisions feed off this signal:\n *\n * 1. Under `tolerated`, only issues whose `resolveCreationFactoryName`\n * returns a value flow into the planner (create-if-absent).\n * 2. A suppressed subject's record carries the resolved creation factoryName\n * when it has at least one creation-flavoured issue, else `undefined`.\n */\n readonly resolveCreationFactoryName: (issue: TIssue) => string | undefined;\n}): {\n readonly plannable: readonly TIssue[];\n readonly suppressions: readonly SuppressionRecord[];\n} {\n const defaultControlPolicy = options.contract.defaultControlPolicy;\n\n const plannable: TIssue[] = [];\n // Resolved-subject suppressions are deduplicated by subject key so we emit\n // one record per suppressed subject, not one per suppressed issue.\n // `creationFactoryName` upgrades from `undefined` to a concrete creation\n // name the first time we see a creation-flavoured issue for the subject.\n const suppressedSubjects = new Map<\n string,\n {\n readonly subject: ControlPolicySubject;\n readonly policy: ControlPolicy;\n creationFactoryName?: string;\n }\n >();\n const unresolvedSuppressions: SuppressionRecord[] = [];\n\n for (const issue of options.issues) {\n const subject = options.resolveControlPolicySubject(issue);\n const policy = controlPolicyForCall(subject, defaultControlPolicy);\n const creationFactoryName = options.resolveCreationFactoryName(issue);\n\n if (policy === 'managed') {\n plannable.push(issue);\n continue;\n }\n if (\n policy === 'tolerated' &&\n subject !== undefined &&\n creationFactoryName !== undefined &&\n subject.createsNewObject\n ) {\n plannable.push(issue);\n continue;\n }\n\n if (subject === undefined) {\n unresolvedSuppressions.push({\n subject: undefined,\n policy,\n factoryName: creationFactoryName,\n createsNewObject: false,\n });\n continue;\n }\n\n const key = subjectKey(subject);\n const existing = suppressedSubjects.get(key);\n if (existing) {\n if (existing.creationFactoryName === undefined && creationFactoryName !== undefined) {\n existing.creationFactoryName = creationFactoryName;\n }\n } else {\n suppressedSubjects.set(key, {\n subject,\n policy,\n ...ifDefined('creationFactoryName', creationFactoryName),\n });\n }\n }\n\n const suppressions: SuppressionRecord[] = [...unresolvedSuppressions];\n for (const entry of suppressedSubjects.values()) {\n suppressions.push({\n subject: entry.subject,\n policy: entry.policy,\n factoryName: entry.creationFactoryName,\n createsNewObject: entry.subject.createsNewObject,\n });\n }\n\n return Object.freeze({\n plannable: Object.freeze(plannable),\n suppressions: Object.freeze(suppressions),\n });\n}\n\nfunction subjectKey(subject: ControlPolicySubject): string {\n return `${subject.namespaceId}\\u0000${subject.entityKind ?? ''}\\u0000${subject.entityName ?? ''}`;\n}\n","/**\n * Codec lifecycle hook planner — runs `onFieldEvent` for every per-field\n * delta between two contracts and concatenates the returned ops in a\n * deterministic order.\n *\n * Wired by each target's planner (`PostgresMigrationPlanner`,\n * `SqliteMigrationPlanner`) so codec-emitted ops are inlined alongside\n * structural DDL in the app-space migration's `ops.json`. Pure, target-\n * agnostic, and only ever invoked at the app-space emitter; extension-space\n * planning never reaches this helper.\n *\n * Ordering rules (see ADR 213):\n *\n * - Events are grouped by phase: `'added'` → `'dropped'` → `'altered'`.\n * - Within each phase, entries are sorted alphabetically by\n * `(namespaceId, tableName, fieldName)`.\n * - The hook's returned ops are appended in the order the hook returned them.\n *\n * `'altered'` is suppressed when only `codecId` differs (codec rotation is a\n * v1 non-goal).\n *\n * See: `docs/architecture docs/adrs/ADR 213 - Codec lifecycle hooks.md`.\n */\n\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { OpFactoryCall } from '@prisma-next/framework-components/control';\nimport { type SqlStorage, type StorageColumn, StorageTable } from '@prisma-next/sql-contract/types';\nimport type { CodecControlHooks, FieldEvent, FieldEventContext } from './types';\n\nexport interface PlanFieldEventOperationsOptions {\n /**\n * Prior contract the planner is diffing against. `null` for first emits\n * (every field is treated as added).\n */\n readonly priorContract: Contract<SqlStorage> | null;\n /**\n * New contract the user just authored.\n */\n readonly newContract: Contract<SqlStorage>;\n /**\n * Codec-id keyed map of control hooks, as produced by\n * {@link import('./assembly').extractCodecControlHooks}. Hooks carry\n * `unknown` target details after extraction; the caller casts the\n * helper's returned ops to its target's `SqlMigrationPlanOperation`\n * specialisation at the integration boundary, mirroring how\n * `storageTypePlanCallStrategy` lifts `planTypeOperations` results into\n * `RawSqlCall`.\n */\n readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;\n}\n\ninterface FieldEntry {\n readonly namespaceId: string;\n readonly tableName: string;\n readonly fieldName: string;\n readonly priorTable: StorageTable | undefined;\n readonly newTable: StorageTable | undefined;\n readonly priorField: StorageColumn | undefined;\n readonly newField: StorageColumn | undefined;\n}\n\nexport function planFieldEventOperations(\n options: PlanFieldEventOperationsOptions,\n): readonly OpFactoryCall[] {\n const priorContract = options.priorContract;\n const newContract = options.newContract;\n\n const added: FieldEntry[] = [];\n const dropped: FieldEntry[] = [];\n const altered: FieldEntry[] = [];\n\n const namespaceIds = unionSorted(\n priorContract ? Object.keys(priorContract.storage.namespaces) : [],\n Object.keys(newContract.storage.namespaces),\n );\n\n for (const namespaceId of namespaceIds) {\n const priorNs = priorContract?.storage.namespaces[namespaceId];\n const newNs = newContract.storage.namespaces[namespaceId];\n const priorTables = priorNs?.entries.table;\n const newTables = newNs?.entries.table;\n\n const tableNames = unionSorted(\n priorTables ? Object.keys(priorTables) : [],\n newTables ? Object.keys(newTables) : [],\n );\n\n for (const tableName of tableNames) {\n const priorTableRaw = priorTables?.[tableName];\n const newTableRaw = newTables?.[tableName];\n const priorTable = StorageTable.is(priorTableRaw) ? priorTableRaw : undefined;\n const newTable = StorageTable.is(newTableRaw) ? newTableRaw : undefined;\n const fieldNames = unionSorted(\n priorTable ? Object.keys(priorTable.columns) : [],\n newTable ? Object.keys(newTable.columns) : [],\n );\n for (const fieldName of fieldNames) {\n const priorField = priorTable?.columns[fieldName];\n const newField = newTable?.columns[fieldName];\n const entry: FieldEntry = {\n namespaceId,\n tableName,\n fieldName,\n priorTable,\n newTable,\n priorField,\n newField,\n };\n if (priorField === undefined && newField !== undefined) {\n added.push(entry);\n } else if (priorField !== undefined && newField === undefined) {\n dropped.push(entry);\n } else if (priorField !== undefined && newField !== undefined) {\n if (isAlteration(priorField, newField)) altered.push(entry);\n }\n }\n }\n }\n\n const calls: OpFactoryCall[] = [];\n appendCalls('added', added, options.codecHooks, calls, (e) => e.newField?.codecId);\n appendCalls('dropped', dropped, options.codecHooks, calls, (e) => e.priorField?.codecId);\n appendCalls('altered', altered, options.codecHooks, calls, (e) => e.newField?.codecId);\n return calls;\n}\n\nfunction appendCalls(\n event: FieldEvent,\n entries: readonly FieldEntry[],\n codecHooks: ReadonlyMap<string, CodecControlHooks>,\n calls: OpFactoryCall[],\n pickCodecId: (entry: FieldEntry) => string | undefined,\n): void {\n for (const entry of entries) {\n const codecId = pickCodecId(entry);\n if (codecId === undefined) continue;\n const hook = codecHooks.get(codecId);\n if (!hook?.onFieldEvent) continue;\n const ctx = buildContext(event, entry);\n const emitted = hook.onFieldEvent(event, ctx);\n for (const call of emitted) calls.push(call);\n }\n}\n\n/**\n * The context's prior/new sides are scoped to the event:\n *\n * - `'added'` — only `newTable` / `newField` populated.\n * - `'dropped'` — only `priorTable` / `priorField` populated.\n * - `'altered'` — both sides populated.\n */\nfunction buildContext(event: FieldEvent, entry: FieldEntry): FieldEventContext {\n const base = {\n namespaceId: entry.namespaceId,\n tableName: entry.tableName,\n fieldName: entry.fieldName,\n };\n if (event === 'added') {\n return {\n ...base,\n ...(entry.newTable !== undefined ? { newTable: entry.newTable } : {}),\n ...(entry.newField !== undefined ? { newField: entry.newField } : {}),\n };\n }\n if (event === 'dropped') {\n return {\n ...base,\n ...(entry.priorTable !== undefined ? { priorTable: entry.priorTable } : {}),\n ...(entry.priorField !== undefined ? { priorField: entry.priorField } : {}),\n };\n }\n return {\n ...base,\n ...(entry.priorTable !== undefined ? { priorTable: entry.priorTable } : {}),\n ...(entry.newTable !== undefined ? { newTable: entry.newTable } : {}),\n ...(entry.priorField !== undefined ? { priorField: entry.priorField } : {}),\n ...(entry.newField !== undefined ? { newField: entry.newField } : {}),\n };\n}\n\n/**\n * `'altered'` predicate. Returns `false` whenever `codecId` differs —\n * any codec change suppresses the `altered` event entirely, including\n * cases where another property also differs in the same diff. Codec\n * rotation is a v1 non-goal; avoiding the mixed event keeps the\n * migration semantics for codec changes explicit rather than smuggling\n * them through as `altered`.\n *\n * For non-`codecId` diffs, returns `true` iff any other column property\n * differs.\n */\nfunction isAlteration(prior: StorageColumn, current: StorageColumn): boolean {\n if (prior.codecId !== current.codecId) return false;\n return !sameStorageColumn(prior, current);\n}\n\nfunction sameStorageColumn(a: StorageColumn, b: StorageColumn): boolean {\n if (a === b) return true;\n if (a.nativeType !== b.nativeType) return false;\n if (a.nullable !== b.nullable) return false;\n if (a.typeRef !== b.typeRef) return false;\n if (!sameJson(a.typeParams, b.typeParams)) return false;\n if (!sameJson(a.default, b.default)) return false;\n return true;\n}\n\nfunction sameJson(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\nfunction unionSorted(a: readonly string[], b: readonly string[]): readonly string[] {\n const set = new Set<string>();\n for (const name of a) set.add(name);\n for (const name of b) set.add(name);\n return [...set].sort((x, y) => (x < y ? -1 : x > y ? 1 : 0));\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport { extractCodecControlHooks } from '../assembly';\n\n/**\n * Builds the codec-hook-composed `expandNativeType` callback the contract→IR\n * derivation uses to expand parameterized native types (e.g. `character` +\n * `{ length: 36 }` → `character(36)`). Returns `undefined` when no framework\n * components are supplied, so callers can omit the option entirely.\n */\nexport function buildNativeTypeExpander(\n frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n) {\n if (!frameworkComponents) {\n return undefined;\n }\n const codecHooks = extractCodecControlHooks(frameworkComponents);\n return (input: {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n }) => {\n if (!input.typeParams) return input.nativeType;\n if (!input.codecId) return input.nativeType;\n const hooks = codecHooks.get(input.codecId);\n if (!hooks?.expandNativeType) return input.nativeType;\n return hooks.expandNativeType(input);\n };\n}\n","import type { NotOk, Ok } from '@prisma-next/utils/result';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport type {\n AnyRecord,\n CreateSqlMigrationPlanOptions,\n SqlMigrationPlan,\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n SqlMigrationPlanOperationTarget,\n SqlMigrationRunnerErrorCode,\n SqlMigrationRunnerFailure,\n SqlMigrationRunnerSuccessValue,\n SqlPlannerConflict,\n SqlPlannerFailureResult,\n SqlPlannerSuccessResult,\n} from './types';\n\nconst readOnlyEmptyObject: Record<string, never> = Object.freeze({});\n\nfunction cloneRecord<T extends AnyRecord>(value: T): T {\n if (value === readOnlyEmptyObject) {\n return value;\n }\n return Object.freeze({ ...value }) as T;\n}\n\nfunction freezeSteps(\n steps: readonly SqlMigrationPlanOperationStep[],\n): readonly SqlMigrationPlanOperationStep[] {\n if (steps.length === 0) {\n return Object.freeze([]);\n }\n return Object.freeze(\n steps.map((step) =>\n Object.freeze({\n description: step.description,\n sql: step.sql,\n ...(step.params ? { params: Object.freeze([...step.params]) } : {}),\n ...(step.meta ? { meta: cloneRecord(step.meta) } : {}),\n }),\n ),\n );\n}\n\nfunction freezeDetailsValue<T>(value: T): T {\n // Primitives and null/undefined are already immutable, return as-is\n if (value === null || value === undefined) {\n return value;\n }\n if (typeof value !== 'object') {\n return value;\n }\n // Arrays: shallow clone and freeze\n if (Array.isArray(value)) {\n return Object.freeze([...value]) as T;\n }\n // Objects: shallow clone and freeze (matching cloneRecord pattern)\n return Object.freeze({ ...value }) as T;\n}\n\nfunction freezeTargetDetails<TTargetDetails>(\n target: SqlMigrationPlanOperationTarget<TTargetDetails>,\n): SqlMigrationPlanOperationTarget<TTargetDetails> {\n return Object.freeze({\n id: target.id,\n ...(target.details !== undefined ? { details: freezeDetailsValue(target.details) } : {}),\n });\n}\n\nfunction freezeOperation<TTargetDetails>(\n operation: SqlMigrationPlanOperation<TTargetDetails>,\n): SqlMigrationPlanOperation<TTargetDetails> {\n return Object.freeze({\n id: operation.id,\n label: operation.label,\n ...(operation.summary ? { summary: operation.summary } : {}),\n operationClass: operation.operationClass,\n ...(operation.invariantId ? { invariantId: operation.invariantId } : {}),\n target: freezeTargetDetails(operation.target),\n precheck: freezeSteps(operation.precheck),\n execute: freezeSteps(operation.execute),\n postcheck: freezeSteps(operation.postcheck),\n ...(operation.meta ? { meta: cloneRecord(operation.meta) } : {}),\n });\n}\n\nfunction freezeOperations<TTargetDetails>(\n operations: readonly SqlMigrationPlanOperation<TTargetDetails>[],\n): readonly SqlMigrationPlanOperation<TTargetDetails>[] {\n if (operations.length === 0) {\n return Object.freeze([]);\n }\n return Object.freeze(operations.map((operation) => freezeOperation(operation)));\n}\n\nexport function createMigrationPlan<TTargetDetails>(\n options: CreateSqlMigrationPlanOptions<TTargetDetails>,\n): SqlMigrationPlan<TTargetDetails> {\n return Object.freeze({\n targetId: options.targetId,\n spaceId: options.spaceId,\n ...(options.origin !== undefined\n ? { origin: options.origin ? Object.freeze({ ...options.origin }) : null }\n : {}),\n destination: Object.freeze({ ...options.destination }),\n operations: freezeOperations(options.operations),\n providedInvariants: Object.freeze([...options.providedInvariants]),\n ...(options.meta ? { meta: cloneRecord(options.meta) } : {}),\n });\n}\n\nexport function plannerSuccess<TTargetDetails>(\n plan: SqlMigrationPlan<TTargetDetails>,\n warnings?: readonly SqlPlannerConflict[],\n): SqlPlannerSuccessResult<TTargetDetails> {\n return Object.freeze({\n kind: 'success',\n plan,\n ...(warnings && warnings.length > 0\n ? {\n warnings: Object.freeze(\n warnings.map((conflict) =>\n Object.freeze({\n kind: conflict.kind,\n summary: conflict.summary,\n ...(conflict.why ? { why: conflict.why } : {}),\n ...(conflict.location ? { location: Object.freeze({ ...conflict.location }) } : {}),\n ...(conflict.meta ? { meta: cloneRecord(conflict.meta) } : {}),\n }),\n ),\n ),\n }\n : {}),\n });\n}\n\nexport function plannerFailure(conflicts: readonly SqlPlannerConflict[]): SqlPlannerFailureResult {\n return Object.freeze({\n kind: 'failure' as const,\n conflicts: Object.freeze(\n conflicts.map((conflict) =>\n Object.freeze({\n kind: conflict.kind,\n summary: conflict.summary,\n ...(conflict.why ? { why: conflict.why } : {}),\n ...(conflict.location ? { location: Object.freeze({ ...conflict.location }) } : {}),\n ...(conflict.meta ? { meta: cloneRecord(conflict.meta) } : {}),\n }),\n ),\n ),\n });\n}\n\n/**\n * Creates a successful migration runner result.\n */\nexport function runnerSuccess(value: {\n operationsPlanned: number;\n operationsExecuted: number;\n}): Ok<SqlMigrationRunnerSuccessValue> {\n return ok(\n Object.freeze({\n operationsPlanned: value.operationsPlanned,\n operationsExecuted: value.operationsExecuted,\n }),\n );\n}\n\n/**\n * Creates a failed migration runner result.\n */\nexport function runnerFailure(\n code: SqlMigrationRunnerErrorCode,\n summary: string,\n options?: { why?: string; meta?: AnyRecord },\n): NotOk<SqlMigrationRunnerFailure> {\n const failure: SqlMigrationRunnerFailure = Object.freeze({\n code,\n summary,\n ...(options?.why ? { why: options.why } : {}),\n ...(options?.meta ? { meta: cloneRecord(options.meta) } : {}),\n });\n return notOk(failure);\n}\n","import type { MigrationOperationPolicy } from '@prisma-next/framework-components/control';\n\n/**\n * Policy used by `db init`: additive-only operations, no widening/destructive steps.\n */\nexport const INIT_ADDITIVE_POLICY: MigrationOperationPolicy = Object.freeze({\n allowedOperationClasses: Object.freeze(['additive'] as const),\n});\n","import { SqlFamilyDescriptor } from '../core/control-descriptor';\n\n// Re-export core types from canonical source\nexport type {\n MigrationOperationClass,\n MigrationOperationPolicy,\n MigrationPlan,\n MigrationPlanner,\n MigrationPlannerConflict,\n MigrationPlannerResult,\n MigrationPlanOperation,\n TargetMigrationsCapability,\n} from '@prisma-next/framework-components/control';\nexport { assembleAuthoringContributions } from '@prisma-next/framework-components/control';\nexport { extractCodecControlHooks } from '../core/assembly';\nexport type { SqlControlFamilyInstance } from '../core/control-instance';\nexport type {\n SqlControlTargetDescriptor,\n SqlDescribedContractSpace,\n} from '../core/control-target-descriptor';\nexport type {\n ContractToSchemaIROptions,\n DefaultRenderer,\n DefaultResolver,\n EnumNamespaceSchemaResolver,\n NativeTypeExpander,\n} from '../core/migrations/contract-to-schema-ir';\n// Contract → SchemaIR conversion for offline migration planning\nexport {\n contractNamespaceToSchemaIR,\n contractToSchemaIR,\n detectDestructiveChanges,\n resolveValueSetValues,\n} from '../core/migrations/contract-to-schema-ir';\nexport type { ControlPolicySubject, SuppressionRecord } from '../core/migrations/control-policy';\nexport {\n controlPolicyForCall,\n partitionCallsByControlPolicy,\n partitionIssuesByControlPolicy,\n} from '../core/migrations/control-policy';\nexport type { PlanFieldEventOperationsOptions } from '../core/migrations/field-event-planner';\nexport { planFieldEventOperations } from '../core/migrations/field-event-planner';\nexport { buildNativeTypeExpander } from '../core/migrations/native-type-expander';\nexport {\n createMigrationPlan,\n plannerFailure,\n plannerSuccess,\n runnerFailure,\n runnerSuccess,\n} from '../core/migrations/plan-helpers';\nexport { INIT_ADDITIVE_POLICY } from '../core/migrations/policies';\nexport type {\n SqlSchemaDiffFn,\n SqlSchemaDiffInput,\n SqlSchemaDiffResult,\n} from '../core/migrations/schema-differ';\nexport type {\n CodecControlHooks,\n CreateSqlMigrationPlanOptions,\n ExpandNativeTypeInput,\n FieldEvent,\n FieldEventContext,\n ResolveIdentityValueInput,\n SqlControlAdapterDescriptor,\n SqlControlExtensionDescriptor,\n SqlMigrationPlan,\n SqlMigrationPlanContractInfo,\n SqlMigrationPlanner,\n SqlMigrationPlannerPlanOptions,\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n SqlMigrationPlanOperationTarget,\n SqlMigrationRunner,\n SqlMigrationRunnerErrorCode,\n SqlMigrationRunnerExecuteCallbacks,\n SqlMigrationRunnerExecuteOptions,\n SqlMigrationRunnerFailure,\n SqlMigrationRunnerResult,\n SqlMigrationRunnerSuccessValue,\n SqlPlannerConflict,\n SqlPlannerConflictKind,\n SqlPlannerConflictLocation,\n SqlPlannerFailureResult,\n SqlPlannerResult,\n SqlPlannerSuccessResult,\n SqlPlanTargetDetails,\n StorageTypePlanResult,\n} from '../core/migrations/types';\nexport {\n temporalAuthoringPresets,\n temporalCodecPreset,\n temporalCodecPresetWithPrecision,\n timestampNowControlDescriptor,\n} from '../core/timestamp-now-generator';\n\nexport default new SqlFamilyDescriptor();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"control.mjs","names":[],"sources":["../src/core/operation-preview.ts","../src/core/control-instance.ts","../src/core/control-descriptor.ts","../src/core/migrations/contract-to-schema-ir.ts","../src/core/migrations/control-policy.ts","../src/core/migrations/field-event-planner.ts","../src/core/migrations/native-type-expander.ts","../src/core/migrations/plan-helpers.ts","../src/core/migrations/policies.ts","../src/exports/control.ts"],"sourcesContent":["import type {\n MigrationPlanOperation,\n OperationPreview,\n} from '@prisma-next/framework-components/control';\n\n/**\n * Shape of an SQL execute step on `SqlMigrationPlanOperation`. Used for runtime\n * type narrowing without importing the concrete SQL type.\n */\ninterface SqlExecuteStep {\n readonly sql: string;\n}\n\nfunction isDdlStatement(sqlStatement: string): boolean {\n const trimmed = sqlStatement.trim().toLowerCase();\n return (\n trimmed.startsWith('create ') || trimmed.startsWith('alter ') || trimmed.startsWith('drop ')\n );\n}\n\nfunction hasExecuteSteps(\n operation: MigrationPlanOperation,\n): operation is MigrationPlanOperation & { readonly execute: readonly SqlExecuteStep[] } {\n const candidate = operation as unknown as Record<string, unknown>;\n if (!('execute' in candidate) || !Array.isArray(candidate['execute'])) {\n return false;\n }\n return candidate['execute'].every(\n (step: unknown) => typeof step === 'object' && step !== null && 'sql' in step,\n );\n}\n\n/**\n * Extracts a best-effort SQL DDL preview for CLI plan output.\n * Presentation-only: never used to decide migration correctness.\n */\nexport function extractSqlDdl(operations: readonly MigrationPlanOperation[]): string[] {\n const statements: string[] = [];\n for (const operation of operations) {\n if (!hasExecuteSteps(operation)) {\n continue;\n }\n for (const step of operation.execute) {\n if (typeof step.sql === 'string' && isDdlStatement(step.sql)) {\n statements.push(step.sql.trim());\n }\n }\n }\n return statements;\n}\n\n/**\n * Wraps `extractSqlDdl` into the family-agnostic `OperationPreview` shape.\n * Each statement carries `language: 'sql'`.\n */\nexport function sqlOperationsToPreview(\n operations: readonly MigrationPlanOperation[],\n): OperationPreview {\n return {\n statements: extractSqlDdl(operations).map((text) => ({ text, language: 'sql' })),\n };\n}\n","import type {\n Contract,\n ContractMarkerRecord,\n LedgerEntryRecord,\n} from '@prisma-next/contract/types';\nimport type {\n TargetBoundComponentDescriptor,\n TargetDescriptor,\n} from '@prisma-next/framework-components/components';\nimport type {\n ControlFamilyInstance,\n ControlStack,\n CoreSchemaView,\n DiffSubjectGranularity,\n MigrationPlanOperation,\n OperationPreview,\n OperationPreviewCapable,\n PslContractInferCapable,\n SchemaDiffIssue,\n SchemaViewCapable,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n APP_SPACE_ID,\n SchemaTreeNode,\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport type { TypesImportSpec } from '@prisma-next/framework-components/emission';\nimport { isPlainRecord } from '@prisma-next/framework-components/ir';\nimport type { PslDocumentAst } from '@prisma-next/framework-components/psl-ast';\nimport { assertDescriptorSelfConsistency } from '@prisma-next/migration-tools/spaces';\nimport { sqlContractCanonicalizationHooks } from '@prisma-next/sql-contract/canonicalization-hooks';\nimport type { SqlControlDriverInstance, SqlStorage } from '@prisma-next/sql-contract/types';\nimport type {\n AnyQueryAst,\n DdlNode,\n LowererContext,\n SqlExecuteRequest,\n} from '@prisma-next/sql-relational-core/ast';\nimport type { SqlSchemaIRNode, SqlTableIR } from '@prisma-next/sql-schema-ir/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { InternalError } from '@prisma-next/utils/internal-error';\nimport type { StructuredError } from '@prisma-next/utils/structured-error';\nimport type { SqlControlAdapter } from './control-adapter';\nimport type {\n SqlControlTargetDescriptor,\n SqlDescribedContractSpace,\n} from './control-target-descriptor';\nimport {\n classifyDiffEntityKind,\n classifyDiffSubjectGranularity,\n verifySqlSchemaByDiff,\n} from './diff/schema-verify';\nimport { sqlFamilyError } from './errors';\nimport { SqlContractSerializer } from './ir/sql-contract-serializer';\nimport type { SqlSchemaDiffFn } from './migrations/schema-differ';\nimport type {\n SqlControlAdapterDescriptor,\n SqlControlExtensionDescriptor,\n} from './migrations/types';\nimport { sqlOperationsToPreview } from './operation-preview';\nimport { collectSupportedCodecTypeIds } from './verify';\n\nfunction missingDescriptorOperationError(targetId: string, operation: string): StructuredError {\n return sqlFamilyError(\n 'CONTRACT.PACK_CONTRIBUTION_INVALID',\n `SQL target \"${targetId}\" is missing the required ${operation} descriptor operation`,\n {\n why: `The target descriptor does not contribute the ${operation} operation the SQL family requires for this call.`,\n fix: `Use a target package whose control descriptor implements ${operation}.`,\n meta: { targetId, operation },\n },\n );\n}\n\nfunction extractCodecTypeIdsFromContract(contract: unknown): readonly string[] {\n const typeIds = new Set<string>();\n\n // Type guard for SQL contract structure\n if (\n typeof contract === 'object' &&\n contract !== null &&\n 'storage' in contract &&\n typeof contract.storage === 'object' &&\n contract.storage !== null &&\n 'namespaces' in contract.storage &&\n typeof contract.storage.namespaces === 'object' &&\n contract.storage.namespaces !== null\n ) {\n const namespaces = contract.storage.namespaces as Record<\n string,\n { readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>> }\n >;\n for (const ns of Object.values(namespaces)) {\n const tbls = ns.entries['table'];\n if (typeof tbls !== 'object' || tbls === null) continue;\n for (const table of Object.values(tbls)) {\n if (\n typeof table === 'object' &&\n table !== null &&\n 'columns' in table &&\n typeof table.columns === 'object' &&\n table.columns !== null\n ) {\n const columns = table.columns as Record<string, { codecId: string } | undefined>;\n for (const column of Object.values(columns)) {\n if (\n column &&\n typeof column === 'object' &&\n 'codecId' in column &&\n typeof column.codecId === 'string'\n ) {\n typeIds.add(column.codecId);\n }\n }\n }\n }\n }\n }\n\n return Array.from(typeIds).sort();\n}\n\nfunction createVerifyResult(options: {\n ok: boolean;\n code?: string;\n summary: string;\n contractStorageHash: string;\n contractProfileHash?: string;\n marker?: ContractMarkerRecord;\n expectedTargetId: string;\n actualTargetId?: string;\n missingCodecs?: readonly string[];\n codecCoverageSkipped?: boolean;\n configPath?: string;\n contractPath: string;\n totalTime: number;\n}): VerifyDatabaseResult {\n const contract: { storageHash: string; profileHash?: string } = {\n storageHash: options.contractStorageHash,\n };\n if (options.contractProfileHash) {\n contract.profileHash = options.contractProfileHash;\n }\n\n const target: { expected: string; actual?: string } = {\n expected: options.expectedTargetId,\n };\n if (options.actualTargetId) {\n target.actual = options.actualTargetId;\n }\n\n const meta: { contractPath: string; configPath?: string } = {\n contractPath: options.contractPath,\n };\n if (options.configPath) {\n meta.configPath = options.configPath;\n }\n\n const result: VerifyDatabaseResult = {\n ok: options.ok,\n summary: options.summary,\n contract,\n target,\n meta,\n timings: {\n total: options.totalTime,\n },\n };\n\n if (options.code) {\n (result as { code?: string }).code = options.code;\n }\n\n if (options.marker) {\n (result as { marker?: { storageHash: string; profileHash: string } }).marker = {\n storageHash: options.marker.storageHash,\n profileHash: options.marker.profileHash,\n };\n }\n\n if (options.missingCodecs) {\n (result as { missingCodecs?: readonly string[] }).missingCodecs = options.missingCodecs;\n }\n\n if (options.codecCoverageSkipped) {\n (result as { codecCoverageSkipped?: boolean }).codecCoverageSkipped =\n options.codecCoverageSkipped;\n }\n\n return result;\n}\n\ninterface SqlTypeMetadata {\n readonly typeId: string;\n readonly familyId: 'sql';\n readonly targetId: string;\n readonly nativeType?: string;\n}\n\ntype SqlTypeMetadataRegistry = Map<string, SqlTypeMetadata>;\n\ninterface SqlFamilyInstanceState {\n readonly codecTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly extensionIds: ReadonlyArray<string>;\n readonly typeMetadataRegistry: SqlTypeMetadataRegistry;\n}\n\nexport interface SqlControlFamilyInstance\n extends ControlFamilyInstance<'sql', SqlSchemaIRNode>,\n SchemaViewCapable<SqlSchemaIRNode>,\n PslContractInferCapable<SqlSchemaIRNode>,\n OperationPreviewCapable,\n SqlFamilyInstanceState {\n /**\n * The family seam-of-record for on-disk contract reads. Structurally\n * validates the JSON envelope, then hydrates IR-class instances via\n * the per-target ContractSerializer. The single named entry point\n * every CLI on-disk read crosses (TML-2536) — `as Contract` casts\n * in production package sources are a serializer-bypass smell guarded\n * by `pnpm lint:no-contract-cast`.\n */\n deserializeContract(contractJson: unknown): Contract;\n\n verify(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult>;\n\n /**\n * Verify a contract against an already-introspected schema.\n *\n * Callers that need to verify against the live database compose\n * `introspect({ driver })` + `verifySchema({ contract, schema, ... })`.\n * The aggregate verifier hands in the full introspected schema and scopes\n * the returned result to each member's contract space afterwards — so\n * sibling-space tables never survive as `extras`.\n */\n verifySchema(options: {\n readonly contract: unknown;\n readonly schema: SqlSchemaIRNode;\n readonly strict: boolean;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n }): VerifyDatabaseSchemaResult;\n\n /**\n * Classifies a diff issue's subject granularity on demand, resolved from\n * its node's `nodeKind` via the target's classifier. Satisfies the\n * {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}\n * capability that framework consumers spanning contract spaces (the\n * migration aggregate's unclaimed-elements sweep) detect via\n * `hasSchemaSubjectClassifier` and call instead of reading family/target\n * node vocabulary. Nothing is stamped on the issue or the node.\n */\n classifySubjectGranularity(issue: SchemaDiffIssue): DiffSubjectGranularity | undefined;\n\n /**\n * Classifies a diff issue's subject storage `entityKind` on demand,\n * resolved from its node's `nodeKind` via the target's classifier —\n * sibling of `classifySubjectGranularity` above, part of the same\n * {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}\n * capability. Nothing is stamped on the issue or the node.\n */\n classifyEntityKind(issue: SchemaDiffIssue): string | undefined;\n\n sign(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult>;\n\n introspect(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract?: unknown;\n }): Promise<SqlSchemaIRNode>;\n\n inferPslContract(schemaIR: SqlSchemaIRNode): PslDocumentAst;\n\n lowerAst(\n ast: AnyQueryAst | DdlNode,\n context: LowererContext<unknown>,\n ): Promise<SqlExecuteRequest>;\n\n /**\n * Inserts the initial marker row for `space` (upsert on `space`).\n * Delegates to the target control adapter's write SPI; see\n * `SqlControlAdapter.initMarker`.\n */\n initMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n };\n }): Promise<void>;\n\n /**\n * Compare-and-swap advance of the marker row for `space`. Returns `true`\n * when the swap matched a row; see `SqlControlAdapter.updateMarker`.\n */\n updateMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly expectedFrom: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n };\n }): Promise<boolean>;\n\n /**\n * Appends a ledger entry for `space`; see\n * `SqlControlAdapter.writeLedgerEntry`.\n */\n writeLedgerEntry(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n readonly migrationName: string;\n readonly migrationHash: string;\n readonly operations: readonly unknown[];\n readonly destinationContractJson?: unknown;\n };\n }): Promise<void>;\n\n bootstrapControlTableQueries(): readonly DdlNode[];\n\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview;\n}\n\nexport type SqlFamilyInstance = SqlControlFamilyInstance;\n\ninterface DescriptorWithStorageTypes {\n readonly targetId?: string | undefined;\n readonly types?:\n | {\n readonly storage?:\n | ReadonlyArray<{\n readonly typeId: string;\n readonly familyId: string;\n readonly targetId: string;\n readonly nativeType?: string | undefined;\n }>\n | undefined;\n }\n | undefined;\n}\n\nfunction buildSqlTypeMetadataRegistry(options: {\n readonly target: DescriptorWithStorageTypes;\n readonly adapter: DescriptorWithStorageTypes & { readonly targetId: string };\n readonly extensions: readonly DescriptorWithStorageTypes[];\n}): SqlTypeMetadataRegistry {\n const { target, adapter, extensions } = options;\n const registry = new Map<string, SqlTypeMetadata>();\n const targetId = adapter.targetId;\n const descriptors = [target, adapter, ...extensions];\n\n for (const descriptor of descriptors) {\n const types = descriptor.types;\n const storageTypes = types?.storage;\n\n if (!storageTypes) {\n continue;\n }\n\n for (const storageType of storageTypes) {\n if (storageType.familyId === 'sql' && storageType.targetId === targetId) {\n registry.set(storageType.typeId, {\n typeId: storageType.typeId,\n familyId: 'sql',\n targetId: storageType.targetId,\n ...(storageType.nativeType !== undefined ? { nativeType: storageType.nativeType } : {}),\n });\n }\n }\n }\n\n return registry;\n}\n\ninterface CrossSpaceFkView {\n readonly id: string;\n readonly contractSpace?: {\n readonly contractJson?: {\n readonly extensions?: Readonly<Record<string, unknown>>;\n readonly storage?: {\n readonly namespaces?: Readonly<Record<string, unknown>>;\n };\n };\n };\n}\n\n/**\n * Builds a map from each extension id to the set of extension ids it\n * transitively depends on. Uses the same declared-dependency data that\n * `buildExtensionLoadOrder` in control-stack uses.\n */\nfunction buildTransitiveDependsOnMap(\n extensions: readonly CrossSpaceFkView[],\n): Map<string, Set<string>> {\n const directDeps = new Map<string, readonly string[]>();\n for (const ext of extensions) {\n const packs = ext.contractSpace?.contractJson?.extensions;\n const deps = packs !== null && typeof packs === 'object' ? Object.keys(packs) : [];\n directDeps.set(ext.id, deps);\n }\n\n const result = new Map<string, Set<string>>();\n const resolve = (id: string, visiting: Set<string>): Set<string> => {\n const cached = result.get(id);\n if (cached !== undefined) return cached;\n const set = new Set<string>();\n result.set(id, set);\n for (const depId of directDeps.get(id) ?? []) {\n set.add(depId);\n if (!visiting.has(depId)) {\n visiting.add(depId);\n for (const transitive of resolve(depId, visiting)) {\n set.add(transitive);\n }\n visiting.delete(depId);\n }\n }\n return set;\n };\n\n for (const ext of extensions) {\n resolve(ext.id, new Set([ext.id]));\n }\n return result;\n}\n\n/**\n * Asserts that no cross-space FK in any extension points against the\n * dependency direction.\n *\n * A cross-space FK (target.spaceId present) from extension A pointing at\n * space B is a violation when B depends on A (directly or transitively),\n * because that means A is pointing \"upward\" against the dependency arrows\n * established by the extension load order.\n *\n * Throws with a diagnostic naming the violating extension (source), the\n * target space, and the direction violation.\n */\nfunction isObjectRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null;\n}\n\nexport function assertNoCrossSpaceFkReverseReferences(\n extensions: readonly CrossSpaceFkView[],\n): void {\n const dependsOnMap = buildTransitiveDependsOnMap(extensions);\n\n for (const ext of extensions) {\n const namespaces = ext.contractSpace?.contractJson?.storage?.namespaces;\n if (!isObjectRecord(namespaces)) continue;\n for (const ns of Object.values(namespaces)) {\n if (!isObjectRecord(ns)) continue;\n const entries = ns['entries'];\n if (!isObjectRecord(entries)) continue;\n for (const slot of Object.values(entries)) {\n if (!isObjectRecord(slot)) continue;\n for (const table of Object.values(slot)) {\n if (!isObjectRecord(table)) continue;\n const foreignKeys = table['foreignKeys'];\n if (!Array.isArray(foreignKeys)) continue;\n for (const fk of foreignKeys) {\n if (!isObjectRecord(fk)) continue;\n const target = fk['target'];\n if (!isObjectRecord(target)) continue;\n if (target['spaceId'] === undefined) continue;\n const targetSpaceId = target['spaceId'];\n if (typeof targetSpaceId !== 'string') continue;\n // Check if targetSpaceId depends on ext.id (directly or transitively)\n const targetDeps = dependsOnMap.get(targetSpaceId);\n if (targetDeps?.has(ext.id)) {\n throw sqlFamilyError(\n 'CONTRACT.FOREIGN_KEY_INVALID',\n `Cross-space FK reverse-reference detected: extension \"${ext.id}\" has a cross-space FK targeting space \"${targetSpaceId}\", but \"${targetSpaceId}\" depends on \"${ext.id}\". Cross-space FKs must follow the dependency direction (a space can only reference spaces it depends on, not spaces that depend on it).`,\n {\n why: 'The foreign key points against the contract-space dependency direction.',\n fix: 'Move the foreign key to the depending space, or restructure the extension dependencies so the referencing space depends on the referenced one.',\n meta: { extensionId: ext.id, targetSpaceId },\n },\n );\n }\n }\n }\n }\n }\n }\n}\n\nexport function createSqlFamilyInstance<TTargetId extends string>(\n stack: ControlStack<'sql', TTargetId>,\n): SqlFamilyInstance {\n if (!stack.adapter) {\n throw new InternalError('SQL family requires an adapter descriptor in ControlStack');\n }\n\n const target = stack.target as unknown as TargetDescriptor<'sql', TTargetId> &\n DescriptorWithStorageTypes;\n const adapter = stack.adapter as unknown as SqlControlAdapterDescriptor<TTargetId> &\n DescriptorWithStorageTypes;\n const extensions =\n stack.extensions as unknown as readonly (SqlControlExtensionDescriptor<TTargetId> &\n DescriptorWithStorageTypes)[];\n\n // Descriptor self-consistency check.\n // Each extension that exposes a `contractSpace` must publish a\n // `headRef.hash` that matches the canonical hash recomputed from its\n // `contractJson`. A stale value would silently corrupt every downstream\n // boundary that trusts `headRef.hash` as the canonical identity (drift\n // detection, on-disk artefact emission, runner marker writes). Failing\n // fast at descriptor-load time turns \"extension author shipped an\n // inconsistent descriptor\" into an explicit, actionable error\n // (`MIGRATION.DESCRIPTOR_HEAD_HASH_MISMATCH`) rather than a confusing\n // mismatch surfacing several layers downstream.\n for (const extension of extensions) {\n if (extension.contractSpace) {\n const { contractJson, headRef } = extension.contractSpace;\n assertDescriptorSelfConsistency({\n extensionId: extension.id,\n target: contractJson.target,\n targetFamily: contractJson.targetFamily,\n storage: contractJson.storage,\n headRefHash: headRef.hash,\n ...sqlContractCanonicalizationHooks,\n });\n }\n }\n\n assertNoCrossSpaceFkReverseReferences(extensions);\n\n const { codecTypeImports, extensionIds } = stack;\n\n const typeMetadataRegistry = buildSqlTypeMetadataRegistry({\n target,\n adapter,\n extensions: extensions,\n });\n\n // Lazily construct the control adapter on first use, then memoize it.\n // Merely building a family instance must not instantiate the adapter —\n // that would change the load/instantiate semantics of the whole stack\n // wherever a family is created (every CLI command, emit, verify, …), not\n // just the migration paths that actually need it. Memoizing also avoids\n // the previous per-operation re-instantiation (a fresh adapter on every\n // call). Family-instance methods accept `SqlControlDriverInstance<string>`\n // (the family API isn't generic on the target id); the adapter\n // descriptor's `create` returns the concrete `SqlControlAdapter<TTargetId>`,\n // widened to `string` to match the family-level driver type without a\n // per-method probe.\n let controlAdapter: SqlControlAdapter<string> | undefined;\n const getControlAdapter = (): SqlControlAdapter<string> =>\n (controlAdapter ??= adapter.create(stack));\n\n const targetSerializer = (\n target as unknown as {\n contractSerializer?: {\n deserializeContract(json: unknown): Contract<SqlStorage>;\n serializeContract(contract: Contract<SqlStorage>): unknown;\n };\n }\n ).contractSerializer;\n // Database→PSL inference is target logic (it owns the dialect type/default\n // maps and walks its own schema tree), so it is read off the descriptor like\n // `contractSerializer`. Absent for targets without `contract infer` (Mongo).\n const targetInferPslContract = blindCast<\n SqlControlTargetDescriptor<TTargetId, unknown>,\n 'reading the optional target-descriptor inferPslContract hook'\n >(target).inferPslContract;\n // The full-tree node diff the verify VERDICT derives from. Read lazily so\n // construction-only stub descriptors (schema-view tests) keep working; the\n // throw happens at verify time.\n const diffSchema = blindCast<\n { readonly diffSchema?: SqlSchemaDiffFn },\n 'reading the target-descriptor diffSchema hook'\n >(target).diffSchema;\n // The target's nodeKind → granularity classifier, resolved on demand by the\n // verdict and by the instance's `classifySubjectGranularity` method below —\n // never stamped onto an issue. Read lazily for the same\n // construction-only-stub reason as `diffSchema`; the throw happens at call\n // time.\n const targetGranularityOf = blindCast<\n { readonly classifySubjectGranularity?: (nodeKind: string) => DiffSubjectGranularity },\n 'reading the target-descriptor classifySubjectGranularity hook'\n >(target).classifySubjectGranularity;\n // The target's nodeKind → storage entityKind classifier — sibling of\n // `targetGranularityOf` above, read the same lazy way for the same\n // construction-only-stub reason.\n const targetEntityKindOf = blindCast<\n { readonly classifyEntityKind?: (nodeKind: string) => string | undefined },\n 'reading the target-descriptor classifyEntityKind hook'\n >(target).classifyEntityKind;\n // `contract infer` needs each extension pack's already-assembled contract,\n // carried as-is (no merging — that is the contract-spaces machinery's\n // concern), paired with the `spaceId` its descriptor was registered under\n // (neither the contract JSON nor `ContractSpace` self-declares it), so the\n // target hook can omit elements those contracts describe and qualify a\n // cross-space relation with the owning pack's space id.\n const describedContracts: readonly SqlDescribedContractSpace[] = extensions.flatMap(\n (extension) =>\n extension.contractSpace\n ? [{ spaceId: extension.id, contract: extension.contractSpace.contractJson }]\n : [],\n );\n const deserializeWithTargetSerializer = (contractOrJson: unknown): Contract<SqlStorage> => {\n const serializer = targetSerializer ?? new SqlContractSerializer();\n const json =\n targetSerializer !== undefined && !isPlainRecord(contractOrJson)\n ? targetSerializer.serializeContract(\n blindCast<\n Contract<SqlStorage>,\n 'isPlainRecord returned false, so contractOrJson is a class instance, not raw JSON'\n >(contractOrJson),\n )\n : contractOrJson;\n return serializer.deserializeContract(json) as Contract<SqlStorage>;\n };\n\n return {\n familyId: 'sql',\n codecTypeImports,\n extensionIds,\n typeMetadataRegistry,\n\n deserializeContract(contractJson: unknown): Contract {\n return deserializeWithTargetSerializer(contractJson);\n },\n\n async verify(verifyOptions: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult> {\n const {\n driver,\n contract: rawContract,\n expectedTargetId,\n contractPath,\n configPath,\n } = verifyOptions;\n const startTime = Date.now();\n\n const contract = deserializeWithTargetSerializer(rawContract) as Contract<SqlStorage>;\n\n const contractStorageHash = contract.storage.storageHash;\n const contractProfileHash = contract.profileHash;\n const contractTarget = contract.target;\n\n const marker = await getControlAdapter().readMarker(driver, APP_SPACE_ID);\n\n let missingCodecs: readonly string[] | undefined;\n let codecCoverageSkipped = false;\n const supportedTypeIds = collectSupportedCodecTypeIds([adapter, target, ...extensions]);\n if (supportedTypeIds.length === 0) {\n codecCoverageSkipped = true;\n } else {\n const supportedSet = new Set(supportedTypeIds);\n const usedTypeIds = extractCodecTypeIdsFromContract(contract);\n const missing = usedTypeIds.filter((id) => !supportedSet.has(id));\n if (missing.length > 0) {\n missingCodecs = missing;\n }\n }\n\n if (!marker) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: VERIFY_CODE_MARKER_MISSING,\n summary: 'Marker missing',\n contractStorageHash,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n if (contractTarget !== expectedTargetId) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: VERIFY_CODE_TARGET_MISMATCH,\n summary: 'Target mismatch',\n contractStorageHash,\n marker,\n expectedTargetId,\n actualTargetId: contractTarget,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n if (marker.storageHash !== contractStorageHash) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: VERIFY_CODE_HASH_MISMATCH,\n summary: 'Hash mismatch',\n contractStorageHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n if (contractProfileHash && marker.profileHash !== contractProfileHash) {\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: false,\n code: VERIFY_CODE_HASH_MISMATCH,\n summary: 'Hash mismatch',\n contractStorageHash,\n contractProfileHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n }\n\n const totalTime = Date.now() - startTime;\n return createVerifyResult({\n ok: true,\n summary: 'Database matches contract',\n contractStorageHash,\n marker,\n expectedTargetId,\n contractPath,\n totalTime,\n ...(contractProfileHash ? { contractProfileHash } : {}),\n ...(missingCodecs ? { missingCodecs } : {}),\n ...(codecCoverageSkipped ? { codecCoverageSkipped } : {}),\n ...(configPath ? { configPath } : {}),\n });\n },\n\n verifySchema(options: {\n readonly contract: unknown;\n readonly schema: SqlSchemaIRNode;\n readonly strict: boolean;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n }): VerifyDatabaseSchemaResult {\n const contract = deserializeWithTargetSerializer(options.contract) as Contract<SqlStorage>;\n if (!diffSchema) {\n throw missingDescriptorOperationError(target.targetId, 'diffSchema');\n }\n if (!targetGranularityOf) {\n throw missingDescriptorOperationError(target.targetId, 'classifySubjectGranularity');\n }\n // THE VERDICT: the target's full-tree node diff, graded by the\n // family's post-diff filters (strict gating + control-policy\n // disposition), plus the codec verifyType hook findings. The result\n // is issue-based — `ok` holds exactly when both issue lists are empty.\n return verifySqlSchemaByDiff({\n contract,\n schema: options.schema,\n strict: options.strict,\n frameworkComponents: options.frameworkComponents,\n diffSchema,\n granularityOf: targetGranularityOf,\n });\n },\n\n /**\n * Classifies a diff issue's subject granularity on demand, by resolving\n * its node's `nodeKind` through the target's classifier — the\n * {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}\n * capability. Framework consumers spanning contract spaces (the\n * migration aggregate's unclaimed-elements sweep) detect and call this\n * instead of reaching into the concrete schema-IR node, which they\n * cannot read; nothing is stamped on the issue or the node.\n */\n classifySubjectGranularity(issue: SchemaDiffIssue): DiffSubjectGranularity | undefined {\n if (!targetGranularityOf) {\n throw missingDescriptorOperationError(target.targetId, 'classifySubjectGranularity');\n }\n return classifyDiffSubjectGranularity(issue, targetGranularityOf);\n },\n /**\n * Classifies a diff issue's subject storage `entityKind` on demand, by\n * resolving its node's `nodeKind` through the target's classifier —\n * the sibling of `classifySubjectGranularity` above, and part of the\n * same {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}\n * capability.\n */\n classifyEntityKind(issue: SchemaDiffIssue): string | undefined {\n if (!targetEntityKindOf) {\n throw missingDescriptorOperationError(target.targetId, 'classifyEntityKind');\n }\n return classifyDiffEntityKind(issue, targetEntityKindOf);\n },\n async sign(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult> {\n const { driver, contract: contractInput, contractPath, configPath } = options;\n const startTime = Date.now();\n\n const contract = deserializeWithTargetSerializer(contractInput) as Contract<SqlStorage>;\n\n const contractStorageHash = contract.storage.storageHash;\n const contractProfileHash =\n 'profileHash' in contract && typeof contract.profileHash === 'string'\n ? contract.profileHash\n : contractStorageHash;\n const contractTarget = contract.target;\n\n const controlAdapter = getControlAdapter();\n const lowererContext = { contract };\n for (const query of controlAdapter.bootstrapSignMarkerQueries()) {\n const lowered = await controlAdapter.lowerToExecuteRequest(query, lowererContext);\n await driver.query(lowered.sql, lowered.params);\n }\n\n const existingMarker = await controlAdapter.readMarker(driver, APP_SPACE_ID);\n\n let markerCreated = false;\n let markerUpdated = false;\n let previousHashes: { storageHash?: string; profileHash?: string } | undefined;\n\n if (!existingMarker) {\n await controlAdapter.insertMarker(driver, APP_SPACE_ID, {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n });\n markerCreated = true;\n } else {\n const existingStorageHash = existingMarker.storageHash;\n const existingProfileHash = existingMarker.profileHash;\n\n const storageHashMatches = existingStorageHash === contractStorageHash;\n const profileHashMatches = existingProfileHash === contractProfileHash;\n\n if (!storageHashMatches || !profileHashMatches) {\n previousHashes = {\n storageHash: existingStorageHash,\n profileHash: existingProfileHash,\n };\n const updated = await controlAdapter.updateMarker(\n driver,\n APP_SPACE_ID,\n existingStorageHash,\n {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n },\n );\n if (!updated) {\n throw sqlFamilyError(\n 'MIGRATION.MARKER_CAS_FAILURE',\n 'CAS conflict: marker was modified by another process during sign',\n {\n why: 'Another process updated the contract marker between the read and the compare-and-swap write.',\n fix: 'Re-run the sign command; if it keeps failing, make sure only one migration process runs at a time.',\n meta: { space: APP_SPACE_ID },\n },\n );\n }\n markerUpdated = true;\n }\n }\n\n let summary: string;\n if (markerCreated) {\n summary = 'Database signed (marker created)';\n } else if (markerUpdated) {\n summary = `Database signed (marker updated from ${previousHashes?.storageHash ?? 'unknown'})`;\n } else {\n summary = 'Database already signed with this contract';\n }\n\n const totalTime = Date.now() - startTime;\n\n return {\n ok: true,\n summary,\n contract: {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n },\n target: {\n expected: contractTarget,\n actual: contractTarget,\n },\n marker: {\n created: markerCreated,\n updated: markerUpdated,\n ...(previousHashes ? { previous: previousHashes } : {}),\n },\n meta: {\n contractPath,\n ...(configPath ? { configPath } : {}),\n },\n timings: {\n total: totalTime,\n },\n };\n },\n async readMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n }): Promise<ContractMarkerRecord | null> {\n return getControlAdapter().readMarker(options.driver, options.space);\n },\n async readAllMarkers(options: {\n readonly driver: SqlControlDriverInstance<string>;\n }): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n return getControlAdapter().readAllMarkers(options.driver);\n },\n async readLedger(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space?: string;\n }): Promise<readonly LedgerEntryRecord[]> {\n return getControlAdapter().readLedger(options.driver, options.space);\n },\n async initMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n };\n }): Promise<void> {\n return getControlAdapter().initMarker(options.driver, options.space, options.destination);\n },\n async updateMarker(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly expectedFrom: string;\n readonly destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n };\n }): Promise<boolean> {\n return getControlAdapter().updateMarker(\n options.driver,\n options.space,\n options.expectedFrom,\n options.destination,\n );\n },\n async writeLedgerEntry(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly space: string;\n readonly entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n readonly migrationName: string;\n readonly migrationHash: string;\n readonly operations: readonly unknown[];\n readonly destinationContractJson?: unknown;\n };\n }): Promise<void> {\n return getControlAdapter().writeLedgerEntry(options.driver, options.space, options.entry);\n },\n async introspect(options: {\n readonly driver: SqlControlDriverInstance<string>;\n readonly contract?: unknown;\n }): Promise<SqlSchemaIRNode> {\n return getControlAdapter().introspect(options.driver, options.contract);\n },\n\n inferPslContract(schemaIR: SqlSchemaIRNode): PslDocumentAst {\n if (!targetInferPslContract) {\n throw sqlFamilyError(\n 'CONTRACT.INFER_UNSUPPORTED',\n `Target \"${target.targetId}\" does not support contract infer (no inferPslContract on its descriptor).`,\n {\n why: 'The target descriptor does not provide the inferPslContract hook, so a PSL contract cannot be inferred from the database schema.',\n fix: 'Use a target package that supports contract infer, or author the contract instead of inferring it.',\n meta: { targetId: target.targetId },\n },\n );\n }\n return targetInferPslContract(schemaIR, describedContracts);\n },\n\n lowerAst(\n ast: AnyQueryAst | DdlNode,\n context: LowererContext<unknown>,\n ): Promise<SqlExecuteRequest> {\n return getControlAdapter().lowerToExecuteRequest(ast, context);\n },\n\n bootstrapControlTableQueries(): readonly DdlNode[] {\n return getControlAdapter().bootstrapControlTableQueries();\n },\n\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview {\n return sqlOperationsToPreview(operations);\n },\n\n toSchemaView(schema: SqlSchemaIRNode): CoreSchemaView {\n // Walk the schema-IR tree's own structure (root → namespaces → tables)\n // into one flat list of table nodes. A root that exposes a `namespaces`\n // record (Postgres) contributes each namespace's tables; a flat root\n // (SQLite) is its own single namespace. The single-schema common case\n // renders the same table-level view as today — no synthetic namespace\n // level.\n const root = blindCast<\n {\n readonly namespaces?: Readonly<\n Record<string, { readonly tables: Record<string, SqlTableIR> }>\n >;\n readonly tables?: Record<string, SqlTableIR>;\n },\n 'structural read of the schema-IR tree own namespaces/tables records'\n >(schema);\n // A multi-namespace root qualifies every table's display name with its\n // namespace key, so same-named tables in different namespaces (e.g.\n // public.thing and auth.thing) render distinct ids and labels. The\n // single-namespace case (and a flat SQLite root) keeps today's bare\n // names. Synthesized constraint/index fallback names keep the bare table\n // name — that is the name the database derives them from.\n const namespaceEntries: ReadonlyArray<[string | undefined, Record<string, SqlTableIR>]> =\n root.namespaces !== undefined\n ? Object.entries(root.namespaces).map(\n ([namespaceKey, namespace]): [string, Record<string, SqlTableIR>] => [\n namespaceKey,\n namespace.tables,\n ],\n )\n : [[undefined, root.tables ?? {}]];\n const qualify = namespaceEntries.length > 1;\n const tableEntries: ReadonlyArray<[string, string, SqlTableIR]> = namespaceEntries.flatMap(\n ([namespaceKey, tables]) =>\n Object.entries(tables).map(([tableName, table]): [string, string, SqlTableIR] => [\n qualify && namespaceKey !== undefined ? `${namespaceKey}.${tableName}` : tableName,\n tableName,\n table,\n ]),\n );\n const tableNodes: readonly SchemaTreeNode[] = tableEntries.map(\n ([displayName, tableName, table]: [string, string, SqlTableIR]) => {\n const children: SchemaTreeNode[] = [];\n\n const columnNodes: SchemaTreeNode[] = [];\n for (const [columnName, column] of Object.entries(table.columns)) {\n const typeDisplay = column.nativeType;\n const nullability = column.nullable ? 'nullable' : 'not nullable';\n const label = `${columnName}: ${typeDisplay} (${nullability})`;\n columnNodes.push(\n new SchemaTreeNode({\n kind: 'field',\n id: `column-${displayName}-${columnName}`,\n label,\n meta: {\n nativeType: column.nativeType,\n nullable: column.nullable,\n ...ifDefined('default', column.default),\n },\n }),\n );\n }\n\n if (columnNodes.length > 0) {\n children.push(\n new SchemaTreeNode({\n kind: 'collection',\n id: `columns-${displayName}`,\n label: 'columns',\n children: columnNodes,\n }),\n );\n }\n\n if (table.primaryKey) {\n const pkColumns = table.primaryKey.columns.join(', ');\n children.push(\n new SchemaTreeNode({\n kind: 'index',\n id: `primary-key-${displayName}`,\n label: `primary key: ${pkColumns}`,\n meta: {\n columns: table.primaryKey.columns,\n ...(table.primaryKey.name ? { name: table.primaryKey.name } : {}),\n },\n }),\n );\n }\n\n for (const unique of table.uniques) {\n const name = unique.name ?? `${tableName}_${unique.columns.join('_')}_unique`;\n const label = `unique ${name}`;\n children.push(\n new SchemaTreeNode({\n kind: 'index',\n id: `unique-${displayName}-${name}`,\n label,\n meta: {\n columns: unique.columns,\n unique: true,\n },\n }),\n );\n }\n\n for (const index of table.indexes) {\n const name = index.name;\n const label = index.unique ? `unique index ${name}` : `index ${name}`;\n children.push(\n new SchemaTreeNode({\n kind: 'index',\n id: `index-${displayName}-${name}`,\n label,\n meta: {\n columns: index.columns,\n unique: index.unique,\n },\n }),\n );\n }\n\n const tableMeta: Record<string, unknown> = {};\n if (table.primaryKey) {\n tableMeta['primaryKey'] = table.primaryKey.columns;\n if (table.primaryKey.name) {\n tableMeta['primaryKeyName'] = table.primaryKey.name;\n }\n }\n if (table.foreignKeys.length > 0) {\n tableMeta['foreignKeys'] = table.foreignKeys.map((fk) => ({\n columns: fk.columns,\n referencedTable: fk.referencedTable,\n referencedColumns: fk.referencedColumns,\n ...(fk.name ? { name: fk.name } : {}),\n }));\n }\n\n return new SchemaTreeNode({\n kind: 'entity',\n id: `table-${displayName}`,\n label: `table ${displayName}`,\n ...(Object.keys(tableMeta).length > 0 ? { meta: tableMeta } : {}),\n ...(children.length > 0 ? { children } : {}),\n });\n },\n );\n\n return {\n root: new SchemaTreeNode({\n kind: 'root',\n id: 'sql-schema',\n label: 'database',\n ...(tableNodes.length > 0 ? { children: tableNodes } : {}),\n }),\n };\n },\n };\n}\n","import type {\n ControlFamilyDescriptor,\n ControlStack,\n} from '@prisma-next/framework-components/control';\nimport type { EmissionSpi } from '@prisma-next/framework-components/emission';\nimport { sqlEmission } from '@prisma-next/sql-contract-emitter';\nimport { sqlFamilyEntityTypes, sqlFamilyPslBlockDescriptors } from './authoring-entity-types';\nimport { sqlFamilyAuthoringFieldPresets } from './authoring-field-presets';\nimport { sqlFamilyAuthoringTypes } from './authoring-type-constructors';\nimport { createSqlFamilyInstance, type SqlControlFamilyInstance } from './control-instance';\n\nexport class SqlFamilyDescriptor\n implements ControlFamilyDescriptor<'sql', SqlControlFamilyInstance>\n{\n readonly kind = 'family' as const;\n readonly id = 'sql';\n readonly familyId = 'sql' as const;\n readonly version = '0.0.1';\n readonly emission: EmissionSpi = sqlEmission;\n readonly authoring = {\n field: sqlFamilyAuthoringFieldPresets,\n type: sqlFamilyAuthoringTypes,\n entityTypes: sqlFamilyEntityTypes,\n pslBlockDescriptors: sqlFamilyPslBlockDescriptors,\n } as const;\n\n create<TTargetId extends string>(\n stack: ControlStack<'sql', TTargetId>,\n ): SqlControlFamilyInstance {\n return createSqlFamilyInstance(stack);\n }\n}\n","import type { ColumnDefault, Contract, JsonValue } from '@prisma-next/contract/types';\nimport type { CodecRef } from '@prisma-next/framework-components/codec';\nimport type {\n MigrationPlannerConflict,\n SchemaNodeRef,\n} from '@prisma-next/framework-components/control';\nimport {\n type CheckConstraint,\n type ForeignKey,\n type Index,\n isStorageTypeInstance,\n type SqlStorage,\n type StorageColumn,\n StorageTable,\n type StorageTypeInstance,\n type UniqueConstraint,\n} from '@prisma-next/sql-contract/types';\nimport {\n RelationalSchemaNodeKind,\n type SqlAnnotations,\n type SqlCheckConstraintIRInput,\n type SqlColumnIRInput,\n type SqlForeignKeyIRInput,\n type SqlIndexIRInput,\n SqlSchemaIR,\n SqlTableIR,\n type SqlUniqueIRInput,\n} from '@prisma-next/sql-schema-ir/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { InternalError } from '@prisma-next/utils/internal-error';\nimport { sqlFamilyError } from '../errors';\n\n/**\n * Target-specific callback that expands a column's base `nativeType` and optional\n * `typeParams` into the fully-qualified type string used by the database\n * (e.g. `character` + `{ length: 36 }` → `character(36)`).\n *\n * This lives in the family layer as a callback rather than importing a concrete\n * implementation because each target (Postgres, MySQL, SQLite, …) has its own\n * parameterization syntax. The target wires its expander when calling\n * `contractToSchemaIR`, keeping the family layer target-agnostic.\n */\nexport type NativeTypeExpander = (input: {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n}) => string;\n\n/**\n * Target-specific callback that renders a `ColumnDefault` into the raw SQL literal\n * string stored in `SqlColumnIR.default`.\n *\n * Default value serialization is target-specific (quoting, casting, type syntax vary\n * between Postgres, MySQL, SQLite, …). This callback follows the same IoC pattern as\n * `NativeTypeExpander`: the target provides its renderer when calling\n * `contractToSchemaIR`, keeping the family layer target-agnostic.\n */\nexport type DefaultRenderer = (def: ColumnDefault, column: StorageColumn) => string;\n\n/**\n * Target-supplied hook (same IoC seam as `NativeTypeExpander`/`DefaultRenderer`)\n * that normalizes a contract-declared `ColumnDefault` into the resolved shape\n * the target's introspection parses from the live database — e.g. a\n * `dbgenerated(\"'{}'::jsonb\")` function call and the literal Postgres reports\n * are the same value in different shapes, and `resolvedDefaultsEqual`\n * compares `kind` before content. When omitted, the contract's raw default\n * is the resolved default unchanged.\n */\nexport type DefaultResolver = (def: ColumnDefault, resolvedNativeType: string) => ColumnDefault;\n\n/**\n * Target-supplied callback that resolves a contract namespace to the live\n * database schema its enums are stored under.\n *\n * The projected enum annotations are nested by schema\n * (`storageTypes[schema][nativeType]`) so two namespaces holding an enum with\n * the same native type resolve to distinct live-database types. Mapping a\n * namespace to its DDL schema is target-specific (Postgres schemas;\n * SQLite/MySQL differ), so the target injects it here rather than the family\n * importing a concrete `ddlSchemaName`. This keeps the family layer\n * target-agnostic while the projection nests under the same schema the\n * target's read side (`readExistingEnumValues`) looks up.\n */\nexport type EnumNamespaceSchemaResolver = (storage: SqlStorage, namespaceId: string) => string;\n\nfunction convertColumn(\n name: string,\n column: StorageColumn,\n storageTypes: ResolvedStorageTypes,\n expandNativeType: NativeTypeExpander | undefined,\n renderDefault: DefaultRenderer | undefined,\n resolveDefault: DefaultResolver | undefined,\n): SqlColumnIRInput {\n // Resolve `typeRef` so columns that delegate their `nativeType`/`codecId`/\n // `typeParams` to a named `storage.types` entry expand the same way as\n // columns that inline those fields. Without this resolution, a\n // `typeRef`-based column like `post.embedding → Embedding1536` would\n // render as the bare `\"vector\"` (dropping the `length` parameter), while\n // `verify-sql-schema.ts`'s `renderExpectedNativeType` resolves the\n // typeRef and produces `\"vector(1536)\"` — making diffs on the same\n // contract falsely report a `type_mismatch`.\n const resolved = resolveColumnTypeMetadata(column, storageTypes);\n const baseNativeType = expandNativeType\n ? expandNativeType({\n nativeType: resolved.nativeType,\n codecId: resolved.codecId,\n ...ifDefined('typeParams', resolved.typeParams),\n })\n : resolved.nativeType;\n // `many: true` columns keep `nativeType` as the bare element type (matching\n // how the introspected/\"actual\" side reports it — see the postgres control\n // adapter's own `many`-stripping normalization) and carry the array-ness in\n // the separate `many` field instead of baking `[]` into `nativeType`.\n // Baking it in here (`\"text[]\"`) made every `@@` list-typed column\n // permanently mismatch against a live introspected column reporting\n // `{ nativeType: \"text\", many: true }`, regardless of whether the two are\n // otherwise identical — `db verify` reported every such column\n // `not-equal`. `resolvedNativeType` still carries the full `\"text[]\"`\n // form: it is the side both this and the introspected column already\n // agree on as the comparable \"expanded\" type.\n const nativeType = baseNativeType;\n const resolvedNativeType = column.many ? `${baseNativeType}[]` : baseNativeType;\n const rawColumnDefault = column.default ?? undefined;\n const resolvedColumnDefault =\n rawColumnDefault !== undefined && resolveDefault\n ? resolveDefault(rawColumnDefault, resolvedNativeType)\n : rawColumnDefault;\n return {\n name,\n nativeType,\n nullable: column.nullable,\n ...ifDefined('many', column.many),\n ...ifDefined(\n 'default',\n column.default != null && renderDefault ? renderDefault(column.default, column) : undefined,\n ),\n // Contract-derived columns are resolved by construction: the computed\n // full native type doubles as the resolved value. The contract's raw\n // structured default becomes the resolved default after passing through\n // the target's `resolveDefault` hook (when supplied), so a default the\n // target's introspection side would normalize differently (e.g. a\n // `dbgenerated(...)` function call that is actually a literal) compares\n // equal instead of drifting on `kind` alone.\n resolvedNativeType,\n ...ifDefined('resolvedDefault', resolvedColumnDefault),\n // The column's codec identity, carried the same way the query AST\n // carries `CodecRef` (TML-2456) — the migration planner's op-builders\n // resolve DDL rendering from this at plan time (Decision 5), instead of\n // reading a derivation-precomputed render payload.\n codecRef: buildColumnCodecRef(resolved, column.many),\n codecBaseNativeType: resolved.nativeType,\n ...(column.typeRef !== undefined ? { codecNamedType: true } : {}),\n };\n}\n\n/**\n * Builds the column's `CodecRef` from its resolved (post-`typeRef`) codec\n * identity — the same construction the query AST and the migration DDL\n * renderer already use (TML-2456, TML-2918).\n */\nfunction buildColumnCodecRef(\n resolved: Pick<StorageColumn, 'codecId' | 'nativeType' | 'typeParams'>,\n many: boolean | undefined,\n): CodecRef {\n return {\n codecId: resolved.codecId,\n ...ifDefined(\n 'typeParams',\n resolved.typeParams !== undefined\n ? blindCast<\n JsonValue,\n 'resolved.typeParams is JsonValue-shaped storage metadata; the narrowed (non-undefined) value lands in CodecRef.typeParams which is JsonValue'\n >(resolved.typeParams)\n : undefined,\n ),\n ...ifDefined('many', many),\n };\n}\n\ntype ResolvedStorageTypes = Readonly<Record<string, StorageTypeInstance>>;\n\nfunction resolveColumnTypeMetadata(\n column: StorageColumn,\n storageTypes: ResolvedStorageTypes,\n): Pick<StorageColumn, 'codecId' | 'nativeType' | 'typeParams'> {\n if (!column.typeRef) {\n return column;\n }\n const referenced = storageTypes[column.typeRef];\n if (!referenced) {\n throw sqlFamilyError(\n 'CONTRACT.TYPE_UNKNOWN',\n `Column references storage type \"${column.typeRef}\" but it is not defined in storage.types.`,\n {\n why: 'The column typeRef does not resolve to any entry in the contract storage.types map.',\n fix: 'Regenerate the contract from its authoring source; do not hand-edit contract JSON.',\n meta: { typeRef: column.typeRef },\n },\n );\n }\n if (isStorageTypeInstance(referenced)) {\n return {\n codecId: referenced.codecId,\n nativeType: referenced.nativeType,\n typeParams: referenced.typeParams,\n };\n }\n throw new InternalError(\n `Storage type \"${column.typeRef}\" has an unknown polymorphic kind; expected a codec-typed StorageTypeInstance.`,\n );\n}\n\n/**\n * Resolves a `ValueSetRef` to its permitted values from the contract storage.\n *\n * Throws when the referenced namespace or value-set is absent — this indicates\n * the contract was built incorrectly (the check and the value-set must be\n * co-emitted by the lowering step). Used by `convertCheck` (schema-IR\n * projection), `verifyCheckConstraints` (verification), and\n * `checkConstraintPlanCallStrategy` (migration planning) so all three agree on\n * the resolved values and the error behavior on a missing reference.\n */\nfunction allStrings(values: readonly JsonValue[]): values is readonly string[] {\n return values.every((value) => typeof value === 'string');\n}\n\nexport function resolveValueSetValues(\n ref: { readonly namespaceId: string; readonly entityName: string },\n storage: SqlStorage,\n contextLabel: string,\n): readonly string[] {\n const ns = storage.namespaces[ref.namespaceId];\n if (!ns) {\n throw sqlFamilyError(\n 'CONTRACT.NAMESPACE_UNKNOWN',\n `resolveValueSetValues: namespace \"${ref.namespaceId}\" not found in storage (${contextLabel})`,\n {\n why: 'A value-set reference names a namespace the contract storage does not declare.',\n fix: 'Regenerate the contract from its authoring source; do not hand-edit contract JSON.',\n meta: { namespaceId: ref.namespaceId, context: contextLabel },\n },\n );\n }\n const valueSet = ns.entries.valueSet?.[ref.entityName];\n if (!valueSet) {\n throw sqlFamilyError(\n 'CONTRACT.ENUM_UNKNOWN',\n `resolveValueSetValues: value-set \"${ref.entityName}\" not found in namespace \"${ref.namespaceId}\" (${contextLabel})`,\n {\n why: 'A value-set reference names an entry its namespace does not declare.',\n fix: 'Regenerate the contract from its authoring source; do not hand-edit contract JSON.',\n meta: { valueSet: ref.entityName, namespaceId: ref.namespaceId, context: contextLabel },\n },\n );\n }\n // Only TEXT enums ship a CHECK-constraint round-trip in this slice. A\n // non-string value-set is a numeric enum, whose CHECK rendering/verification\n // is future work; fail loudly rather than emit a wrong numeric-as-text check.\n const values = valueSet.values;\n if (!allStrings(values)) {\n throw sqlFamilyError(\n 'CONTRACT.ENUM_INVALID',\n `resolveValueSetValues: value-set \"${ref.entityName}\" in namespace \"${ref.namespaceId}\" has a non-string value; numeric-enum CHECK constraints are not yet supported (${contextLabel})`,\n {\n why: 'Only string value-sets can be rendered as CHECK constraints; this value-set carries a non-string value.',\n fix: 'Use string enum values, or drop the CHECK-constrained enum until numeric enums are supported.',\n meta: { valueSet: ref.entityName, namespaceId: ref.namespaceId, context: contextLabel },\n },\n );\n }\n return values;\n}\n\n/**\n * Projects a `CheckConstraint` IR into an `SqlCheckConstraintIRInput` by\n * resolving the permitted values from the storage value-set it references.\n *\n * The `CheckConstraint.valueSet` ref points to\n * `storage.namespaces[namespaceId].entries.valueSet[name]`. The resolved\n * values are lifted directly from `StorageValueSet.values` so verification\n * compares value sets, not SQL predicate strings.\n *\n * Throws if the referenced namespace or value-set is absent — this\n * indicates the contract was built incorrectly (the check and the\n * value-set must be co-emitted by the lowering step).\n */\nfunction convertCheck(check: CheckConstraint, storage: SqlStorage): SqlCheckConstraintIRInput {\n const permittedValues = resolveValueSetValues(check.valueSet, storage, `check \"${check.name}\"`);\n return {\n name: check.name,\n column: check.column,\n permittedValues,\n };\n}\n\nfunction convertUnique(unique: UniqueConstraint, tableName: string): SqlUniqueIRInput {\n return {\n columns: unique.columns,\n ...ifDefined('name', unique.name),\n dependsOn: flatColumnDependsOn(tableName, unique.columns),\n };\n}\n\nfunction convertIndex(\n index: Index,\n tableName: string,\n tableColumns: readonly string[],\n): SqlIndexIRInput {\n const base = {\n name: index.name,\n prefix: index.prefix,\n where: index.where,\n unique: index.unique,\n partial: index.where !== undefined,\n // Carried so the derived index node compares type/options against the\n // introspected side (the legacy walk read them from the contract).\n type: index.type,\n options: index.options,\n annotations: undefined,\n // An expression index's chains cover every column of its table — the\n // opaque expression is never parsed, so this deterministic\n // over-approximation keeps drops ordered without a SQL parser.\n dependsOn: flatColumnDependsOn(tableName, index.columns ?? tableColumns),\n };\n return index.expression !== undefined\n ? { ...base, expression: index.expression }\n : { ...base, columns: index.columns ?? [] };\n}\n\n/**\n * The referenced table's chain in the flat (single-schema) tree\n * `contractToSchemaIR`/`contractNamespaceToSchemaIR` build: the root\n * (`SqlSchemaIR`, fixed `'database'` id) followed by the table's own id.\n * Postgres discards this when it re-derives the FK against its own\n * multi-schema tree shape (`contractToPostgresDatabaseSchemaNode`); SQLite's\n * flat tree uses it as-is.\n */\nfunction flatSchemaDependsOn(tableName: string): SchemaNodeRef {\n return [\n { nodeKind: RelationalSchemaNodeKind.schema, id: 'database' },\n { nodeKind: RelationalSchemaNodeKind.table, id: tableName },\n ];\n}\n\n/**\n * The chains from a table-child object (foreign key, index, unique, primary\n * key) to each of the own columns it is built on, in the flat tree. Dropping\n * a covered column auto-drops the object, so the object's drop must precede\n * the column's; the graph derives that direction from these edges.\n */\nfunction flatColumnDependsOn(\n tableName: string,\n columns: readonly string[],\n): readonly SchemaNodeRef[] {\n return columns.map((column) => [\n { nodeKind: RelationalSchemaNodeKind.schema, id: 'database' },\n { nodeKind: RelationalSchemaNodeKind.table, id: tableName },\n { nodeKind: RelationalSchemaNodeKind.column, id: `column:${column}` },\n ]);\n}\n\n/**\n * The FK's referenced-namespace identity comes from the target's namespace\n * node, not the raw namespace-id string. An unbound target namespace stamps\n * no `referencedSchema` at all — the FK node's id renders the absence as the\n * empty segment, which is what flat (single-schema) introspection produces,\n * so both diff sides' FK ids meet by construction. A bound namespace (or a\n * cross-space target whose namespace lives in another contract's storage)\n * stamps its coordinate verbatim; namespaced targets (Postgres) resolve the\n * real DDL schema downstream.\n *\n * `dependsOn` carries the referenced table (created before the FK, dropped\n * after it) plus the FK's own columns (dropped after the FK, since dropping a\n * column auto-drops the FK built on it).\n */\nfunction convertForeignKey(fk: ForeignKey, storage: SqlStorage): SqlForeignKeyIRInput {\n const targetNamespace = storage.namespaces[fk.target.namespaceId];\n const targetIsUnbound = targetNamespace?.isUnbound === true;\n return {\n columns: fk.source.columns,\n referencedTable: fk.target.tableName,\n ...(targetIsUnbound ? {} : { referencedSchema: fk.target.namespaceId }),\n referencedColumns: fk.target.columns,\n ...ifDefined('name', fk.name),\n ...ifDefined('onDelete', fk.onDelete),\n ...ifDefined('onUpdate', fk.onUpdate),\n dependsOn: [\n flatSchemaDependsOn(fk.target.tableName),\n ...flatColumnDependsOn(fk.source.tableName, fk.source.columns),\n ],\n };\n}\n\nfunction convertTable(\n name: string,\n table: StorageTable,\n storageTypes: ResolvedStorageTypes,\n expandNativeType: NativeTypeExpander | undefined,\n renderDefault: DefaultRenderer | undefined,\n resolveDefault: DefaultResolver | undefined,\n storage: SqlStorage,\n): SqlTableIR {\n const columns: Record<string, SqlColumnIRInput> = {};\n for (const [colName, colDef] of Object.entries(table.columns)) {\n columns[colName] = convertColumn(\n colName,\n colDef,\n storageTypes,\n expandNativeType,\n renderDefault,\n resolveDefault,\n );\n }\n\n const checks: SqlCheckConstraintIRInput[] | undefined =\n table.checks && table.checks.length > 0\n ? table.checks.map((c) => convertCheck(c, storage))\n : undefined;\n\n const primaryKey =\n table.primaryKey !== undefined\n ? {\n columns: table.primaryKey.columns,\n ...ifDefined('name', table.primaryKey.name),\n dependsOn: flatColumnDependsOn(name, table.primaryKey.columns),\n }\n : undefined;\n\n return new SqlTableIR({\n name,\n columns,\n ...ifDefined('primaryKey', primaryKey),\n // #989 persists a `constraint: false` FK's absence and its backing index as\n // discrete entities at contract construction, so every `foreignKeys[]` entry\n // is now constraint-bearing (no filter) and each FK-backing index is already\n // a `table.indexes[]` entry — it flows through `convertIndex` below, carrying\n // the object→own-column `dependsOn` edge like any other index.\n foreignKeys: table.foreignKeys.map((fk) => convertForeignKey(fk, storage)),\n uniques: table.uniques.map((u) => convertUnique(u, name)),\n indexes: table.indexes.map((i) => convertIndex(i, name, Object.keys(table.columns))),\n ...ifDefined('checks', checks),\n });\n}\n\n/**\n * Detects destructive changes between two contract storages.\n *\n * The additive-only planner silently ignores removals (tables, columns).\n * This function detects those removals so callers can report them as conflicts\n * rather than silently producing an empty plan.\n *\n * Returns an empty array if no destructive changes are found.\n */\nexport function detectDestructiveChanges(\n from: SqlStorage | null,\n to: SqlStorage,\n): readonly MigrationPlannerConflict[] {\n if (!from) return [];\n\n const hasOwn = (value: object, key: string): boolean => Object.hasOwn(value, key);\n\n const conflicts: MigrationPlannerConflict[] = [];\n\n const namespaceIds = [\n ...new Set([...Object.keys(from.namespaces), ...Object.keys(to.namespaces)]),\n ].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n\n for (const namespaceId of namespaceIds) {\n const fromNs = from.namespaces[namespaceId];\n const toNs = to.namespaces[namespaceId];\n const fromTables = fromNs?.entries.table;\n if (!fromTables) continue;\n\n for (const tableName of Object.keys(fromTables)) {\n const toTableRaw = toNs?.entries.table?.[tableName];\n if (!StorageTable.is(toTableRaw)) {\n conflicts.push({\n kind: 'tableRemoved',\n summary: `Table \"${tableName}\" was removed`,\n });\n continue;\n }\n const toTable = toTableRaw;\n\n const fromTableRaw = fromTables[tableName];\n if (!StorageTable.is(fromTableRaw)) continue;\n const fromTable = fromTableRaw;\n\n for (const columnName of Object.keys(fromTable.columns)) {\n if (!hasOwn(toTable.columns, columnName)) {\n conflicts.push({\n kind: 'columnRemoved',\n summary: `Column \"${tableName}\".\"${columnName}\" was removed`,\n });\n }\n }\n }\n }\n\n return conflicts;\n}\n\nexport interface ContractToSchemaIROptions {\n readonly annotationNamespace: string;\n readonly expandNativeType?: NativeTypeExpander;\n readonly renderDefault?: DefaultRenderer;\n readonly resolveDefault?: DefaultResolver;\n /**\n * Target-supplied resolver mapping a namespace to the live database schema\n * its enums are stored under. When provided (Postgres), namespace-scoped\n * enums are nested by that schema in `enumTypes` so the projection matches\n * the target's `readExistingEnumValues` lookup. Targets without\n * schema-scoped enum storage (SQLite) omit it; enums are absent there.\n */\n readonly resolveEnumNamespaceSchema?: EnumNamespaceSchemaResolver;\n}\n\n/**\n * Converts a `Contract` to `SqlSchemaIR`.\n *\n * Reads `contract.storage` for tables and `contract.storage.types` for type\n * annotations. Storage-type annotations are written under\n * `options.annotationNamespace`.\n *\n * Drops codec metadata (`codecId`, `typeRef`) since the schema IR only represents\n * structural information. When `expandNativeType` is provided, parameterized types\n * are expanded (e.g. `character` + `{ length: 36 }` → `character(36)`) so the\n * resulting IR compares correctly against the \"to\" contract during planning.\n *\n * Returns an empty schema IR when `contract` is `null` (new project).\n */\n/**\n * Converts the tables of a single namespace into a `SqlSchemaIR`, keyed by\n * table name within that namespace. Unlike {@link contractToSchemaIR}, which\n * flattens every namespace's tables into one bare-keyed record (and throws on a\n * cross-namespace name collision), this scopes the table iteration to one\n * namespace so the same table name can exist in two schemas.\n *\n * The full `storage` is still passed to `convertTable`, so value-set / enum /\n * type resolution that legitimately spans namespaces is unaffected. Foreign\n * keys are built purely from the FK descriptor (`fk.target`), so cross-namespace\n * FKs survive per-namespace conversion. The `annotations` block (storage-type\n * derived) is omitted here — the per-namespace tree consumer reads only the\n * per-table fields.\n */\nexport function contractNamespaceToSchemaIR(\n storage: SqlStorage,\n namespaceId: string,\n options: ContractToSchemaIROptions,\n): SqlSchemaIR {\n if (options.annotationNamespace.length === 0) {\n throw sqlFamilyError(\n 'CONTRACT.PACK_CONTRIBUTION_INVALID',\n 'annotationNamespace must be a non-empty string',\n {\n why: 'The calling target pack passed an empty annotationNamespace to the contract-to-schema-IR projection.',\n fix: 'Fix the target pack to pass its non-empty annotation namespace (e.g. \"pg\").',\n meta: { option: 'annotationNamespace' },\n },\n );\n }\n const namespace = storage.namespaces[namespaceId];\n if (!namespace) {\n return new SqlSchemaIR({ tables: {} });\n }\n const storageTypes: ResolvedStorageTypes = { ...(storage.types ?? {}) };\n const tables: Record<string, SqlTableIR> = {};\n for (const [tableName, tableDefRaw] of Object.entries(namespace.entries.table ?? {})) {\n StorageTable.assert(tableDefRaw, `namespaces.${namespaceId}.entries.table.${tableName}`);\n tables[tableName] = convertTable(\n tableName,\n tableDefRaw,\n storageTypes,\n options.expandNativeType,\n options.renderDefault,\n options.resolveDefault,\n storage,\n );\n }\n return new SqlSchemaIR({ tables });\n}\n\nexport function contractToSchemaIR(\n contract: Contract<SqlStorage> | null,\n options: ContractToSchemaIROptions,\n): SqlSchemaIR {\n if (options.annotationNamespace.length === 0) {\n throw sqlFamilyError(\n 'CONTRACT.PACK_CONTRIBUTION_INVALID',\n 'annotationNamespace must be a non-empty string',\n {\n why: 'The calling target pack passed an empty annotationNamespace to the contract-to-schema-IR projection.',\n fix: 'Fix the target pack to pass its non-empty annotation namespace (e.g. \"pg\").',\n meta: { option: 'annotationNamespace' },\n },\n );\n }\n\n if (!contract) {\n return new SqlSchemaIR({ tables: {} });\n }\n\n const storage = contract.storage;\n const storageTypes: ResolvedStorageTypes = { ...(storage.types ?? {}) };\n const tables: Record<string, SqlTableIR> = {};\n for (const ns of Object.values(storage.namespaces)) {\n for (const [tableName, tableDefRaw] of Object.entries(ns.entries.table ?? {})) {\n StorageTable.assert(tableDefRaw, `namespaces.${ns.id}.entries.table.${tableName}`);\n const tableDef = tableDefRaw;\n if (tables[tableName] !== undefined) {\n throw sqlFamilyError(\n 'CONTRACT.TABLE_AMBIGUOUS',\n `contractToSchemaIR: duplicate SQL table name \"${tableName}\" across namespaces (ambiguous for flat SqlSchemaIR.tables).`,\n {\n why: 'Two namespaces declare a table with the same name, which is ambiguous for the flat schema-IR table map.',\n fix: 'Rename one of the tables so every table name is unique across namespaces.',\n meta: { table: tableName },\n },\n );\n }\n tables[tableName] = convertTable(\n tableName,\n tableDef,\n storageTypes,\n options.expandNativeType,\n options.renderDefault,\n options.resolveDefault,\n storage,\n );\n }\n }\n\n const annotations = deriveAnnotations(\n storage,\n options.annotationNamespace,\n options.resolveEnumNamespaceSchema,\n );\n\n return new SqlSchemaIR({\n tables,\n ...ifDefined('annotations', annotations),\n });\n}\n\nfunction deriveAnnotations(\n storage: SqlStorage,\n annotationNamespace: string,\n _resolveEnumNamespaceSchema: EnumNamespaceSchemaResolver | undefined,\n): SqlAnnotations | undefined {\n const storageTypes: Record<string, StorageTypeInstance> = {};\n\n for (const typeInstance of Object.values(storage.types ?? {})) {\n if (isStorageTypeInstance(typeInstance)) {\n storageTypes[typeInstance.nativeType] = typeInstance;\n }\n }\n\n const envelope = {\n ...(Object.keys(storageTypes).length > 0 ? { storageTypes } : {}),\n };\n if (Object.keys(envelope).length === 0) return undefined;\n return { [annotationNamespace]: envelope };\n}\n","import {\n type Contract,\n type ControlPolicy,\n effectiveControlPolicy,\n} from '@prisma-next/contract/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\n/**\n * The target object a control policy governs for a single planner call,\n * resolved from the target's own IR. `undefined` means the call's target\n * object could not be positively established — a fail-closed signal: any\n * policy stricter than `managed` drops such a call rather than emitting it.\n *\n * The object identity is a generic storage coordinate — `(entityKind,\n * entityName)`, absent for a whole-namespace subject — never a target-specific\n * `table`/`typeName` field. The family reasons about the coordinate for policy\n * and deduplication; the target owns any vocabulary (table vs enum) when it\n * renders a suppression.\n */\nexport interface ControlPolicySubject {\n readonly namespaceId: string;\n readonly entityKind?: string;\n readonly entityName?: string;\n readonly column?: string;\n readonly explicitNodeControlPolicy?: ControlPolicy;\n /**\n * Whether the call creates a whole, previously-absent top-level storage\n * object (e.g. a table or an enum/type), as opposed to modifying an\n * existing object. This is the only thing `tolerated` permits: it is a\n * create-if-absent policy, so an op that touches an existing object — add\n * column, add index/constraint, alter, drop — is never allowed under it.\n */\n readonly createsNewObject: boolean;\n}\n\n/**\n * The structured record a control-policy partition emits for one suppressed\n * subject or call. It carries only raw data — no strings, no vocabulary — so\n * the consumer (the target) renders the user-facing message itself:\n *\n * - `subject` — the suppressed subject (its coordinate + namespace), or\n * `undefined` when the subject could not be resolved (fail-closed).\n * - `policy` — the effective control policy that caused the suppression.\n * - `factoryName` — the resolved creation factory name if the suppressed thing\n * was a whole-object creation (e.g. `createTable`), else `undefined`. The\n * family never invents a verb for a modification that produced no call.\n * - `createsNewObject` — whether the suppressed thing was object creation.\n */\nexport interface SuppressionRecord {\n readonly subject: ControlPolicySubject | undefined;\n readonly policy: ControlPolicy;\n readonly factoryName: string | undefined;\n readonly createsNewObject: boolean;\n}\n\n/**\n * The control policy that governs a single call. The `external` default is an\n * un-overridable namespace floor: when the contract default is `external`, no\n * per-object `managed` override can escalate DDL above the floor, so the\n * policy is forced to `external` regardless of the node's own declaration.\n * Every other default defers to the node's effective control policy.\n */\nexport function controlPolicyForCall(\n subject: ControlPolicySubject | undefined,\n defaultControlPolicy: ControlPolicy | undefined,\n): ControlPolicy {\n if (defaultControlPolicy === 'external') {\n return 'external';\n }\n return effectiveControlPolicy(subject?.explicitNodeControlPolicy, defaultControlPolicy);\n}\n\n/**\n * Whether a call is allowed to emit under a given control policy.\n *\n * - `managed` — full lifecycle, every op allowed.\n * - `tolerated` — create-if-absent only: allowed iff the call creates a whole\n * new top-level object (and its subject was positively resolved). Anything\n * that modifies an existing object, and anything whose subject could not be\n * resolved, is suppressed.\n * - `external` / `observed` — no DDL at all.\n */\nfunction callAllowedUnderControlPolicy(\n policy: ControlPolicy,\n subject: ControlPolicySubject | undefined,\n): boolean {\n switch (policy) {\n case 'managed':\n return true;\n case 'tolerated':\n return subject?.createsNewObject === true;\n case 'external':\n case 'observed':\n return false;\n }\n}\n\n/**\n * Partition the calls produced for a single set of subjects into those the\n * effective control policy permits (`kept`) and a list of\n * {@link SuppressionRecord}s describing the suppressed calls.\n *\n * **Prefer {@link partitionIssuesByControlPolicy}** for the schema-issue\n * pipeline: it filters subjects out of the planner's *input* so the planner\n * never has to reason about un-modeled state on `external`/`observed`\n * subjects. This call-level helper remains for paths that bypass the issue\n * pipeline — currently the codec-emitted field-event ops, which originate\n * from declared contract fields rather than from introspected schema state\n * and therefore cannot trip the diff engine.\n */\nexport function partitionCallsByControlPolicy<TCall>(options: {\n readonly calls: readonly TCall[];\n readonly contract: Contract<SqlStorage>;\n readonly resolveControlPolicySubject: (call: TCall) => ControlPolicySubject | undefined;\n readonly resolveFactoryName: (call: TCall) => string;\n}): {\n readonly kept: readonly TCall[];\n readonly suppressions: readonly SuppressionRecord[];\n} {\n const defaultControlPolicy = options.contract.defaultControlPolicy;\n const kept: TCall[] = [];\n const suppressions: SuppressionRecord[] = [];\n\n for (const call of options.calls) {\n const subject = options.resolveControlPolicySubject(call);\n const policy = controlPolicyForCall(subject, defaultControlPolicy);\n if (callAllowedUnderControlPolicy(policy, subject)) {\n kept.push(call);\n } else {\n suppressions.push({\n subject,\n policy,\n factoryName: options.resolveFactoryName(call),\n createsNewObject: subject?.createsNewObject ?? false,\n });\n }\n }\n\n return Object.freeze({\n kept: Object.freeze(kept),\n suppressions: Object.freeze(suppressions),\n });\n}\n\n/**\n * Partition a list of schema-issue-shaped inputs by the effective control\n * policy of each issue's subject *before* the planner is invoked.\n *\n * `plannable` is the list of issues whose subject's effective policy permits\n * the planner to act on them (`managed`, or `tolerated` for whole-object\n * creation issues only). Issues for `external`/`observed` subjects, and\n * non-creation issues for `tolerated` subjects, are dropped from the planner's\n * input entirely — they never enter introspection-driven planning, never feed\n * the diff engine, and never produce DDL calls that would have to be\n * post-filtered. This sidesteps a class of failure where the diff engine\n * cannot reason about the live shape of a subject the user marked as\n * out-of-scope (`external`).\n *\n * `suppressions` is one {@link SuppressionRecord} per suppressed subject (not\n * per suppressed issue). Its `factoryName` is the creation factory name when any\n * of the subject's issues is whole-object creation (e.g. `createTable`), else\n * `undefined` — the family never invents a modification verb for an op that\n * produced no call; the target renders the message.\n *\n * Unresolved-subject issues (`resolveControlPolicySubject` returns\n * `undefined`) emit one record each; they cannot be deduplicated because they\n * carry no subject coordinate.\n */\nexport function partitionIssuesByControlPolicy<TIssue>(options: {\n readonly issues: readonly TIssue[];\n readonly contract: Contract<SqlStorage>;\n /**\n * Resolve the subject targeted by this issue (or `undefined` to fail-closed:\n * any policy stricter than `managed` drops the issue).\n */\n readonly resolveControlPolicySubject: (issue: TIssue) => ControlPolicySubject | undefined;\n /**\n * Resolve a creation factoryName for this issue if it represents the\n * absence of the whole top-level object (e.g. `'createTable'` for a\n * missing-table issue). When the issue describes a modification to an\n * existing object, return `undefined`. Both decisions feed off this signal:\n *\n * 1. Under `tolerated`, only issues whose `resolveCreationFactoryName`\n * returns a value flow into the planner (create-if-absent).\n * 2. A suppressed subject's record carries the resolved creation factoryName\n * when it has at least one creation-flavoured issue, else `undefined`.\n */\n readonly resolveCreationFactoryName: (issue: TIssue) => string | undefined;\n}): {\n readonly plannable: readonly TIssue[];\n readonly suppressions: readonly SuppressionRecord[];\n} {\n const defaultControlPolicy = options.contract.defaultControlPolicy;\n\n const plannable: TIssue[] = [];\n // Resolved-subject suppressions are deduplicated by subject key so we emit\n // one record per suppressed subject, not one per suppressed issue.\n // `creationFactoryName` upgrades from `undefined` to a concrete creation\n // name the first time we see a creation-flavoured issue for the subject.\n const suppressedSubjects = new Map<\n string,\n {\n readonly subject: ControlPolicySubject;\n readonly policy: ControlPolicy;\n creationFactoryName?: string;\n }\n >();\n const unresolvedSuppressions: SuppressionRecord[] = [];\n\n for (const issue of options.issues) {\n const subject = options.resolveControlPolicySubject(issue);\n const policy = controlPolicyForCall(subject, defaultControlPolicy);\n const creationFactoryName = options.resolveCreationFactoryName(issue);\n\n if (policy === 'managed') {\n plannable.push(issue);\n continue;\n }\n if (\n policy === 'tolerated' &&\n subject !== undefined &&\n creationFactoryName !== undefined &&\n subject.createsNewObject\n ) {\n plannable.push(issue);\n continue;\n }\n\n if (subject === undefined) {\n unresolvedSuppressions.push({\n subject: undefined,\n policy,\n factoryName: creationFactoryName,\n createsNewObject: false,\n });\n continue;\n }\n\n const key = subjectKey(subject);\n const existing = suppressedSubjects.get(key);\n if (existing) {\n if (existing.creationFactoryName === undefined && creationFactoryName !== undefined) {\n existing.creationFactoryName = creationFactoryName;\n }\n } else {\n suppressedSubjects.set(key, {\n subject,\n policy,\n ...ifDefined('creationFactoryName', creationFactoryName),\n });\n }\n }\n\n const suppressions: SuppressionRecord[] = [...unresolvedSuppressions];\n for (const entry of suppressedSubjects.values()) {\n suppressions.push({\n subject: entry.subject,\n policy: entry.policy,\n factoryName: entry.creationFactoryName,\n createsNewObject: entry.subject.createsNewObject,\n });\n }\n\n return Object.freeze({\n plannable: Object.freeze(plannable),\n suppressions: Object.freeze(suppressions),\n });\n}\n\nfunction subjectKey(subject: ControlPolicySubject): string {\n return `${subject.namespaceId}\\u0000${subject.entityKind ?? ''}\\u0000${subject.entityName ?? ''}`;\n}\n","/**\n * Codec lifecycle hook planner — runs `onFieldEvent` for every per-field\n * delta between two contracts and concatenates the returned ops in a\n * deterministic order.\n *\n * Wired by each target's planner (`PostgresMigrationPlanner`,\n * `SqliteMigrationPlanner`) so codec-emitted ops are inlined alongside\n * structural DDL in the app-space migration's `ops.json`. Pure, target-\n * agnostic, and only ever invoked at the app-space emitter; extension-space\n * planning never reaches this helper.\n *\n * Ordering rules (see ADR 213):\n *\n * - Events are grouped by phase: `'added'` → `'dropped'` → `'altered'`.\n * - Within each phase, entries are sorted alphabetically by\n * `(namespaceId, tableName, fieldName)`.\n * - The hook's returned ops are appended in the order the hook returned them.\n *\n * `'altered'` is suppressed when only `codecId` differs (codec rotation is a\n * v1 non-goal).\n *\n * See: `docs/architecture docs/adrs/ADR 213 - Codec lifecycle hooks.md`.\n */\n\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { OpFactoryCall } from '@prisma-next/framework-components/control';\nimport { type SqlStorage, type StorageColumn, StorageTable } from '@prisma-next/sql-contract/types';\nimport type { CodecControlHooks, FieldEvent, FieldEventContext } from './types';\n\nexport interface PlanFieldEventOperationsOptions {\n /**\n * Prior contract the planner is diffing against. `null` for first emits\n * (every field is treated as added).\n */\n readonly priorContract: Contract<SqlStorage> | null;\n /**\n * New contract the user just authored.\n */\n readonly newContract: Contract<SqlStorage>;\n /**\n * Codec-id keyed map of control hooks, as produced by\n * {@link import('./assembly').extractCodecControlHooks}. Hooks carry\n * `unknown` target details after extraction; the caller casts the\n * helper's returned ops to its target's `SqlMigrationPlanOperation`\n * specialisation at the integration boundary, mirroring how\n * `storageTypePlanCallStrategy` lifts `planTypeOperations` results into\n * `RawSqlCall`.\n */\n readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;\n}\n\ninterface FieldEntry {\n readonly namespaceId: string;\n readonly tableName: string;\n readonly fieldName: string;\n readonly priorTable: StorageTable | undefined;\n readonly newTable: StorageTable | undefined;\n readonly priorField: StorageColumn | undefined;\n readonly newField: StorageColumn | undefined;\n}\n\nexport function planFieldEventOperations(\n options: PlanFieldEventOperationsOptions,\n): readonly OpFactoryCall[] {\n const priorContract = options.priorContract;\n const newContract = options.newContract;\n\n const added: FieldEntry[] = [];\n const dropped: FieldEntry[] = [];\n const altered: FieldEntry[] = [];\n\n const namespaceIds = unionSorted(\n priorContract ? Object.keys(priorContract.storage.namespaces) : [],\n Object.keys(newContract.storage.namespaces),\n );\n\n for (const namespaceId of namespaceIds) {\n const priorNs = priorContract?.storage.namespaces[namespaceId];\n const newNs = newContract.storage.namespaces[namespaceId];\n const priorTables = priorNs?.entries.table;\n const newTables = newNs?.entries.table;\n\n const tableNames = unionSorted(\n priorTables ? Object.keys(priorTables) : [],\n newTables ? Object.keys(newTables) : [],\n );\n\n for (const tableName of tableNames) {\n const priorTableRaw = priorTables?.[tableName];\n const newTableRaw = newTables?.[tableName];\n const priorTable = StorageTable.is(priorTableRaw) ? priorTableRaw : undefined;\n const newTable = StorageTable.is(newTableRaw) ? newTableRaw : undefined;\n const fieldNames = unionSorted(\n priorTable ? Object.keys(priorTable.columns) : [],\n newTable ? Object.keys(newTable.columns) : [],\n );\n for (const fieldName of fieldNames) {\n const priorField = priorTable?.columns[fieldName];\n const newField = newTable?.columns[fieldName];\n const entry: FieldEntry = {\n namespaceId,\n tableName,\n fieldName,\n priorTable,\n newTable,\n priorField,\n newField,\n };\n if (priorField === undefined && newField !== undefined) {\n added.push(entry);\n } else if (priorField !== undefined && newField === undefined) {\n dropped.push(entry);\n } else if (priorField !== undefined && newField !== undefined) {\n if (isAlteration(priorField, newField)) altered.push(entry);\n }\n }\n }\n }\n\n const calls: OpFactoryCall[] = [];\n appendCalls('added', added, options.codecHooks, calls, (e) => e.newField?.codecId);\n appendCalls('dropped', dropped, options.codecHooks, calls, (e) => e.priorField?.codecId);\n appendCalls('altered', altered, options.codecHooks, calls, (e) => e.newField?.codecId);\n return calls;\n}\n\nfunction appendCalls(\n event: FieldEvent,\n entries: readonly FieldEntry[],\n codecHooks: ReadonlyMap<string, CodecControlHooks>,\n calls: OpFactoryCall[],\n pickCodecId: (entry: FieldEntry) => string | undefined,\n): void {\n for (const entry of entries) {\n const codecId = pickCodecId(entry);\n if (codecId === undefined) continue;\n const hook = codecHooks.get(codecId);\n if (!hook?.onFieldEvent) continue;\n const ctx = buildContext(event, entry);\n const emitted = hook.onFieldEvent(event, ctx);\n for (const call of emitted) calls.push(call);\n }\n}\n\n/**\n * The context's prior/new sides are scoped to the event:\n *\n * - `'added'` — only `newTable` / `newField` populated.\n * - `'dropped'` — only `priorTable` / `priorField` populated.\n * - `'altered'` — both sides populated.\n */\nfunction buildContext(event: FieldEvent, entry: FieldEntry): FieldEventContext {\n const base = {\n namespaceId: entry.namespaceId,\n tableName: entry.tableName,\n fieldName: entry.fieldName,\n };\n if (event === 'added') {\n return {\n ...base,\n ...(entry.newTable !== undefined ? { newTable: entry.newTable } : {}),\n ...(entry.newField !== undefined ? { newField: entry.newField } : {}),\n };\n }\n if (event === 'dropped') {\n return {\n ...base,\n ...(entry.priorTable !== undefined ? { priorTable: entry.priorTable } : {}),\n ...(entry.priorField !== undefined ? { priorField: entry.priorField } : {}),\n };\n }\n return {\n ...base,\n ...(entry.priorTable !== undefined ? { priorTable: entry.priorTable } : {}),\n ...(entry.newTable !== undefined ? { newTable: entry.newTable } : {}),\n ...(entry.priorField !== undefined ? { priorField: entry.priorField } : {}),\n ...(entry.newField !== undefined ? { newField: entry.newField } : {}),\n };\n}\n\n/**\n * `'altered'` predicate. Returns `false` whenever `codecId` differs —\n * any codec change suppresses the `altered` event entirely, including\n * cases where another property also differs in the same diff. Codec\n * rotation is a v1 non-goal; avoiding the mixed event keeps the\n * migration semantics for codec changes explicit rather than smuggling\n * them through as `altered`.\n *\n * For non-`codecId` diffs, returns `true` iff any other column property\n * differs.\n */\nfunction isAlteration(prior: StorageColumn, current: StorageColumn): boolean {\n if (prior.codecId !== current.codecId) return false;\n return !sameStorageColumn(prior, current);\n}\n\nfunction sameStorageColumn(a: StorageColumn, b: StorageColumn): boolean {\n if (a === b) return true;\n if (a.nativeType !== b.nativeType) return false;\n if (a.nullable !== b.nullable) return false;\n if (a.typeRef !== b.typeRef) return false;\n if (!sameJson(a.typeParams, b.typeParams)) return false;\n if (!sameJson(a.default, b.default)) return false;\n return true;\n}\n\nfunction sameJson(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\nfunction unionSorted(a: readonly string[], b: readonly string[]): readonly string[] {\n const set = new Set<string>();\n for (const name of a) set.add(name);\n for (const name of b) set.add(name);\n return [...set].sort((x, y) => (x < y ? -1 : x > y ? 1 : 0));\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport { extractCodecControlHooks } from '../assembly';\n\n/**\n * Builds the codec-hook-composed `expandNativeType` callback the contract→IR\n * derivation uses to expand parameterized native types (e.g. `character` +\n * `{ length: 36 }` → `character(36)`). Returns `undefined` when no framework\n * components are supplied, so callers can omit the option entirely.\n */\nexport function buildNativeTypeExpander(\n frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n) {\n if (!frameworkComponents) {\n return undefined;\n }\n const codecHooks = extractCodecControlHooks(frameworkComponents);\n return (input: {\n readonly nativeType: string;\n readonly codecId?: string;\n readonly typeParams?: Record<string, unknown>;\n }) => {\n if (!input.typeParams) return input.nativeType;\n if (!input.codecId) return input.nativeType;\n const hooks = codecHooks.get(input.codecId);\n if (!hooks?.expandNativeType) return input.nativeType;\n return hooks.expandNativeType(input);\n };\n}\n","import type { NotOk, Ok } from '@prisma-next/utils/result';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport type {\n AnyRecord,\n CreateSqlMigrationPlanOptions,\n SqlMigrationPlan,\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n SqlMigrationPlanOperationTarget,\n SqlMigrationRunnerErrorCode,\n SqlMigrationRunnerFailure,\n SqlMigrationRunnerSuccessValue,\n SqlPlannerConflict,\n SqlPlannerFailureResult,\n SqlPlannerSuccessResult,\n} from './types';\n\nconst readOnlyEmptyObject: Record<string, never> = Object.freeze({});\n\nfunction cloneRecord<T extends AnyRecord>(value: T): T {\n if (value === readOnlyEmptyObject) {\n return value;\n }\n return Object.freeze({ ...value }) as T;\n}\n\nfunction freezeSteps(\n steps: readonly SqlMigrationPlanOperationStep[],\n): readonly SqlMigrationPlanOperationStep[] {\n if (steps.length === 0) {\n return Object.freeze([]);\n }\n return Object.freeze(\n steps.map((step) =>\n Object.freeze({\n description: step.description,\n sql: step.sql,\n ...(step.params ? { params: Object.freeze([...step.params]) } : {}),\n ...(step.meta ? { meta: cloneRecord(step.meta) } : {}),\n }),\n ),\n );\n}\n\nfunction freezeDetailsValue<T>(value: T): T {\n // Primitives and null/undefined are already immutable, return as-is\n if (value === null || value === undefined) {\n return value;\n }\n if (typeof value !== 'object') {\n return value;\n }\n // Arrays: shallow clone and freeze\n if (Array.isArray(value)) {\n return Object.freeze([...value]) as T;\n }\n // Objects: shallow clone and freeze (matching cloneRecord pattern)\n return Object.freeze({ ...value }) as T;\n}\n\nfunction freezeTargetDetails<TTargetDetails>(\n target: SqlMigrationPlanOperationTarget<TTargetDetails>,\n): SqlMigrationPlanOperationTarget<TTargetDetails> {\n return Object.freeze({\n id: target.id,\n ...(target.details !== undefined ? { details: freezeDetailsValue(target.details) } : {}),\n });\n}\n\nfunction freezeOperation<TTargetDetails>(\n operation: SqlMigrationPlanOperation<TTargetDetails>,\n): SqlMigrationPlanOperation<TTargetDetails> {\n return Object.freeze({\n id: operation.id,\n label: operation.label,\n ...(operation.summary ? { summary: operation.summary } : {}),\n operationClass: operation.operationClass,\n ...(operation.invariantId ? { invariantId: operation.invariantId } : {}),\n target: freezeTargetDetails(operation.target),\n precheck: freezeSteps(operation.precheck),\n execute: freezeSteps(operation.execute),\n postcheck: freezeSteps(operation.postcheck),\n ...(operation.meta ? { meta: cloneRecord(operation.meta) } : {}),\n });\n}\n\nfunction freezeOperations<TTargetDetails>(\n operations: readonly SqlMigrationPlanOperation<TTargetDetails>[],\n): readonly SqlMigrationPlanOperation<TTargetDetails>[] {\n if (operations.length === 0) {\n return Object.freeze([]);\n }\n return Object.freeze(operations.map((operation) => freezeOperation(operation)));\n}\n\nexport function createMigrationPlan<TTargetDetails>(\n options: CreateSqlMigrationPlanOptions<TTargetDetails>,\n): SqlMigrationPlan<TTargetDetails> {\n return Object.freeze({\n targetId: options.targetId,\n spaceId: options.spaceId,\n ...(options.origin !== undefined\n ? { origin: options.origin ? Object.freeze({ ...options.origin }) : null }\n : {}),\n destination: Object.freeze({ ...options.destination }),\n operations: freezeOperations(options.operations),\n providedInvariants: Object.freeze([...options.providedInvariants]),\n ...(options.meta ? { meta: cloneRecord(options.meta) } : {}),\n });\n}\n\nexport function plannerSuccess<TTargetDetails>(\n plan: SqlMigrationPlan<TTargetDetails>,\n warnings?: readonly SqlPlannerConflict[],\n): SqlPlannerSuccessResult<TTargetDetails> {\n return Object.freeze({\n kind: 'success',\n plan,\n ...(warnings && warnings.length > 0\n ? {\n warnings: Object.freeze(\n warnings.map((conflict) =>\n Object.freeze({\n kind: conflict.kind,\n summary: conflict.summary,\n ...(conflict.why ? { why: conflict.why } : {}),\n ...(conflict.location ? { location: Object.freeze({ ...conflict.location }) } : {}),\n ...(conflict.meta ? { meta: cloneRecord(conflict.meta) } : {}),\n }),\n ),\n ),\n }\n : {}),\n });\n}\n\nexport function plannerFailure(conflicts: readonly SqlPlannerConflict[]): SqlPlannerFailureResult {\n return Object.freeze({\n kind: 'failure' as const,\n conflicts: Object.freeze(\n conflicts.map((conflict) =>\n Object.freeze({\n kind: conflict.kind,\n summary: conflict.summary,\n ...(conflict.why ? { why: conflict.why } : {}),\n ...(conflict.location ? { location: Object.freeze({ ...conflict.location }) } : {}),\n ...(conflict.meta ? { meta: cloneRecord(conflict.meta) } : {}),\n }),\n ),\n ),\n });\n}\n\n/**\n * Creates a successful migration runner result.\n */\nexport function runnerSuccess(value: {\n operationsPlanned: number;\n operationsExecuted: number;\n}): Ok<SqlMigrationRunnerSuccessValue> {\n return ok(\n Object.freeze({\n operationsPlanned: value.operationsPlanned,\n operationsExecuted: value.operationsExecuted,\n }),\n );\n}\n\n/**\n * Creates a failed migration runner result.\n */\nexport function runnerFailure(\n code: SqlMigrationRunnerErrorCode,\n summary: string,\n options?: { why?: string; meta?: AnyRecord },\n): NotOk<SqlMigrationRunnerFailure> {\n const failure: SqlMigrationRunnerFailure = Object.freeze({\n code,\n summary,\n ...(options?.why ? { why: options.why } : {}),\n ...(options?.meta ? { meta: cloneRecord(options.meta) } : {}),\n });\n return notOk(failure);\n}\n","import type { MigrationOperationPolicy } from '@prisma-next/framework-components/control';\n\n/**\n * Policy used by `db init`: additive-only operations, no widening/destructive steps.\n */\nexport const INIT_ADDITIVE_POLICY: MigrationOperationPolicy = Object.freeze({\n allowedOperationClasses: Object.freeze(['additive'] as const),\n});\n","import { SqlFamilyDescriptor } from '../core/control-descriptor';\n\n// Re-export core types from canonical source\nexport type {\n MigrationOperationClass,\n MigrationOperationPolicy,\n MigrationPlan,\n MigrationPlanner,\n MigrationPlannerConflict,\n MigrationPlannerResult,\n MigrationPlanOperation,\n TargetMigrationsCapability,\n} from '@prisma-next/framework-components/control';\nexport { assembleAuthoringContributions } from '@prisma-next/framework-components/control';\nexport { extractCodecControlHooks } from '../core/assembly';\nexport type { SqlControlFamilyInstance } from '../core/control-instance';\nexport type {\n SqlControlTargetDescriptor,\n SqlDescribedContractSpace,\n} from '../core/control-target-descriptor';\nexport type {\n ContractToSchemaIROptions,\n DefaultRenderer,\n DefaultResolver,\n EnumNamespaceSchemaResolver,\n NativeTypeExpander,\n} from '../core/migrations/contract-to-schema-ir';\n// Contract → SchemaIR conversion for offline migration planning\nexport {\n contractNamespaceToSchemaIR,\n contractToSchemaIR,\n detectDestructiveChanges,\n resolveValueSetValues,\n} from '../core/migrations/contract-to-schema-ir';\nexport type { ControlPolicySubject, SuppressionRecord } from '../core/migrations/control-policy';\nexport {\n controlPolicyForCall,\n partitionCallsByControlPolicy,\n partitionIssuesByControlPolicy,\n} from '../core/migrations/control-policy';\nexport type { PlanFieldEventOperationsOptions } from '../core/migrations/field-event-planner';\nexport { planFieldEventOperations } from '../core/migrations/field-event-planner';\nexport { buildNativeTypeExpander } from '../core/migrations/native-type-expander';\nexport {\n createMigrationPlan,\n plannerFailure,\n plannerSuccess,\n runnerFailure,\n runnerSuccess,\n} from '../core/migrations/plan-helpers';\nexport { INIT_ADDITIVE_POLICY } from '../core/migrations/policies';\nexport type {\n SqlSchemaDiffFn,\n SqlSchemaDiffInput,\n SqlSchemaDiffResult,\n} from '../core/migrations/schema-differ';\nexport type {\n CodecControlHooks,\n CreateSqlMigrationPlanOptions,\n ExpandNativeTypeInput,\n FieldEvent,\n FieldEventContext,\n ResolveIdentityValueInput,\n SqlControlAdapterDescriptor,\n SqlControlExtensionDescriptor,\n SqlMigrationPlan,\n SqlMigrationPlanContractInfo,\n SqlMigrationPlanner,\n SqlMigrationPlannerPlanOptions,\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n SqlMigrationPlanOperationTarget,\n SqlMigrationRunner,\n SqlMigrationRunnerErrorCode,\n SqlMigrationRunnerExecuteCallbacks,\n SqlMigrationRunnerExecuteOptions,\n SqlMigrationRunnerFailure,\n SqlMigrationRunnerResult,\n SqlMigrationRunnerSuccessValue,\n SqlPlannerConflict,\n SqlPlannerConflictKind,\n SqlPlannerConflictLocation,\n SqlPlannerFailureResult,\n SqlPlannerResult,\n SqlPlannerSuccessResult,\n SqlPlanTargetDetails,\n StorageTypePlanResult,\n} from '../core/migrations/types';\nexport {\n temporalAuthoringPresets,\n temporalCodecPreset,\n temporalCodecPresetWithPrecision,\n timestampNowControlDescriptor,\n} from '../core/timestamp-now-generator';\n\nexport default new SqlFamilyDescriptor();\n"],"mappings":"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"}
|