🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@prisma-next/framework-components

Package Overview
Dependencies
Maintainers
4
Versions
444
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@prisma-next/framework-components - npm Package Compare versions

Comparing version
0.14.0-dev.33
to
0.14.0-dev.35
+1
-1
dist/control.mjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"control.mjs","names":[],"sources":["../src/control/control-capabilities.ts","../src/control/control-result-types.ts","../src/control/control-schema-view.ts","../src/control/control-spaces.ts","../src/control/control-stack.ts","../src/control/schema-diff.ts","../src/control/verifier-disposition.ts"],"sourcesContent":["import type { ControlTargetDescriptor } from './control-descriptors';\nimport type { ControlFamilyInstance } from './control-instances';\nimport type { MigrationPlanOperation, TargetMigrationsCapability } from './control-migration-types';\nimport type { OperationPreview } from './control-operation-preview';\nimport type { CoreSchemaView } from './control-schema-view';\nimport type { PslDocumentAst } from './psl-ast';\n\nexport interface MigratableTargetDescriptor<\n TFamilyId extends string,\n TTargetId extends string,\n TFamilyInstance extends ControlFamilyInstance<TFamilyId, unknown> = ControlFamilyInstance<\n TFamilyId,\n unknown\n >,\n> extends ControlTargetDescriptor<TFamilyId, TTargetId> {\n readonly migrations: TargetMigrationsCapability<TFamilyId, TTargetId, TFamilyInstance>;\n}\n\nexport function hasMigrations<TFamilyId extends string, TTargetId extends string>(\n target: ControlTargetDescriptor<TFamilyId, TTargetId>,\n): target is MigratableTargetDescriptor<TFamilyId, TTargetId> {\n return 'migrations' in target && !!(target as Record<string, unknown>)['migrations'];\n}\n\nexport interface SchemaViewCapable<TSchemaIR = unknown> {\n toSchemaView(schema: TSchemaIR): CoreSchemaView;\n}\n\nexport function hasSchemaView<TFamilyId extends string, TSchemaIR>(\n instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,\n): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & SchemaViewCapable<TSchemaIR> {\n return (\n 'toSchemaView' in instance &&\n typeof (instance as Record<string, unknown>)['toSchemaView'] === 'function'\n );\n}\n\n/**\n * Capability declaring that a family can infer a PSL contract AST from its\n * opaque introspected schema IR. Consumed by `prisma-next contract infer`.\n */\nexport interface PslContractInferCapable<TSchemaIR = unknown> {\n inferPslContract(schemaIR: TSchemaIR): PslDocumentAst;\n}\n\nexport function hasPslContractInfer<TFamilyId extends string, TSchemaIR>(\n instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,\n): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & PslContractInferCapable<TSchemaIR> {\n return (\n 'inferPslContract' in instance &&\n typeof (instance as Record<string, unknown>)['inferPslContract'] === 'function'\n );\n}\n\n/**\n * Capability declaring that a family can render a textual preview of migration\n * operations for the CLI's \"DDL preview\" output. SQL families emit\n * `language: 'sql'` statements; Mongo families emit `language: 'mongodb-shell'`.\n */\nexport interface OperationPreviewCapable {\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview;\n}\n\nexport function hasOperationPreview<TFamilyId extends string, TSchemaIR>(\n instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,\n): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & OperationPreviewCapable {\n return (\n 'toOperationPreview' in instance &&\n typeof (instance as Record<string, unknown>)['toOperationPreview'] === 'function'\n );\n}\n","import type { SchemaDiffIssue } from './schema-diff';\n\nexport const VERIFY_CODE_MARKER_MISSING = 'PN-RUN-3001';\nexport const VERIFY_CODE_HASH_MISMATCH = 'PN-RUN-3002';\nexport const VERIFY_CODE_TARGET_MISMATCH = 'PN-RUN-3003';\nexport const VERIFY_CODE_SCHEMA_FAILURE = 'PN-RUN-3010';\n\nexport interface OperationContext {\n readonly contractPath?: string;\n readonly configPath?: string;\n readonly meta?: Readonly<Record<string, unknown>>;\n}\n\nexport interface VerifyDatabaseResult {\n readonly ok: boolean;\n readonly code?: string;\n readonly summary: string;\n readonly contract: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n readonly marker?: {\n readonly storageHash?: string;\n readonly profileHash?: string;\n };\n readonly target: {\n readonly expected: string;\n readonly actual?: string;\n };\n readonly missingCodecs?: readonly string[];\n readonly codecCoverageSkipped?: boolean;\n readonly meta?: {\n readonly configPath?: string;\n readonly contractPath: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nexport interface BaseSchemaIssue {\n readonly kind:\n | 'missing_schema'\n | 'missing_table'\n | 'missing_column'\n | 'extra_table'\n | 'extra_column'\n | 'extra_primary_key'\n | 'extra_foreign_key'\n | 'extra_unique_constraint'\n | 'extra_index'\n | 'extra_validator'\n | 'type_mismatch'\n | 'type_missing'\n | 'type_values_mismatch'\n | 'nullability_mismatch'\n | 'primary_key_mismatch'\n | 'foreign_key_mismatch'\n | 'unique_constraint_mismatch'\n | 'index_mismatch'\n | 'default_missing'\n | 'default_mismatch'\n | 'extra_default'\n | 'check_missing'\n | 'check_removed'\n | 'check_mismatch';\n readonly table?: string;\n /**\n * Namespace coordinate of the issue's subject (e.g. the schema a SQL\n * table lives in). Populated by family verifiers that have the\n * coordinate in scope when constructing the issue; absent for issues\n * whose family has no namespace concept (e.g. Mongo collections) or\n * whose subject isn't in any contract namespace (e.g. an extra-table\n * issue raised for a table that exists in the live DB but not in the\n * contract).\n *\n * Downstream planners trust this field as the authoritative subject\n * coordinate and do not re-derive it by name lookup. A finer-grained\n * structural split between framework-shared and family-specific issue\n * fields is tracked under a follow-up ticket.\n */\n readonly namespaceId?: string;\n readonly column?: string;\n readonly indexOrConstraint?: string;\n readonly typeName?: string;\n readonly expected?: string;\n readonly actual?: string;\n readonly message: string;\n}\n\nexport interface EnumValuesChangedIssue {\n readonly kind: 'enum_values_changed';\n /**\n * Namespace coordinate of the enum type that changed values. Populated by\n * family verifiers that have the coordinate in scope when constructing the\n * issue. Downstream planners trust this field as the authoritative subject\n * coordinate and do not re-derive it by name lookup.\n */\n readonly namespaceId: string;\n readonly typeName: string;\n readonly addedValues: readonly string[];\n readonly removedValues: readonly string[];\n readonly message: string;\n}\n\nexport type SchemaIssue = BaseSchemaIssue | EnumValuesChangedIssue;\n\nexport interface SchemaVerificationNode {\n readonly status: 'pass' | 'warn' | 'fail';\n readonly kind: string;\n readonly name: string;\n readonly contractPath: string;\n readonly code: string;\n readonly message: string;\n readonly expected: unknown;\n readonly actual: unknown;\n readonly children: readonly SchemaVerificationNode[];\n}\n\nexport interface VerifyDatabaseSchemaResult {\n readonly ok: boolean;\n readonly code?: string;\n readonly summary: string;\n readonly contract: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n readonly target: {\n readonly expected: string;\n readonly actual?: string;\n };\n readonly schema: {\n readonly issues: readonly SchemaIssue[];\n readonly schemaDiffIssues: readonly SchemaDiffIssue[];\n readonly root: SchemaVerificationNode;\n readonly counts: {\n readonly pass: number;\n readonly warn: number;\n readonly fail: number;\n readonly totalNodes: number;\n };\n };\n readonly meta?: {\n readonly configPath?: string;\n readonly contractPath?: string;\n readonly strict: boolean;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nexport interface EmitContractResult {\n readonly contractJson: string;\n readonly contractDts: string;\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n}\n\nexport interface IntrospectSchemaResult<TSchemaIR> {\n readonly ok: true;\n readonly summary: string;\n readonly target: {\n readonly familyId: string;\n readonly id: string;\n };\n readonly schema: TSchemaIR;\n readonly meta?: {\n readonly configPath?: string;\n readonly dbUrl?: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nexport interface SignDatabaseResult {\n readonly ok: boolean;\n readonly summary: string;\n readonly contract: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n readonly target: {\n readonly expected: string;\n readonly actual?: string;\n };\n readonly marker: {\n readonly created: boolean;\n readonly updated: boolean;\n readonly previous?: {\n readonly storageHash?: string;\n readonly profileHash?: string;\n };\n };\n readonly meta?: {\n readonly configPath?: string;\n readonly contractPath: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n","/**\n * Core schema view types for family-agnostic schema visualization.\n *\n * These types provide a minimal, generic, tree-shaped representation of schemas\n * across families, designed for CLI visualization and lightweight tooling.\n *\n * Families can optionally project their family-specific Schema IR into this\n * core view via the `toSchemaView` method on `FamilyInstance`.\n */\n\nexport type SchemaViewNodeKind =\n | 'root'\n | 'namespace'\n | 'collection'\n | 'entity'\n | 'field'\n | 'index'\n | 'dependency';\n\nexport interface SchemaTreeVisitor<R> {\n visit(node: SchemaTreeNode): R;\n}\n\nexport interface SchemaTreeNodeOptions {\n readonly kind: SchemaViewNodeKind;\n readonly id: string;\n readonly label: string;\n readonly meta?: Record<string, unknown>;\n readonly children?: readonly SchemaTreeNode[];\n}\n\nexport class SchemaTreeNode {\n readonly kind: SchemaViewNodeKind;\n readonly id: string;\n readonly label: string;\n readonly meta?: Record<string, unknown>;\n readonly children?: readonly SchemaTreeNode[];\n\n constructor(options: SchemaTreeNodeOptions) {\n this.kind = options.kind;\n this.id = options.id;\n this.label = options.label;\n if (options.meta !== undefined) this.meta = options.meta;\n if (options.children !== undefined) this.children = options.children;\n Object.freeze(this);\n }\n\n accept<R>(visitor: SchemaTreeVisitor<R>): R {\n return visitor.visit(this);\n }\n}\n\n/**\n * Core schema view providing a family-agnostic tree representation of a schema.\n * Used by CLI and cross-family tooling for visualization.\n */\nexport interface CoreSchemaView {\n readonly root: SchemaTreeNode;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { MigrationMetadata, MigrationPlanOperation } from './control-migration-types';\n\n/**\n * Canonical control-plane identifiers for contract spaces.\n *\n * A contract space is the disjoint `(contract.json, migration-graph)` unit\n * the per-space planner / runner / verifier (project: extension contract\n * spaces, TML-2397) operates on. The application owns one well-known\n * space — the value below — and each loaded extension that contributes\n * schema owns a uniquely-named space.\n *\n * Lives in `framework-components/control` so every layer that has to\n * reason about space identity (the migration tooling, the SQL runtime's\n * marker reader, target-side statement builders, target-side adapters)\n * can import a single value rather than duplicating the literal. Raw\n * `'app'` string literals in framework / target / runtime / adapter\n * source code are forbidden and policed by\n * `scripts/lint-app-space-id.mjs` (wired into `pnpm lint:deps`).\n *\n * @see specs/framework-mechanism.spec.md § 3 — Layout convention (γ).\n */\nexport const APP_SPACE_ID = 'app' as const;\n\n/**\n * Head ref for a contract space — the `(hash, invariants)` tuple\n * a runner targets when applying that space's migration graph. Identical\n * in shape to the on-disk `migrations/<space-id>/refs/head.json` the\n * framework writes per loaded extension, and to the app-space\n * `<projectRoot>/refs/head.json`. Family-agnostic: SQL, Mongo, and any\n * future family share the same head-ref shape.\n *\n * @see specs/framework-mechanism.spec.md § 1.\n */\nexport interface ContractSpaceHeadRef {\n readonly hash: string;\n readonly invariants: readonly string[];\n}\n\n/**\n * Canonical structural shape of a migration package — the unit a planner\n * produces and a runner consumes: a directory name, the metadata\n * envelope, and the operation list.\n *\n * In-memory by default. Readers in `@prisma-next/migration-tools`\n * (`readMigrationPackage` / `readMigrationsDir`) return the augmented\n * {@link import('@prisma-next/migration-tools/package').OnDiskMigrationPackage}\n * variant which adds `dirPath`; everything else operates against the\n * canonical shape so the same value flows through pre-emission\n * authoring, on-disk loading, and runner execution without conversion.\n *\n * @see specs/framework-mechanism.spec.md § 1.\n */\nexport interface MigrationPackage {\n readonly dirName: string;\n readonly metadata: MigrationMetadata;\n readonly ops: readonly MigrationPlanOperation[];\n}\n\n/**\n * Canonical structural shape of a contract space — one disjoint\n * `(contractJson, migration-graph)` unit the per-space planner / runner\n * / verifier operates on. The application owns one well-known space\n * ({@link APP_SPACE_ID}); each loaded extension that contributes schema\n * owns a uniquely-named space. Whether a value is the app's space or an\n * extension's space is a control-plane concern; the type carries no\n * such distinction.\n *\n * Generic over the contract so each family pins a typed contract value\n * at consumption time. The SQL family specialises to\n * `ContractSpace<Contract<SqlStorage>>` at the descriptor surface;\n * Mongo's symmetrical `ContractSpace<Contract<MongoStorage>>` will land\n * with that family.\n *\n * @see specs/framework-mechanism.spec.md § 1.\n */\nexport interface ContractSpace<TContract extends Contract = Contract> {\n readonly contractJson: TContract;\n readonly migrations: readonly MigrationPackage[];\n readonly headRef: ContractSpaceHeadRef;\n}\n","import type { JsonValue } from '@prisma-next/contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { Codec } from '../shared/codec';\nimport type { AnyCodecDescriptor } from '../shared/codec-descriptor';\nimport type { CodecLookup, CodecMeta, CodecRef, CodecRegistry } from '../shared/codec-types';\nimport type {\n AuthoringContributions,\n AuthoringEntityTypeNamespace,\n AuthoringFieldNamespace,\n AuthoringPslBlockDescriptorNamespace,\n AuthoringTypeNamespace,\n} from '../shared/framework-authoring';\nimport {\n assertNoCrossRegistryCollisions,\n isAuthoringEntityTypeDescriptor,\n isAuthoringFieldPresetDescriptor,\n isAuthoringPslBlockDescriptor,\n isAuthoringTypeConstructorDescriptor,\n mergeAuthoringNamespaces,\n} from '../shared/framework-authoring';\nimport type { ComponentMetadata } from '../shared/framework-components';\nimport type {\n ControlMutationDefaultEntry,\n ControlMutationDefaults,\n MutationDefaultGeneratorDescriptor,\n} from '../shared/mutation-default-types';\nimport {\n CONTRACT_CODEC_DESCRIPTOR_MISSING,\n materializeCodec,\n resolveCodecDescriptorOrThrow,\n} from '../shared/resolve-codec';\nimport type { TypesImportSpec } from '../shared/types-import-spec';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n ControlTargetDescriptor,\n} from './control-descriptors';\n\nexport interface AssembledAuthoringContributions {\n readonly field: AuthoringFieldNamespace;\n readonly type: AuthoringTypeNamespace;\n readonly entityTypes: AuthoringEntityTypeNamespace;\n readonly pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace;\n}\n\nexport interface ControlStack<\n TFamilyId extends string = string,\n TTargetId extends string = string,\n> {\n readonly family: ControlFamilyDescriptor<TFamilyId>;\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter?: ControlAdapterDescriptor<TFamilyId, TTargetId> | undefined;\n readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;\n readonly extensionPacks: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];\n\n readonly codecTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly queryOperationTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly extensionIds: ReadonlyArray<string>;\n readonly codecLookup: CodecRegistry;\n readonly authoringContributions: AssembledAuthoringContributions;\n readonly scalarTypeDescriptors: ReadonlyMap<string, string>;\n readonly controlMutationDefaults: ControlMutationDefaults;\n}\n\nexport interface CreateControlStackInput<\n TFamilyId extends string = string,\n TTargetId extends string = string,\n> {\n readonly family: ControlFamilyDescriptor<TFamilyId>;\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter?: ControlAdapterDescriptor<TFamilyId, TTargetId> | undefined;\n readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;\n readonly extensionPacks?:\n | ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>\n | undefined;\n}\n\nfunction addUniqueId(ids: string[], seen: Set<string>, id: string): void {\n if (!seen.has(id)) {\n ids.push(id);\n seen.add(id);\n }\n}\n\nexport function assertUniqueCodecOwner(options: {\n readonly codecId: string;\n readonly owners: Map<string, string>;\n readonly descriptorId: string;\n readonly entityLabel: string;\n readonly entityOwnershipLabel: string;\n}): void {\n const existingOwner = options.owners.get(options.codecId);\n if (existingOwner !== undefined) {\n throw new Error(\n `Duplicate ${options.entityLabel} for codecId \"${options.codecId}\". ` +\n `Descriptor \"${options.descriptorId}\" conflicts with \"${existingOwner}\". ` +\n `Each codecId can only have one ${options.entityOwnershipLabel}.`,\n );\n }\n}\n\nexport function extractCodecTypeImports(\n descriptors: ReadonlyArray<Pick<ComponentMetadata, 'types'>>,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const codecTypes = descriptor.types?.codecTypes;\n if (codecTypes?.import) {\n imports.push(codecTypes.import);\n }\n if (codecTypes?.typeImports) {\n imports.push(...codecTypes.typeImports);\n }\n }\n\n return imports;\n}\n\nexport function extractQueryOperationTypeImports(\n descriptors: ReadonlyArray<Pick<ComponentMetadata, 'types'>>,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const queryOperationTypes = descriptor.types?.queryOperationTypes;\n if (queryOperationTypes?.import) {\n imports.push(queryOperationTypes.import);\n }\n }\n\n return imports;\n}\n\nexport function extractComponentIds(\n family: { readonly id: string },\n target: { readonly id: string },\n adapter: { readonly id: string } | undefined,\n extensions: ReadonlyArray<{ readonly id: string }>,\n): ReadonlyArray<string> {\n const ids: string[] = [];\n const seen = new Set<string>();\n\n addUniqueId(ids, seen, family.id);\n addUniqueId(ids, seen, target.id);\n if (adapter) {\n addUniqueId(ids, seen, adapter.id);\n }\n\n for (const ext of extensions) {\n addUniqueId(ids, seen, ext.id);\n }\n\n return ids;\n}\n\nexport function assembleAuthoringContributions(\n descriptors: ReadonlyArray<{ readonly authoring?: AuthoringContributions }>,\n): AssembledAuthoringContributions {\n const field = {} as Record<string, unknown>;\n const type = {} as Record<string, unknown>;\n const entityTypes = {} as Record<string, unknown>;\n const pslBlockDescriptors: Record<string, unknown> = {};\n\n for (const descriptor of descriptors) {\n if (descriptor.authoring?.field) {\n mergeAuthoringNamespaces(\n field,\n descriptor.authoring.field,\n [],\n isAuthoringFieldPresetDescriptor,\n 'field',\n );\n }\n if (descriptor.authoring?.type) {\n mergeAuthoringNamespaces(\n type,\n descriptor.authoring.type,\n [],\n isAuthoringTypeConstructorDescriptor,\n 'type',\n );\n }\n if (descriptor.authoring?.entityTypes) {\n mergeAuthoringNamespaces(\n entityTypes,\n descriptor.authoring.entityTypes,\n [],\n isAuthoringEntityTypeDescriptor,\n 'entity',\n );\n }\n if (descriptor.authoring?.pslBlockDescriptors) {\n mergeAuthoringNamespaces(\n pslBlockDescriptors,\n descriptor.authoring.pslBlockDescriptors,\n [],\n isAuthoringPslBlockDescriptor,\n 'pslBlock',\n );\n }\n }\n\n const fieldNamespace = field as AuthoringFieldNamespace;\n const typeNamespace = type as AuthoringTypeNamespace;\n const entityTypeNamespace = entityTypes as AuthoringEntityTypeNamespace;\n const pslBlockDescriptorNamespace = blindCast<\n AuthoringPslBlockDescriptorNamespace,\n 'merge target accumulator narrows to typed namespace post-merge'\n >(pslBlockDescriptors);\n assertNoCrossRegistryCollisions(\n typeNamespace,\n fieldNamespace,\n entityTypeNamespace,\n pslBlockDescriptorNamespace,\n );\n\n return {\n field: fieldNamespace,\n type: typeNamespace,\n entityTypes: entityTypeNamespace,\n pslBlockDescriptors: pslBlockDescriptorNamespace,\n };\n}\n\nexport function assembleScalarTypeDescriptors(\n descriptors: ReadonlyArray<\n Pick<ComponentMetadata, 'scalarTypeDescriptors'> & { readonly id?: string }\n >,\n): ReadonlyMap<string, string> {\n const result = new Map<string, string>();\n const owners = new Map<string, string>();\n\n for (const descriptor of descriptors) {\n const descriptorMap = descriptor.scalarTypeDescriptors;\n if (!descriptorMap) continue;\n const descriptorId = descriptor.id ?? '<unknown>';\n for (const [typeName, codecId] of descriptorMap) {\n const existingOwner = owners.get(typeName);\n if (existingOwner !== undefined) {\n throw new Error(\n `Duplicate scalar type descriptor \"${typeName}\". ` +\n `Descriptor \"${descriptorId}\" conflicts with \"${existingOwner}\".`,\n );\n }\n result.set(typeName, codecId);\n owners.set(typeName, descriptorId);\n }\n }\n\n return result;\n}\n\nexport function assembleControlMutationDefaults(\n descriptors: ReadonlyArray<\n Pick<ComponentMetadata, 'controlMutationDefaults'> & { readonly id?: string }\n >,\n): ControlMutationDefaults {\n const defaultFunctionRegistry = new Map<string, ControlMutationDefaultEntry>();\n const functionOwners = new Map<string, string>();\n const generatorMap = new Map<string, MutationDefaultGeneratorDescriptor>();\n const generatorOwners = new Map<string, string>();\n\n for (const descriptor of descriptors) {\n const contributions = descriptor.controlMutationDefaults;\n if (!contributions) continue;\n const descriptorId = descriptor.id ?? '<unknown>';\n\n for (const generatorDescriptor of contributions.generatorDescriptors) {\n const existingOwner = generatorOwners.get(generatorDescriptor.id);\n if (existingOwner !== undefined) {\n throw new Error(\n `Duplicate mutation default generator id \"${generatorDescriptor.id}\". ` +\n `Descriptor \"${descriptorId}\" conflicts with \"${existingOwner}\".`,\n );\n }\n generatorMap.set(generatorDescriptor.id, generatorDescriptor);\n generatorOwners.set(generatorDescriptor.id, descriptorId);\n }\n\n for (const [functionName, handler] of contributions.defaultFunctionRegistry) {\n const existingOwner = functionOwners.get(functionName);\n if (existingOwner !== undefined) {\n throw new Error(\n `Duplicate mutation default function \"${functionName}\". ` +\n `Descriptor \"${descriptorId}\" conflicts with \"${existingOwner}\".`,\n );\n }\n defaultFunctionRegistry.set(functionName, handler);\n functionOwners.set(functionName, descriptorId);\n }\n }\n\n return {\n defaultFunctionRegistry,\n generatorDescriptors: Array.from(generatorMap.values()),\n };\n}\n\nexport function extractCodecLookup(\n descriptors: ReadonlyArray<Pick<ComponentMetadata & { id: string }, 'types' | 'id'>>,\n): CodecRegistry {\n const byId = new Map<string, Codec>();\n const descriptorsById = new Map<string, AnyCodecDescriptor>();\n const targetTypesById = new Map<string, readonly string[]>();\n const metaById = new Map<string, CodecMeta>();\n const renderersById = new Map<string, (params: Record<string, unknown>) => string | undefined>();\n const inputRenderersById = new Map<\n string,\n (params: Record<string, unknown>) => string | undefined\n >();\n const valueLiteralRenderersById = new Map<\n string,\n (value: JsonValue, side: 'output' | 'input') => string | undefined\n >();\n const owners = new Map<string, string>();\n for (const descriptor of descriptors) {\n const codecTypes = descriptor.types?.codecTypes;\n const descriptorId = descriptor.id;\n // Descriptor-side metadata is the single source of truth for `targetTypes` / `meta` / `renderOutputType`. Every contributor ships a `codecDescriptors` list on `types.codecTypes`.\n for (const codecDescriptor of codecTypes?.codecDescriptors ?? []) {\n assertUniqueCodecOwner({\n codecId: codecDescriptor.codecId,\n owners,\n descriptorId,\n entityLabel: 'codec descriptor',\n entityOwnershipLabel: 'codec descriptor provider',\n });\n owners.set(codecDescriptor.codecId, descriptorId);\n descriptorsById.set(codecDescriptor.codecId, codecDescriptor);\n if (Array.isArray(codecDescriptor.targetTypes)) {\n targetTypesById.set(codecDescriptor.codecId, codecDescriptor.targetTypes);\n }\n if (codecDescriptor.meta !== undefined) {\n metaById.set(codecDescriptor.codecId, codecDescriptor.meta);\n }\n if (typeof codecDescriptor.renderOutputType === 'function') {\n renderersById.set(codecDescriptor.codecId, codecDescriptor.renderOutputType);\n }\n if (typeof codecDescriptor.renderInputType === 'function') {\n inputRenderersById.set(codecDescriptor.codecId, codecDescriptor.renderInputType);\n }\n if (typeof codecDescriptor.renderValueLiteral === 'function') {\n valueLiteralRenderersById.set(codecDescriptor.codecId, codecDescriptor.renderValueLiteral);\n }\n // Materialize a representative `Codec` instance for `byId.get()` so consumers reading the lookup's instance side (e.g. SQL renderer's cast-policy lookup, or the contract emitter's literal-default `encodeJson` resolver) keep finding the codec.\n //\n // Two cohorts:\n // - Non-parameterized descriptors: factory must succeed; any throw is a real bug and we let it propagate (no silent try/catch).\n // - Parameterized descriptors: try with empty params. Many parameterized codecs treat params as advisory (e.g. `pg/timestamptz@1` whose precision is rendered into the `nativeType` only and never read by the runtime codec), so an empty-params construction yields a usable representative for id-keyed lookups (e.g. emit-time literal-default encoding). Codecs whose factory genuinely requires params (e.g. `pg/vector@1` threading `length` into the runtime codec) will throw; for those, per-column instances are materialized at runtime by `buildContractCodecRegistry` and the id-keyed lookup miss is correct (the column-aware path resolves them).\n if (!byId.has(codecDescriptor.codecId)) {\n if (codecDescriptor.isParameterized) {\n try {\n const representative = codecDescriptor.factory({} as never)({\n name: `<lookup:${codecDescriptor.codecId}>`,\n } as Parameters<ReturnType<typeof codecDescriptor.factory>>[0]);\n byId.set(codecDescriptor.codecId, representative);\n } catch {\n // Factory requires concrete params; skip representative materialization. Per-column instances are built at runtime; id-keyed lookup miss is the correct outcome here.\n }\n } else {\n const representative = codecDescriptor.factory(undefined as never)({\n name: `<lookup:${codecDescriptor.codecId}>`,\n } as Parameters<ReturnType<typeof codecDescriptor.factory>>[0]);\n byId.set(codecDescriptor.codecId, representative);\n }\n }\n }\n }\n return {\n get: (id) => byId.get(id),\n forCodecRef(ref: CodecRef) {\n const d = resolveCodecDescriptorOrThrow(\n (id) => descriptorsById.get(id),\n ref,\n CONTRACT_CODEC_DESCRIPTOR_MISSING,\n );\n return materializeCodec(d, ref, { name: `<ref:${ref.codecId}>` });\n },\n forColumn: () => undefined,\n targetTypesFor: (id) => targetTypesById.get(id),\n metaFor: (id) => metaById.get(id),\n renderOutputTypeFor: (id, params) => renderersById.get(id)?.(params),\n renderInputTypeFor: (id, params) => inputRenderersById.get(id)?.(params),\n renderValueLiteralFor: (id, value, side) => valueLiteralRenderersById.get(id)?.(value, side),\n };\n}\n\nexport function validateScalarTypeCodecIds(\n scalarTypeDescriptors: ReadonlyMap<string, string>,\n codecLookup: CodecLookup,\n): string[] {\n const errors: string[] = [];\n for (const [typeName, codecId] of scalarTypeDescriptors) {\n if (!codecLookup.get(codecId)) {\n errors.push(\n `Scalar type \"${typeName}\" references codec \"${codecId}\" which is not registered by any component.`,\n );\n }\n }\n return errors;\n}\n\ninterface DependencyDeclaringDescriptor {\n readonly id: string;\n readonly contractSpace?: {\n readonly contractJson?: {\n readonly extensionPacks?: Readonly<Record<string, unknown>>;\n };\n };\n}\n\nfunction readDeclaredDependencyIds(descriptor: DependencyDeclaringDescriptor): readonly string[] {\n const packs = descriptor.contractSpace?.contractJson?.extensionPacks;\n if (packs === null || typeof packs !== 'object') return [];\n return Object.keys(packs);\n}\n\n/**\n * Builds a dependency-respecting load order for the given extension descriptors\n * using Kahn's topological sort algorithm. Dependencies (packs declared in\n * `contractSpace.contractJson.extensionPacks`) are placed before the extensions\n * that depend on them.\n *\n * Throws if the dependency graph contains a cycle, with an error message that\n * names every extension involved in the cycle.\n *\n * Throws if any extension declares a dependency on a pack ID that is not present\n * in the provided list — add the missing pack to the `extensionPacks` list to\n * resolve the error.\n */\n\nexport function buildExtensionLoadOrder(\n extensions: ReadonlyArray<DependencyDeclaringDescriptor>,\n): readonly string[] {\n if (extensions.length === 0) return [];\n\n const idSet = new Set(extensions.map((e) => e.id));\n const inDegree = new Map<string, number>();\n const dependents = new Map<string, string[]>();\n\n for (const ext of extensions) {\n if (!inDegree.has(ext.id)) inDegree.set(ext.id, 0);\n if (!dependents.has(ext.id)) dependents.set(ext.id, []);\n }\n\n for (const ext of extensions) {\n for (const depId of readDeclaredDependencyIds(ext)) {\n if (!idSet.has(depId)) {\n throw new Error(\n `Extension \"${ext.id}\" declares a dependency on \"${depId}\", but \"${depId}\" is not in the provided extension set. Add the missing space to extensionPacks.`,\n );\n }\n inDegree.set(ext.id, (inDegree.get(ext.id) ?? 0) + 1);\n const list = dependents.get(depId);\n if (list !== undefined) list.push(ext.id);\n }\n }\n\n const queue: string[] = [];\n for (const [id, deg] of inDegree) {\n if (deg === 0) queue.push(id);\n }\n queue.sort();\n\n const result: string[] = [];\n while (queue.length > 0) {\n const id = queue.shift();\n if (id === undefined) break;\n result.push(id);\n const children = dependents.get(id) ?? [];\n children.sort();\n for (const childId of children) {\n const newDeg = (inDegree.get(childId) ?? 1) - 1;\n inDegree.set(childId, newDeg);\n if (newDeg === 0) queue.push(childId);\n }\n }\n\n if (result.length < extensions.length) {\n const cycleMembers = extensions\n .map((e) => e.id)\n .filter((id) => !result.includes(id))\n .sort();\n throw new Error(\n `Extension dependency cycle detected. Cycle members: ${cycleMembers.map((id) => `\"${id}\"`).join(', ')}.`,\n );\n }\n\n return result;\n}\n\nexport function createControlStack<TFamilyId extends string, TTargetId extends string>(\n input: CreateControlStackInput<TFamilyId, TTargetId>,\n): ControlStack<TFamilyId, TTargetId> {\n const { family, target, adapter, driver, extensionPacks = [] } = input;\n\n const orderedIds = buildExtensionLoadOrder(extensionPacks);\n const extensionById = new Map(extensionPacks.map((ext) => [ext.id, ext]));\n const orderedExtensionPacks = orderedIds\n .map((id) => extensionById.get(id))\n .filter((ext): ext is ControlExtensionDescriptor<TFamilyId, TTargetId> => ext !== undefined);\n\n const allDescriptors = [family, target, ...(adapter ? [adapter] : []), ...orderedExtensionPacks];\n\n const codecLookup = extractCodecLookup(allDescriptors);\n const scalarTypeDescriptors = assembleScalarTypeDescriptors(allDescriptors);\n\n return {\n family,\n target,\n adapter,\n driver,\n extensionPacks: orderedExtensionPacks,\n\n codecTypeImports: extractCodecTypeImports(allDescriptors),\n queryOperationTypeImports: extractQueryOperationTypeImports(allDescriptors),\n extensionIds: extractComponentIds(family, target, adapter, orderedExtensionPacks),\n codecLookup,\n authoringContributions: assembleAuthoringContributions(allDescriptors),\n scalarTypeDescriptors,\n controlMutationDefaults: assembleControlMutationDefaults(allDescriptors),\n };\n}\n","export type SchemaDiffOutcome = 'missing' | 'extra' | 'mismatch';\n\nexport interface SchemaDiffIssue {\n /** Path from the root node down to the diffed node, as a sequence of local keys. */\n readonly path: readonly string[];\n readonly outcome: SchemaDiffOutcome;\n readonly message: string;\n /** The expected (contract-side) node, when available. Absent for `extra` outcomes. */\n readonly expected?: DiffableNode;\n /** The actual (live-DB-side) node, when available. Absent for `missing` outcomes. */\n readonly actual?: DiffableNode;\n}\n\n/**\n * A node in the schema tree. Every node in the tree implements this interface.\n *\n * `id` must be unique among sibling nodes at the same level — the differ keys\n * on it and treats a collision as the same entity (enforced by a duplicate-id\n * throw). The differ accumulates these ids into a path that stamps every emitted\n * issue.\n */\nexport interface DiffableNode {\n readonly id: string;\n isEqualTo(other: DiffableNode): boolean;\n children(): readonly DiffableNode[];\n}\n\nfunction insertNode(map: Map<string, DiffableNode>, node: DiffableNode): void {\n const key = node.id;\n if (map.has(key)) {\n throw new Error(`diffSchemas: duplicate id among siblings: ${key}`);\n }\n map.set(key, node);\n}\n\nfunction outcomeMessage(outcome: SchemaDiffOutcome, path: readonly string[]): string {\n return `${outcome}: ${path.join('/')}`;\n}\n\nfunction emitMissingSubtree(node: DiffableNode, parentPath: readonly string[]): SchemaDiffIssue[] {\n const path = [...parentPath, node.id];\n return [\n { path, outcome: 'missing', message: outcomeMessage('missing', path), expected: node },\n ...node.children().flatMap((c) => emitMissingSubtree(c, path)),\n ];\n}\n\nfunction emitExtraSubtree(node: DiffableNode, parentPath: readonly string[]): SchemaDiffIssue[] {\n const path = [...parentPath, node.id];\n return [\n { path, outcome: 'extra', message: outcomeMessage('extra', path), actual: node },\n ...node.children().flatMap((c) => emitExtraSubtree(c, path)),\n ];\n}\n\n/**\n * Diff two schema trees starting from their roots.\n *\n * The differ is **total**: every node-level difference is reported. An unmatched\n * non-leaf node emits its own issue and descends, emitting an issue for every\n * node in the missing/extra subtree. Coalescing a parent change over its\n * children is the planner's responsibility. Ownership filtering (dropping `extra`\n * issues in namespaces a contract doesn't own) is the caller's responsibility.\n */\nexport function diffSchemas(\n expected: DiffableNode,\n actual: DiffableNode,\n): readonly SchemaDiffIssue[] {\n return diffPair(expected, actual, []);\n}\n\nfunction diffPair(\n expected: DiffableNode,\n actual: DiffableNode,\n parentPath: readonly string[],\n): readonly SchemaDiffIssue[] {\n const path = [...parentPath, expected.id];\n const issues: SchemaDiffIssue[] = [];\n if (!expected.isEqualTo(actual)) {\n issues.push({\n path,\n outcome: 'mismatch',\n message: outcomeMessage('mismatch', path),\n expected,\n actual,\n });\n }\n issues.push(...diffChildren(expected.children(), actual.children(), path));\n return issues;\n}\n\n/**\n * Align one level of nodes by id; emit issues in input order and recurse.\n *\n * A missing node emits one issue for itself and one for every node in its\n * subtree (total descent). Same for extra nodes. A matched pair recurses via\n * `diffPair`.\n */\nfunction diffChildren(\n expected: readonly DiffableNode[],\n actual: readonly DiffableNode[],\n parentPath: readonly string[],\n): readonly SchemaDiffIssue[] {\n const expectedMap = new Map<string, DiffableNode>();\n for (const node of expected) {\n insertNode(expectedMap, node);\n }\n\n const actualMap = new Map<string, DiffableNode>();\n for (const node of actual) {\n insertNode(actualMap, node);\n }\n\n const issues: SchemaDiffIssue[] = [];\n\n for (const [key, expectedNode] of expectedMap) {\n const actualNode = actualMap.get(key);\n if (actualNode === undefined) {\n issues.push(...emitMissingSubtree(expectedNode, parentPath));\n } else {\n issues.push(...diffPair(expectedNode, actualNode, parentPath));\n }\n }\n\n for (const [key, actualNode] of actualMap) {\n if (!expectedMap.has(key)) {\n issues.push(...emitExtraSubtree(actualNode, parentPath));\n }\n }\n\n return issues;\n}\n","import type { ControlPolicy } from '@prisma-next/contract/types';\nimport type { SchemaVerificationNode } from './control-result-types';\n\nexport type VerificationStatus = SchemaVerificationNode['status'];\n\nexport type VerifierOutcome = VerificationStatus | 'suppress';\n\n/**\n * Target-neutral classification of a verifier finding, abstracted away from any\n * one storage model's vocabulary. Each family classifies its own concrete issue\n * kinds into these categories; the framework only grades the category against a\n * control policy.\n *\n * - `declaredMissing` — a declared object/element is absent from the database.\n * - `declaredIncompatible` — a declared object/element exists but its shape diverges.\n * - `valueDrift` — the value set of an existing type drifted (e.g. enum values).\n * - `extraNestedElement` — an undeclared element nested inside a declared object\n * (a SQL column, a document field).\n * - `extraAuxiliary` — an undeclared auxiliary attached to a declared object\n * (a SQL constraint/index, a Mongo index/validator).\n * - `extraTopLevelObject` — an undeclared top-level object (a SQL table, a\n * Mongo collection).\n */\nexport type VerifierIssueCategory =\n | 'declaredMissing'\n | 'declaredIncompatible'\n | 'valueDrift'\n | 'extraNestedElement'\n | 'extraAuxiliary'\n | 'extraTopLevelObject';\n\n/**\n * Grades a target-neutral issue category against a control policy.\n *\n * - `observed` warns on everything.\n * - `tolerated` suppresses only an extra nested element (everything else fails).\n * - `external` suppresses every extra category and value drift (existence and\n * declared-shape divergences still fail).\n * - `managed` (and any other) fails.\n */\nexport function dispositionForCategory(\n controlPolicy: ControlPolicy,\n category: VerifierIssueCategory,\n): VerifierOutcome {\n if (controlPolicy === 'observed') {\n return 'warn';\n }\n if (controlPolicy === 'tolerated' && category === 'extraNestedElement') {\n return 'suppress';\n }\n if (controlPolicy === 'external') {\n if (\n category === 'extraNestedElement' ||\n category === 'extraAuxiliary' ||\n category === 'extraTopLevelObject' ||\n category === 'valueDrift'\n ) {\n return 'suppress';\n }\n }\n return 'fail';\n}\n"],"mappings":"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"}
{"version":3,"file":"control.mjs","names":[],"sources":["../src/control/control-capabilities.ts","../src/control/control-result-types.ts","../src/control/control-schema-view.ts","../src/control/control-spaces.ts","../src/control/control-stack.ts","../src/control/schema-diff.ts","../src/control/verifier-disposition.ts"],"sourcesContent":["import type { ControlTargetDescriptor } from './control-descriptors';\nimport type { ControlFamilyInstance } from './control-instances';\nimport type { MigrationPlanOperation, TargetMigrationsCapability } from './control-migration-types';\nimport type { OperationPreview } from './control-operation-preview';\nimport type { CoreSchemaView } from './control-schema-view';\nimport type { PslDocumentAst } from './psl-ast';\n\nexport interface MigratableTargetDescriptor<\n TFamilyId extends string,\n TTargetId extends string,\n TFamilyInstance extends ControlFamilyInstance<TFamilyId, unknown> = ControlFamilyInstance<\n TFamilyId,\n unknown\n >,\n> extends ControlTargetDescriptor<TFamilyId, TTargetId> {\n readonly migrations: TargetMigrationsCapability<TFamilyId, TTargetId, TFamilyInstance>;\n}\n\nexport function hasMigrations<TFamilyId extends string, TTargetId extends string>(\n target: ControlTargetDescriptor<TFamilyId, TTargetId>,\n): target is MigratableTargetDescriptor<TFamilyId, TTargetId> {\n return 'migrations' in target && !!(target as Record<string, unknown>)['migrations'];\n}\n\nexport interface SchemaViewCapable<TSchemaIR = unknown> {\n toSchemaView(schema: TSchemaIR): CoreSchemaView;\n}\n\nexport function hasSchemaView<TFamilyId extends string, TSchemaIR>(\n instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,\n): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & SchemaViewCapable<TSchemaIR> {\n return (\n 'toSchemaView' in instance &&\n typeof (instance as Record<string, unknown>)['toSchemaView'] === 'function'\n );\n}\n\n/**\n * Capability declaring that a family can infer a PSL contract AST from its\n * opaque introspected schema IR. Consumed by `prisma-next contract infer`.\n */\nexport interface PslContractInferCapable<TSchemaIR = unknown> {\n inferPslContract(schemaIR: TSchemaIR): PslDocumentAst;\n}\n\nexport function hasPslContractInfer<TFamilyId extends string, TSchemaIR>(\n instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,\n): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & PslContractInferCapable<TSchemaIR> {\n return (\n 'inferPslContract' in instance &&\n typeof (instance as Record<string, unknown>)['inferPslContract'] === 'function'\n );\n}\n\n/**\n * Capability declaring that a family can render a textual preview of migration\n * operations for the CLI's \"DDL preview\" output. SQL families emit\n * `language: 'sql'` statements; Mongo families emit `language: 'mongodb-shell'`.\n */\nexport interface OperationPreviewCapable {\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview;\n}\n\nexport function hasOperationPreview<TFamilyId extends string, TSchemaIR>(\n instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,\n): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & OperationPreviewCapable {\n return (\n 'toOperationPreview' in instance &&\n typeof (instance as Record<string, unknown>)['toOperationPreview'] === 'function'\n );\n}\n","import type { SchemaDiffIssue } from './schema-diff';\n\nexport const VERIFY_CODE_MARKER_MISSING = 'PN-RUN-3001';\nexport const VERIFY_CODE_HASH_MISMATCH = 'PN-RUN-3002';\nexport const VERIFY_CODE_TARGET_MISMATCH = 'PN-RUN-3003';\nexport const VERIFY_CODE_SCHEMA_FAILURE = 'PN-RUN-3010';\n\nexport interface OperationContext {\n readonly contractPath?: string;\n readonly configPath?: string;\n readonly meta?: Readonly<Record<string, unknown>>;\n}\n\nexport interface VerifyDatabaseResult {\n readonly ok: boolean;\n readonly code?: string;\n readonly summary: string;\n readonly contract: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n readonly marker?: {\n readonly storageHash?: string;\n readonly profileHash?: string;\n };\n readonly target: {\n readonly expected: string;\n readonly actual?: string;\n };\n readonly missingCodecs?: readonly string[];\n readonly codecCoverageSkipped?: boolean;\n readonly meta?: {\n readonly configPath?: string;\n readonly contractPath: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nexport interface BaseSchemaIssue {\n readonly kind:\n | 'missing_schema'\n | 'missing_table'\n | 'missing_column'\n | 'extra_table'\n | 'extra_column'\n | 'extra_primary_key'\n | 'extra_foreign_key'\n | 'extra_unique_constraint'\n | 'extra_index'\n | 'extra_validator'\n | 'type_mismatch'\n | 'type_missing'\n | 'type_values_mismatch'\n | 'nullability_mismatch'\n | 'primary_key_mismatch'\n | 'foreign_key_mismatch'\n | 'unique_constraint_mismatch'\n | 'index_mismatch'\n | 'default_missing'\n | 'default_mismatch'\n | 'extra_default'\n | 'check_missing'\n | 'check_removed'\n | 'check_mismatch';\n readonly table?: string;\n /**\n * Namespace coordinate of the issue's subject (e.g. the schema a SQL\n * table lives in). Populated by family verifiers that have the\n * coordinate in scope when constructing the issue; absent for issues\n * whose family has no namespace concept (e.g. Mongo collections) or\n * whose subject isn't in any contract namespace (e.g. an extra-table\n * issue raised for a table that exists in the live DB but not in the\n * contract).\n *\n * Downstream planners trust this field as the authoritative subject\n * coordinate and do not re-derive it by name lookup. A finer-grained\n * structural split between framework-shared and family-specific issue\n * fields is tracked under a follow-up ticket.\n */\n readonly namespaceId?: string;\n readonly column?: string;\n readonly indexOrConstraint?: string;\n readonly typeName?: string;\n readonly expected?: string;\n readonly actual?: string;\n readonly message: string;\n}\n\nexport interface EnumValuesChangedIssue {\n readonly kind: 'enum_values_changed';\n /**\n * Namespace coordinate of the enum type that changed values. Populated by\n * family verifiers that have the coordinate in scope when constructing the\n * issue. Downstream planners trust this field as the authoritative subject\n * coordinate and do not re-derive it by name lookup.\n */\n readonly namespaceId: string;\n readonly typeName: string;\n readonly addedValues: readonly string[];\n readonly removedValues: readonly string[];\n readonly message: string;\n}\n\nexport type SchemaIssue = BaseSchemaIssue | EnumValuesChangedIssue;\n\nexport interface SchemaVerificationNode {\n readonly status: 'pass' | 'warn' | 'fail';\n readonly kind: string;\n readonly name: string;\n readonly contractPath: string;\n readonly code: string;\n readonly message: string;\n readonly expected: unknown;\n readonly actual: unknown;\n readonly children: readonly SchemaVerificationNode[];\n}\n\nexport interface VerifyDatabaseSchemaResult {\n readonly ok: boolean;\n readonly code?: string;\n readonly summary: string;\n readonly contract: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n readonly target: {\n readonly expected: string;\n readonly actual?: string;\n };\n readonly schema: {\n readonly issues: readonly SchemaIssue[];\n readonly schemaDiffIssues: readonly SchemaDiffIssue[];\n readonly root: SchemaVerificationNode;\n readonly counts: {\n readonly pass: number;\n readonly warn: number;\n readonly fail: number;\n readonly totalNodes: number;\n };\n };\n readonly meta?: {\n readonly configPath?: string;\n readonly contractPath?: string;\n readonly strict: boolean;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nexport interface EmitContractResult {\n readonly contractJson: string;\n readonly contractDts: string;\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n}\n\nexport interface IntrospectSchemaResult<TSchemaIR> {\n readonly ok: true;\n readonly summary: string;\n readonly target: {\n readonly familyId: string;\n readonly id: string;\n };\n readonly schema: TSchemaIR;\n readonly meta?: {\n readonly configPath?: string;\n readonly dbUrl?: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nexport interface SignDatabaseResult {\n readonly ok: boolean;\n readonly summary: string;\n readonly contract: {\n readonly storageHash: string;\n readonly profileHash?: string;\n };\n readonly target: {\n readonly expected: string;\n readonly actual?: string;\n };\n readonly marker: {\n readonly created: boolean;\n readonly updated: boolean;\n readonly previous?: {\n readonly storageHash?: string;\n readonly profileHash?: string;\n };\n };\n readonly meta?: {\n readonly configPath?: string;\n readonly contractPath: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n","/**\n * Core schema view types for family-agnostic schema visualization.\n *\n * These types provide a minimal, generic, tree-shaped representation of schemas\n * across families, designed for CLI visualization and lightweight tooling.\n *\n * Families can optionally project their family-specific Schema IR into this\n * core view via the `toSchemaView` method on `FamilyInstance`.\n */\n\nexport type SchemaViewNodeKind =\n | 'root'\n | 'namespace'\n | 'collection'\n | 'entity'\n | 'field'\n | 'index'\n | 'dependency';\n\nexport interface SchemaTreeVisitor<R> {\n visit(node: SchemaTreeNode): R;\n}\n\nexport interface SchemaTreeNodeOptions {\n readonly kind: SchemaViewNodeKind;\n readonly id: string;\n readonly label: string;\n readonly meta?: Record<string, unknown>;\n readonly children?: readonly SchemaTreeNode[];\n}\n\nexport class SchemaTreeNode {\n readonly kind: SchemaViewNodeKind;\n readonly id: string;\n readonly label: string;\n readonly meta?: Record<string, unknown>;\n readonly children?: readonly SchemaTreeNode[];\n\n constructor(options: SchemaTreeNodeOptions) {\n this.kind = options.kind;\n this.id = options.id;\n this.label = options.label;\n if (options.meta !== undefined) this.meta = options.meta;\n if (options.children !== undefined) this.children = options.children;\n Object.freeze(this);\n }\n\n accept<R>(visitor: SchemaTreeVisitor<R>): R {\n return visitor.visit(this);\n }\n}\n\n/**\n * Core schema view providing a family-agnostic tree representation of a schema.\n * Used by CLI and cross-family tooling for visualization.\n */\nexport interface CoreSchemaView {\n readonly root: SchemaTreeNode;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { MigrationMetadata, MigrationPlanOperation } from './control-migration-types';\n\n/**\n * Canonical control-plane identifiers for contract spaces.\n *\n * A contract space is the disjoint `(contract.json, migration-graph)` unit\n * the per-space planner / runner / verifier (project: extension contract\n * spaces, TML-2397) operates on. The application owns one well-known\n * space — the value below — and each loaded extension that contributes\n * schema owns a uniquely-named space.\n *\n * Lives in `framework-components/control` so every layer that has to\n * reason about space identity (the migration tooling, the SQL runtime's\n * marker reader, target-side statement builders, target-side adapters)\n * can import a single value rather than duplicating the literal. Raw\n * `'app'` string literals in framework / target / runtime / adapter\n * source code are forbidden and policed by\n * `scripts/lint-app-space-id.mjs` (wired into `pnpm lint:deps`).\n *\n * @see specs/framework-mechanism.spec.md § 3 — Layout convention (γ).\n */\nexport const APP_SPACE_ID = 'app' as const;\n\n/**\n * Head ref for a contract space — the `(hash, invariants)` tuple\n * a runner targets when applying that space's migration graph. Identical\n * in shape to the on-disk `migrations/<space-id>/refs/head.json` the\n * framework writes per loaded extension, and to the app-space\n * `<projectRoot>/refs/head.json`. Family-agnostic: SQL, Mongo, and any\n * future family share the same head-ref shape.\n *\n * @see specs/framework-mechanism.spec.md § 1.\n */\nexport interface ContractSpaceHeadRef {\n readonly hash: string;\n readonly invariants: readonly string[];\n}\n\n/**\n * Canonical structural shape of a migration package — the unit a planner\n * produces and a runner consumes: a directory name, the metadata\n * envelope, and the operation list.\n *\n * In-memory by default. Readers in `@prisma-next/migration-tools`\n * (`readMigrationPackage` / `readMigrationsDir`) return the augmented\n * {@link import('@prisma-next/migration-tools/package').OnDiskMigrationPackage}\n * variant which adds `dirPath`; everything else operates against the\n * canonical shape so the same value flows through pre-emission\n * authoring, on-disk loading, and runner execution without conversion.\n *\n * @see specs/framework-mechanism.spec.md § 1.\n */\nexport interface MigrationPackage {\n readonly dirName: string;\n readonly metadata: MigrationMetadata;\n readonly ops: readonly MigrationPlanOperation[];\n}\n\n/**\n * Canonical structural shape of a contract space — one disjoint\n * `(contractJson, migration-graph)` unit the per-space planner / runner\n * / verifier operates on. The application owns one well-known space\n * ({@link APP_SPACE_ID}); each loaded extension that contributes schema\n * owns a uniquely-named space. Whether a value is the app's space or an\n * extension's space is a control-plane concern; the type carries no\n * such distinction.\n *\n * Generic over the contract so each family pins a typed contract value\n * at consumption time. The SQL family specialises to\n * `ContractSpace<Contract<SqlStorage>>` at the descriptor surface;\n * Mongo's symmetrical `ContractSpace<Contract<MongoStorage>>` will land\n * with that family.\n *\n * @see specs/framework-mechanism.spec.md § 1.\n */\nexport interface ContractSpace<TContract extends Contract = Contract> {\n readonly contractJson: TContract;\n readonly migrations: readonly MigrationPackage[];\n readonly headRef: ContractSpaceHeadRef;\n}\n","import type { JsonValue } from '@prisma-next/contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { Codec } from '../shared/codec';\nimport type { AnyCodecDescriptor } from '../shared/codec-descriptor';\nimport type { CodecLookup, CodecMeta, CodecRef, CodecRegistry } from '../shared/codec-types';\nimport type {\n AuthoringContributions,\n AuthoringEntityTypeNamespace,\n AuthoringFieldNamespace,\n AuthoringPslBlockDescriptorNamespace,\n AuthoringTypeNamespace,\n} from '../shared/framework-authoring';\nimport {\n assertNoCrossRegistryCollisions,\n isAuthoringEntityTypeDescriptor,\n isAuthoringFieldPresetDescriptor,\n isAuthoringPslBlockDescriptor,\n isAuthoringTypeConstructorDescriptor,\n mergeAuthoringNamespaces,\n} from '../shared/framework-authoring';\nimport type { ComponentMetadata } from '../shared/framework-components';\nimport type {\n ControlMutationDefaultEntry,\n ControlMutationDefaults,\n MutationDefaultGeneratorDescriptor,\n} from '../shared/mutation-default-types';\nimport {\n CONTRACT_CODEC_DESCRIPTOR_MISSING,\n materializeCodec,\n resolveCodecDescriptorOrThrow,\n} from '../shared/resolve-codec';\nimport type { TypesImportSpec } from '../shared/types-import-spec';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n ControlTargetDescriptor,\n} from './control-descriptors';\n\nexport interface AssembledAuthoringContributions {\n readonly field: AuthoringFieldNamespace;\n readonly type: AuthoringTypeNamespace;\n readonly entityTypes: AuthoringEntityTypeNamespace;\n readonly pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace;\n}\n\nexport interface ControlStack<\n TFamilyId extends string = string,\n TTargetId extends string = string,\n> {\n readonly family: ControlFamilyDescriptor<TFamilyId>;\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter?: ControlAdapterDescriptor<TFamilyId, TTargetId> | undefined;\n readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;\n readonly extensionPacks: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];\n\n readonly codecTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly queryOperationTypeImports: ReadonlyArray<TypesImportSpec>;\n readonly extensionIds: ReadonlyArray<string>;\n readonly codecLookup: CodecRegistry;\n readonly authoringContributions: AssembledAuthoringContributions;\n readonly scalarTypeDescriptors: ReadonlyMap<string, string>;\n readonly controlMutationDefaults: ControlMutationDefaults;\n}\n\nexport interface CreateControlStackInput<\n TFamilyId extends string = string,\n TTargetId extends string = string,\n> {\n readonly family: ControlFamilyDescriptor<TFamilyId>;\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter?: ControlAdapterDescriptor<TFamilyId, TTargetId> | undefined;\n readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;\n readonly extensionPacks?:\n | ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>\n | undefined;\n}\n\nfunction addUniqueId(ids: string[], seen: Set<string>, id: string): void {\n if (!seen.has(id)) {\n ids.push(id);\n seen.add(id);\n }\n}\n\nexport function assertUniqueCodecOwner(options: {\n readonly codecId: string;\n readonly owners: Map<string, string>;\n readonly descriptorId: string;\n readonly entityLabel: string;\n readonly entityOwnershipLabel: string;\n}): void {\n const existingOwner = options.owners.get(options.codecId);\n if (existingOwner !== undefined) {\n throw new Error(\n `Duplicate ${options.entityLabel} for codecId \"${options.codecId}\". ` +\n `Descriptor \"${options.descriptorId}\" conflicts with \"${existingOwner}\". ` +\n `Each codecId can only have one ${options.entityOwnershipLabel}.`,\n );\n }\n}\n\nexport function extractCodecTypeImports(\n descriptors: ReadonlyArray<Pick<ComponentMetadata, 'types'>>,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const codecTypes = descriptor.types?.codecTypes;\n if (codecTypes?.import) {\n imports.push(codecTypes.import);\n }\n if (codecTypes?.typeImports) {\n imports.push(...codecTypes.typeImports);\n }\n }\n\n return imports;\n}\n\nexport function extractQueryOperationTypeImports(\n descriptors: ReadonlyArray<Pick<ComponentMetadata, 'types'>>,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const queryOperationTypes = descriptor.types?.queryOperationTypes;\n if (queryOperationTypes?.import) {\n imports.push(queryOperationTypes.import);\n }\n }\n\n return imports;\n}\n\nexport function extractComponentIds(\n family: { readonly id: string },\n target: { readonly id: string },\n adapter: { readonly id: string } | undefined,\n extensions: ReadonlyArray<{ readonly id: string }>,\n): ReadonlyArray<string> {\n const ids: string[] = [];\n const seen = new Set<string>();\n\n addUniqueId(ids, seen, family.id);\n addUniqueId(ids, seen, target.id);\n if (adapter) {\n addUniqueId(ids, seen, adapter.id);\n }\n\n for (const ext of extensions) {\n addUniqueId(ids, seen, ext.id);\n }\n\n return ids;\n}\n\nexport function assembleAuthoringContributions(\n descriptors: ReadonlyArray<{ readonly authoring?: AuthoringContributions }>,\n): AssembledAuthoringContributions {\n const field = {} as Record<string, unknown>;\n const type = {} as Record<string, unknown>;\n const entityTypes = {} as Record<string, unknown>;\n const pslBlockDescriptors: Record<string, unknown> = {};\n\n for (const descriptor of descriptors) {\n if (descriptor.authoring?.field) {\n mergeAuthoringNamespaces(\n field,\n descriptor.authoring.field,\n [],\n isAuthoringFieldPresetDescriptor,\n 'field',\n );\n }\n if (descriptor.authoring?.type) {\n mergeAuthoringNamespaces(\n type,\n descriptor.authoring.type,\n [],\n isAuthoringTypeConstructorDescriptor,\n 'type',\n );\n }\n if (descriptor.authoring?.entityTypes) {\n mergeAuthoringNamespaces(\n entityTypes,\n descriptor.authoring.entityTypes,\n [],\n isAuthoringEntityTypeDescriptor,\n 'entity',\n );\n }\n if (descriptor.authoring?.pslBlockDescriptors) {\n mergeAuthoringNamespaces(\n pslBlockDescriptors,\n descriptor.authoring.pslBlockDescriptors,\n [],\n isAuthoringPslBlockDescriptor,\n 'pslBlock',\n );\n }\n }\n\n const fieldNamespace = field as AuthoringFieldNamespace;\n const typeNamespace = type as AuthoringTypeNamespace;\n const entityTypeNamespace = entityTypes as AuthoringEntityTypeNamespace;\n const pslBlockDescriptorNamespace = blindCast<\n AuthoringPslBlockDescriptorNamespace,\n 'merge target accumulator narrows to typed namespace post-merge'\n >(pslBlockDescriptors);\n assertNoCrossRegistryCollisions(\n typeNamespace,\n fieldNamespace,\n entityTypeNamespace,\n pslBlockDescriptorNamespace,\n );\n\n return {\n field: fieldNamespace,\n type: typeNamespace,\n entityTypes: entityTypeNamespace,\n pslBlockDescriptors: pslBlockDescriptorNamespace,\n };\n}\n\nexport function assembleScalarTypeDescriptors(\n descriptors: ReadonlyArray<\n Pick<ComponentMetadata, 'scalarTypeDescriptors'> & { readonly id?: string }\n >,\n): ReadonlyMap<string, string> {\n const result = new Map<string, string>();\n const owners = new Map<string, string>();\n\n for (const descriptor of descriptors) {\n const descriptorMap = descriptor.scalarTypeDescriptors;\n if (!descriptorMap) continue;\n const descriptorId = descriptor.id ?? '<unknown>';\n for (const [typeName, codecId] of descriptorMap) {\n const existingOwner = owners.get(typeName);\n if (existingOwner !== undefined) {\n throw new Error(\n `Duplicate scalar type descriptor \"${typeName}\". ` +\n `Descriptor \"${descriptorId}\" conflicts with \"${existingOwner}\".`,\n );\n }\n result.set(typeName, codecId);\n owners.set(typeName, descriptorId);\n }\n }\n\n return result;\n}\n\nexport function assembleControlMutationDefaults(\n descriptors: ReadonlyArray<\n Pick<ComponentMetadata, 'controlMutationDefaults'> & { readonly id?: string }\n >,\n): ControlMutationDefaults {\n const defaultFunctionRegistry = new Map<string, ControlMutationDefaultEntry>();\n const functionOwners = new Map<string, string>();\n const generatorMap = new Map<string, MutationDefaultGeneratorDescriptor>();\n const generatorOwners = new Map<string, string>();\n\n for (const descriptor of descriptors) {\n const contributions = descriptor.controlMutationDefaults;\n if (!contributions) continue;\n const descriptorId = descriptor.id ?? '<unknown>';\n\n for (const generatorDescriptor of contributions.generatorDescriptors) {\n const existingOwner = generatorOwners.get(generatorDescriptor.id);\n if (existingOwner !== undefined) {\n throw new Error(\n `Duplicate mutation default generator id \"${generatorDescriptor.id}\". ` +\n `Descriptor \"${descriptorId}\" conflicts with \"${existingOwner}\".`,\n );\n }\n generatorMap.set(generatorDescriptor.id, generatorDescriptor);\n generatorOwners.set(generatorDescriptor.id, descriptorId);\n }\n\n for (const [functionName, handler] of contributions.defaultFunctionRegistry) {\n const existingOwner = functionOwners.get(functionName);\n if (existingOwner !== undefined) {\n throw new Error(\n `Duplicate mutation default function \"${functionName}\". ` +\n `Descriptor \"${descriptorId}\" conflicts with \"${existingOwner}\".`,\n );\n }\n defaultFunctionRegistry.set(functionName, handler);\n functionOwners.set(functionName, descriptorId);\n }\n }\n\n return {\n defaultFunctionRegistry,\n generatorDescriptors: Array.from(generatorMap.values()),\n };\n}\n\nexport function extractCodecLookup(\n descriptors: ReadonlyArray<Pick<ComponentMetadata & { id: string }, 'types' | 'id'>>,\n): CodecRegistry {\n const byId = new Map<string, Codec>();\n const descriptorsById = new Map<string, AnyCodecDescriptor>();\n const targetTypesById = new Map<string, readonly string[]>();\n const metaById = new Map<string, CodecMeta>();\n const renderersById = new Map<string, (params: Record<string, unknown>) => string | undefined>();\n const inputRenderersById = new Map<\n string,\n (params: Record<string, unknown>) => string | undefined\n >();\n const valueLiteralRenderersById = new Map<\n string,\n (value: JsonValue, side: 'output' | 'input') => string | undefined\n >();\n const owners = new Map<string, string>();\n for (const descriptor of descriptors) {\n const codecTypes = descriptor.types?.codecTypes;\n const descriptorId = descriptor.id;\n // Descriptor-side metadata is the single source of truth for `targetTypes` / `meta` / `renderOutputType`. A component contributes its codecs by listing `codecDescriptors` on `types.codecTypes`; each codecId has exactly one contributor across the stack.\n for (const codecDescriptor of codecTypes?.codecDescriptors ?? []) {\n assertUniqueCodecOwner({\n codecId: codecDescriptor.codecId,\n owners,\n descriptorId,\n entityLabel: 'codec descriptor',\n entityOwnershipLabel: 'codec descriptor provider',\n });\n owners.set(codecDescriptor.codecId, descriptorId);\n descriptorsById.set(codecDescriptor.codecId, codecDescriptor);\n if (Array.isArray(codecDescriptor.targetTypes)) {\n targetTypesById.set(codecDescriptor.codecId, codecDescriptor.targetTypes);\n }\n if (codecDescriptor.meta !== undefined) {\n metaById.set(codecDescriptor.codecId, codecDescriptor.meta);\n }\n if (typeof codecDescriptor.renderOutputType === 'function') {\n renderersById.set(codecDescriptor.codecId, codecDescriptor.renderOutputType);\n }\n if (typeof codecDescriptor.renderInputType === 'function') {\n inputRenderersById.set(codecDescriptor.codecId, codecDescriptor.renderInputType);\n }\n if (typeof codecDescriptor.renderValueLiteral === 'function') {\n valueLiteralRenderersById.set(codecDescriptor.codecId, codecDescriptor.renderValueLiteral);\n }\n // Materialize a representative `Codec` instance for `byId.get()` so consumers reading the lookup's instance side (e.g. SQL renderer's cast-policy lookup, or the contract emitter's literal-default `encodeJson` resolver) keep finding the codec.\n //\n // Two cohorts:\n // - Non-parameterized descriptors: factory must succeed; any throw is a real bug and we let it propagate (no silent try/catch).\n // - Parameterized descriptors: try with empty params. Many parameterized codecs treat params as advisory (e.g. `pg/timestamptz@1` whose precision is rendered into the `nativeType` only and never read by the runtime codec), so an empty-params construction yields a usable representative for id-keyed lookups (e.g. emit-time literal-default encoding). Codecs whose factory genuinely requires params (e.g. `pg/vector@1` threading `length` into the runtime codec) will throw; for those, per-column instances are materialized at runtime by `buildContractCodecRegistry` and the id-keyed lookup miss is correct (the column-aware path resolves them).\n if (!byId.has(codecDescriptor.codecId)) {\n if (codecDescriptor.isParameterized) {\n try {\n const representative = codecDescriptor.factory({} as never)({\n name: `<lookup:${codecDescriptor.codecId}>`,\n } as Parameters<ReturnType<typeof codecDescriptor.factory>>[0]);\n byId.set(codecDescriptor.codecId, representative);\n } catch {\n // Factory requires concrete params; skip representative materialization. Per-column instances are built at runtime; id-keyed lookup miss is the correct outcome here.\n }\n } else {\n const representative = codecDescriptor.factory(undefined as never)({\n name: `<lookup:${codecDescriptor.codecId}>`,\n } as Parameters<ReturnType<typeof codecDescriptor.factory>>[0]);\n byId.set(codecDescriptor.codecId, representative);\n }\n }\n }\n }\n return {\n get: (id) => byId.get(id),\n forCodecRef(ref: CodecRef) {\n const d = resolveCodecDescriptorOrThrow(\n (id) => descriptorsById.get(id),\n ref,\n CONTRACT_CODEC_DESCRIPTOR_MISSING,\n );\n return materializeCodec(d, ref, { name: `<ref:${ref.codecId}>` });\n },\n forColumn: () => undefined,\n targetTypesFor: (id) => targetTypesById.get(id),\n metaFor: (id) => metaById.get(id),\n renderOutputTypeFor: (id, params) => renderersById.get(id)?.(params),\n renderInputTypeFor: (id, params) => inputRenderersById.get(id)?.(params),\n renderValueLiteralFor: (id, value, side) => valueLiteralRenderersById.get(id)?.(value, side),\n };\n}\n\nexport function validateScalarTypeCodecIds(\n scalarTypeDescriptors: ReadonlyMap<string, string>,\n codecLookup: CodecLookup,\n): string[] {\n const errors: string[] = [];\n for (const [typeName, codecId] of scalarTypeDescriptors) {\n if (!codecLookup.get(codecId)) {\n errors.push(\n `Scalar type \"${typeName}\" references codec \"${codecId}\" which is not registered by any component.`,\n );\n }\n }\n return errors;\n}\n\ninterface DependencyDeclaringDescriptor {\n readonly id: string;\n readonly contractSpace?: {\n readonly contractJson?: {\n readonly extensionPacks?: Readonly<Record<string, unknown>>;\n };\n };\n}\n\nfunction readDeclaredDependencyIds(descriptor: DependencyDeclaringDescriptor): readonly string[] {\n const packs = descriptor.contractSpace?.contractJson?.extensionPacks;\n if (packs === null || typeof packs !== 'object') return [];\n return Object.keys(packs);\n}\n\n/**\n * Builds a dependency-respecting load order for the given extension descriptors\n * using Kahn's topological sort algorithm. Dependencies (packs declared in\n * `contractSpace.contractJson.extensionPacks`) are placed before the extensions\n * that depend on them.\n *\n * Throws if the dependency graph contains a cycle, with an error message that\n * names every extension involved in the cycle.\n *\n * Throws if any extension declares a dependency on a pack ID that is not present\n * in the provided list — add the missing pack to the `extensionPacks` list to\n * resolve the error.\n */\n\nexport function buildExtensionLoadOrder(\n extensions: ReadonlyArray<DependencyDeclaringDescriptor>,\n): readonly string[] {\n if (extensions.length === 0) return [];\n\n const idSet = new Set(extensions.map((e) => e.id));\n const inDegree = new Map<string, number>();\n const dependents = new Map<string, string[]>();\n\n for (const ext of extensions) {\n if (!inDegree.has(ext.id)) inDegree.set(ext.id, 0);\n if (!dependents.has(ext.id)) dependents.set(ext.id, []);\n }\n\n for (const ext of extensions) {\n for (const depId of readDeclaredDependencyIds(ext)) {\n if (!idSet.has(depId)) {\n throw new Error(\n `Extension \"${ext.id}\" declares a dependency on \"${depId}\", but \"${depId}\" is not in the provided extension set. Add the missing space to extensionPacks.`,\n );\n }\n inDegree.set(ext.id, (inDegree.get(ext.id) ?? 0) + 1);\n const list = dependents.get(depId);\n if (list !== undefined) list.push(ext.id);\n }\n }\n\n const queue: string[] = [];\n for (const [id, deg] of inDegree) {\n if (deg === 0) queue.push(id);\n }\n queue.sort();\n\n const result: string[] = [];\n while (queue.length > 0) {\n const id = queue.shift();\n if (id === undefined) break;\n result.push(id);\n const children = dependents.get(id) ?? [];\n children.sort();\n for (const childId of children) {\n const newDeg = (inDegree.get(childId) ?? 1) - 1;\n inDegree.set(childId, newDeg);\n if (newDeg === 0) queue.push(childId);\n }\n }\n\n if (result.length < extensions.length) {\n const cycleMembers = extensions\n .map((e) => e.id)\n .filter((id) => !result.includes(id))\n .sort();\n throw new Error(\n `Extension dependency cycle detected. Cycle members: ${cycleMembers.map((id) => `\"${id}\"`).join(', ')}.`,\n );\n }\n\n return result;\n}\n\nexport function createControlStack<TFamilyId extends string, TTargetId extends string>(\n input: CreateControlStackInput<TFamilyId, TTargetId>,\n): ControlStack<TFamilyId, TTargetId> {\n const { family, target, adapter, driver, extensionPacks = [] } = input;\n\n const orderedIds = buildExtensionLoadOrder(extensionPacks);\n const extensionById = new Map(extensionPacks.map((ext) => [ext.id, ext]));\n const orderedExtensionPacks = orderedIds\n .map((id) => extensionById.get(id))\n .filter((ext): ext is ControlExtensionDescriptor<TFamilyId, TTargetId> => ext !== undefined);\n\n const allDescriptors = [family, target, ...(adapter ? [adapter] : []), ...orderedExtensionPacks];\n\n const codecLookup = extractCodecLookup(allDescriptors);\n const scalarTypeDescriptors = assembleScalarTypeDescriptors(allDescriptors);\n\n return {\n family,\n target,\n adapter,\n driver,\n extensionPacks: orderedExtensionPacks,\n\n codecTypeImports: extractCodecTypeImports(allDescriptors),\n queryOperationTypeImports: extractQueryOperationTypeImports(allDescriptors),\n extensionIds: extractComponentIds(family, target, adapter, orderedExtensionPacks),\n codecLookup,\n authoringContributions: assembleAuthoringContributions(allDescriptors),\n scalarTypeDescriptors,\n controlMutationDefaults: assembleControlMutationDefaults(allDescriptors),\n };\n}\n","export type SchemaDiffOutcome = 'missing' | 'extra' | 'mismatch';\n\nexport interface SchemaDiffIssue {\n /** Path from the root node down to the diffed node, as a sequence of local keys. */\n readonly path: readonly string[];\n readonly outcome: SchemaDiffOutcome;\n readonly message: string;\n /** The expected (contract-side) node, when available. Absent for `extra` outcomes. */\n readonly expected?: DiffableNode;\n /** The actual (live-DB-side) node, when available. Absent for `missing` outcomes. */\n readonly actual?: DiffableNode;\n}\n\n/**\n * A node in the schema tree. Every node in the tree implements this interface.\n *\n * `id` must be unique among sibling nodes at the same level — the differ keys\n * on it and treats a collision as the same entity (enforced by a duplicate-id\n * throw). The differ accumulates these ids into a path that stamps every emitted\n * issue.\n */\nexport interface DiffableNode {\n readonly id: string;\n isEqualTo(other: DiffableNode): boolean;\n children(): readonly DiffableNode[];\n}\n\nfunction insertNode(map: Map<string, DiffableNode>, node: DiffableNode): void {\n const key = node.id;\n if (map.has(key)) {\n throw new Error(`diffSchemas: duplicate id among siblings: ${key}`);\n }\n map.set(key, node);\n}\n\nfunction outcomeMessage(outcome: SchemaDiffOutcome, path: readonly string[]): string {\n return `${outcome}: ${path.join('/')}`;\n}\n\nfunction emitMissingSubtree(node: DiffableNode, parentPath: readonly string[]): SchemaDiffIssue[] {\n const path = [...parentPath, node.id];\n return [\n { path, outcome: 'missing', message: outcomeMessage('missing', path), expected: node },\n ...node.children().flatMap((c) => emitMissingSubtree(c, path)),\n ];\n}\n\nfunction emitExtraSubtree(node: DiffableNode, parentPath: readonly string[]): SchemaDiffIssue[] {\n const path = [...parentPath, node.id];\n return [\n { path, outcome: 'extra', message: outcomeMessage('extra', path), actual: node },\n ...node.children().flatMap((c) => emitExtraSubtree(c, path)),\n ];\n}\n\n/**\n * Diff two schema trees starting from their roots.\n *\n * The differ is **total**: every node-level difference is reported. An unmatched\n * non-leaf node emits its own issue and descends, emitting an issue for every\n * node in the missing/extra subtree. Coalescing a parent change over its\n * children is the planner's responsibility. Ownership filtering (dropping `extra`\n * issues in namespaces a contract doesn't own) is the caller's responsibility.\n */\nexport function diffSchemas(\n expected: DiffableNode,\n actual: DiffableNode,\n): readonly SchemaDiffIssue[] {\n return diffPair(expected, actual, []);\n}\n\nfunction diffPair(\n expected: DiffableNode,\n actual: DiffableNode,\n parentPath: readonly string[],\n): readonly SchemaDiffIssue[] {\n const path = [...parentPath, expected.id];\n const issues: SchemaDiffIssue[] = [];\n if (!expected.isEqualTo(actual)) {\n issues.push({\n path,\n outcome: 'mismatch',\n message: outcomeMessage('mismatch', path),\n expected,\n actual,\n });\n }\n issues.push(...diffChildren(expected.children(), actual.children(), path));\n return issues;\n}\n\n/**\n * Align one level of nodes by id; emit issues in input order and recurse.\n *\n * A missing node emits one issue for itself and one for every node in its\n * subtree (total descent). Same for extra nodes. A matched pair recurses via\n * `diffPair`.\n */\nfunction diffChildren(\n expected: readonly DiffableNode[],\n actual: readonly DiffableNode[],\n parentPath: readonly string[],\n): readonly SchemaDiffIssue[] {\n const expectedMap = new Map<string, DiffableNode>();\n for (const node of expected) {\n insertNode(expectedMap, node);\n }\n\n const actualMap = new Map<string, DiffableNode>();\n for (const node of actual) {\n insertNode(actualMap, node);\n }\n\n const issues: SchemaDiffIssue[] = [];\n\n for (const [key, expectedNode] of expectedMap) {\n const actualNode = actualMap.get(key);\n if (actualNode === undefined) {\n issues.push(...emitMissingSubtree(expectedNode, parentPath));\n } else {\n issues.push(...diffPair(expectedNode, actualNode, parentPath));\n }\n }\n\n for (const [key, actualNode] of actualMap) {\n if (!expectedMap.has(key)) {\n issues.push(...emitExtraSubtree(actualNode, parentPath));\n }\n }\n\n return issues;\n}\n","import type { ControlPolicy } from '@prisma-next/contract/types';\nimport type { SchemaVerificationNode } from './control-result-types';\n\nexport type VerificationStatus = SchemaVerificationNode['status'];\n\nexport type VerifierOutcome = VerificationStatus | 'suppress';\n\n/**\n * Target-neutral classification of a verifier finding, abstracted away from any\n * one storage model's vocabulary. Each family classifies its own concrete issue\n * kinds into these categories; the framework only grades the category against a\n * control policy.\n *\n * - `declaredMissing` — a declared object/element is absent from the database.\n * - `declaredIncompatible` — a declared object/element exists but its shape diverges.\n * - `valueDrift` — the value set of an existing type drifted (e.g. enum values).\n * - `extraNestedElement` — an undeclared element nested inside a declared object\n * (a SQL column, a document field).\n * - `extraAuxiliary` — an undeclared auxiliary attached to a declared object\n * (a SQL constraint/index, a Mongo index/validator).\n * - `extraTopLevelObject` — an undeclared top-level object (a SQL table, a\n * Mongo collection).\n */\nexport type VerifierIssueCategory =\n | 'declaredMissing'\n | 'declaredIncompatible'\n | 'valueDrift'\n | 'extraNestedElement'\n | 'extraAuxiliary'\n | 'extraTopLevelObject';\n\n/**\n * Grades a target-neutral issue category against a control policy.\n *\n * - `observed` warns on everything.\n * - `tolerated` suppresses only an extra nested element (everything else fails).\n * - `external` suppresses every extra category and value drift (existence and\n * declared-shape divergences still fail).\n * - `managed` (and any other) fails.\n */\nexport function dispositionForCategory(\n controlPolicy: ControlPolicy,\n category: VerifierIssueCategory,\n): VerifierOutcome {\n if (controlPolicy === 'observed') {\n return 'warn';\n }\n if (controlPolicy === 'tolerated' && category === 'extraNestedElement') {\n return 'suppress';\n }\n if (controlPolicy === 'external') {\n if (\n category === 'extraNestedElement' ||\n category === 'extraAuxiliary' ||\n category === 'extraTopLevelObject' ||\n category === 'valueDrift'\n ) {\n return 'suppress';\n }\n }\n return 'fail';\n}\n"],"mappings":";;;;AAkBA,SAAgB,cACd,QAC4D;CAC5D,OAAO,gBAAgB,UAAU,CAAC,CAAE,OAAmC;AACzE;AAMA,SAAgB,cACd,UACwF;CACxF,OACE,kBAAkB,YAClB,OAAQ,SAAqC,oBAAoB;AAErE;AAUA,SAAgB,oBACd,UAC8F;CAC9F,OACE,sBAAsB,YACtB,OAAQ,SAAqC,wBAAwB;AAEzE;AAWA,SAAgB,oBACd,UACmF;CACnF,OACE,wBAAwB,YACxB,OAAQ,SAAqC,0BAA0B;AAE3E;;;ACpEA,MAAa,6BAA6B;AAC1C,MAAa,4BAA4B;AACzC,MAAa,8BAA8B;AAC3C,MAAa,6BAA6B;;;AC0B1C,IAAa,iBAAb,MAA4B;CAC1B;CACA;CACA;CACA;CACA;CAEA,YAAY,SAAgC;EAC1C,KAAK,OAAO,QAAQ;EACpB,KAAK,KAAK,QAAQ;EAClB,KAAK,QAAQ,QAAQ;EACrB,IAAI,QAAQ,SAAS,KAAA,GAAW,KAAK,OAAO,QAAQ;EACpD,IAAI,QAAQ,aAAa,KAAA,GAAW,KAAK,WAAW,QAAQ;EAC5D,OAAO,OAAO,IAAI;CACpB;CAEA,OAAU,SAAkC;EAC1C,OAAO,QAAQ,MAAM,IAAI;CAC3B;AACF;;;;;;;;;;;;;;;;;;;;;;AC5BA,MAAa,eAAe;;;ACyD5B,SAAS,YAAY,KAAe,MAAmB,IAAkB;CACvE,IAAI,CAAC,KAAK,IAAI,EAAE,GAAG;EACjB,IAAI,KAAK,EAAE;EACX,KAAK,IAAI,EAAE;CACb;AACF;AAEA,SAAgB,uBAAuB,SAM9B;CACP,MAAM,gBAAgB,QAAQ,OAAO,IAAI,QAAQ,OAAO;CACxD,IAAI,kBAAkB,KAAA,GACpB,MAAM,IAAI,MACR,aAAa,QAAQ,YAAY,gBAAgB,QAAQ,QAAQ,iBAChD,QAAQ,aAAa,oBAAoB,cAAc,oCACpC,QAAQ,qBAAqB,EACnE;AAEJ;AAEA,SAAgB,wBACd,aACgC;CAChC,MAAM,UAA6B,CAAC;CAEpC,KAAK,MAAM,cAAc,aAAa;EACpC,MAAM,aAAa,WAAW,OAAO;EACrC,IAAI,YAAY,QACd,QAAQ,KAAK,WAAW,MAAM;EAEhC,IAAI,YAAY,aACd,QAAQ,KAAK,GAAG,WAAW,WAAW;CAE1C;CAEA,OAAO;AACT;AAEA,SAAgB,iCACd,aACgC;CAChC,MAAM,UAA6B,CAAC;CAEpC,KAAK,MAAM,cAAc,aAAa;EACpC,MAAM,sBAAsB,WAAW,OAAO;EAC9C,IAAI,qBAAqB,QACvB,QAAQ,KAAK,oBAAoB,MAAM;CAE3C;CAEA,OAAO;AACT;AAEA,SAAgB,oBACd,QACA,QACA,SACA,YACuB;CACvB,MAAM,MAAgB,CAAC;CACvB,MAAM,uBAAO,IAAI,IAAY;CAE7B,YAAY,KAAK,MAAM,OAAO,EAAE;CAChC,YAAY,KAAK,MAAM,OAAO,EAAE;CAChC,IAAI,SACF,YAAY,KAAK,MAAM,QAAQ,EAAE;CAGnC,KAAK,MAAM,OAAO,YAChB,YAAY,KAAK,MAAM,IAAI,EAAE;CAG/B,OAAO;AACT;AAEA,SAAgB,+BACd,aACiC;CACjC,MAAM,QAAQ,CAAC;CACf,MAAM,OAAO,CAAC;CACd,MAAM,cAAc,CAAC;CACrB,MAAM,sBAA+C,CAAC;CAEtD,KAAK,MAAM,cAAc,aAAa;EACpC,IAAI,WAAW,WAAW,OACxB,yBACE,OACA,WAAW,UAAU,OACrB,CAAC,GACD,kCACA,OACF;EAEF,IAAI,WAAW,WAAW,MACxB,yBACE,MACA,WAAW,UAAU,MACrB,CAAC,GACD,sCACA,MACF;EAEF,IAAI,WAAW,WAAW,aACxB,yBACE,aACA,WAAW,UAAU,aACrB,CAAC,GACD,iCACA,QACF;EAEF,IAAI,WAAW,WAAW,qBACxB,yBACE,qBACA,WAAW,UAAU,qBACrB,CAAC,GACD,+BACA,UACF;CAEJ;CAEA,MAAM,iBAAiB;CACvB,MAAM,gBAAgB;CACtB,MAAM,sBAAsB;CAC5B,MAAM,8BAA8B,UAGlC,mBAAmB;CACrB,gCACE,eACA,gBACA,qBACA,2BACF;CAEA,OAAO;EACL,OAAO;EACP,MAAM;EACN,aAAa;EACb,qBAAqB;CACvB;AACF;AAEA,SAAgB,8BACd,aAG6B;CAC7B,MAAM,yBAAS,IAAI,IAAoB;CACvC,MAAM,yBAAS,IAAI,IAAoB;CAEvC,KAAK,MAAM,cAAc,aAAa;EACpC,MAAM,gBAAgB,WAAW;EACjC,IAAI,CAAC,eAAe;EACpB,MAAM,eAAe,WAAW,MAAM;EACtC,KAAK,MAAM,CAAC,UAAU,YAAY,eAAe;GAC/C,MAAM,gBAAgB,OAAO,IAAI,QAAQ;GACzC,IAAI,kBAAkB,KAAA,GACpB,MAAM,IAAI,MACR,qCAAqC,SAAS,iBAC7B,aAAa,oBAAoB,cAAc,GAClE;GAEF,OAAO,IAAI,UAAU,OAAO;GAC5B,OAAO,IAAI,UAAU,YAAY;EACnC;CACF;CAEA,OAAO;AACT;AAEA,SAAgB,gCACd,aAGyB;CACzB,MAAM,0CAA0B,IAAI,IAAyC;CAC7E,MAAM,iCAAiB,IAAI,IAAoB;CAC/C,MAAM,+BAAe,IAAI,IAAgD;CACzE,MAAM,kCAAkB,IAAI,IAAoB;CAEhD,KAAK,MAAM,cAAc,aAAa;EACpC,MAAM,gBAAgB,WAAW;EACjC,IAAI,CAAC,eAAe;EACpB,MAAM,eAAe,WAAW,MAAM;EAEtC,KAAK,MAAM,uBAAuB,cAAc,sBAAsB;GACpE,MAAM,gBAAgB,gBAAgB,IAAI,oBAAoB,EAAE;GAChE,IAAI,kBAAkB,KAAA,GACpB,MAAM,IAAI,MACR,4CAA4C,oBAAoB,GAAG,iBAClD,aAAa,oBAAoB,cAAc,GAClE;GAEF,aAAa,IAAI,oBAAoB,IAAI,mBAAmB;GAC5D,gBAAgB,IAAI,oBAAoB,IAAI,YAAY;EAC1D;EAEA,KAAK,MAAM,CAAC,cAAc,YAAY,cAAc,yBAAyB;GAC3E,MAAM,gBAAgB,eAAe,IAAI,YAAY;GACrD,IAAI,kBAAkB,KAAA,GACpB,MAAM,IAAI,MACR,wCAAwC,aAAa,iBACpC,aAAa,oBAAoB,cAAc,GAClE;GAEF,wBAAwB,IAAI,cAAc,OAAO;GACjD,eAAe,IAAI,cAAc,YAAY;EAC/C;CACF;CAEA,OAAO;EACL;EACA,sBAAsB,MAAM,KAAK,aAAa,OAAO,CAAC;CACxD;AACF;AAEA,SAAgB,mBACd,aACe;CACf,MAAM,uBAAO,IAAI,IAAmB;CACpC,MAAM,kCAAkB,IAAI,IAAgC;CAC5D,MAAM,kCAAkB,IAAI,IAA+B;CAC3D,MAAM,2BAAW,IAAI,IAAuB;CAC5C,MAAM,gCAAgB,IAAI,IAAqE;CAC/F,MAAM,qCAAqB,IAAI,IAG7B;CACF,MAAM,4CAA4B,IAAI,IAGpC;CACF,MAAM,yBAAS,IAAI,IAAoB;CACvC,KAAK,MAAM,cAAc,aAAa;EACpC,MAAM,aAAa,WAAW,OAAO;EACrC,MAAM,eAAe,WAAW;EAEhC,KAAK,MAAM,mBAAmB,YAAY,oBAAoB,CAAC,GAAG;GAChE,uBAAuB;IACrB,SAAS,gBAAgB;IACzB;IACA;IACA,aAAa;IACb,sBAAsB;GACxB,CAAC;GACD,OAAO,IAAI,gBAAgB,SAAS,YAAY;GAChD,gBAAgB,IAAI,gBAAgB,SAAS,eAAe;GAC5D,IAAI,MAAM,QAAQ,gBAAgB,WAAW,GAC3C,gBAAgB,IAAI,gBAAgB,SAAS,gBAAgB,WAAW;GAE1E,IAAI,gBAAgB,SAAS,KAAA,GAC3B,SAAS,IAAI,gBAAgB,SAAS,gBAAgB,IAAI;GAE5D,IAAI,OAAO,gBAAgB,qBAAqB,YAC9C,cAAc,IAAI,gBAAgB,SAAS,gBAAgB,gBAAgB;GAE7E,IAAI,OAAO,gBAAgB,oBAAoB,YAC7C,mBAAmB,IAAI,gBAAgB,SAAS,gBAAgB,eAAe;GAEjF,IAAI,OAAO,gBAAgB,uBAAuB,YAChD,0BAA0B,IAAI,gBAAgB,SAAS,gBAAgB,kBAAkB;GAO3F,IAAI,CAAC,KAAK,IAAI,gBAAgB,OAAO,GACnC,IAAI,gBAAgB,iBAClB,IAAI;IACF,MAAM,iBAAiB,gBAAgB,QAAQ,CAAC,CAAU,CAAC,CAAC,EAC1D,MAAM,WAAW,gBAAgB,QAAQ,GAC3C,CAA8D;IAC9D,KAAK,IAAI,gBAAgB,SAAS,cAAc;GAClD,QAAQ,CAER;QACK;IACL,MAAM,iBAAiB,gBAAgB,QAAQ,KAAA,CAAkB,CAAC,CAAC,EACjE,MAAM,WAAW,gBAAgB,QAAQ,GAC3C,CAA8D;IAC9D,KAAK,IAAI,gBAAgB,SAAS,cAAc;GAClD;EAEJ;CACF;CACA,OAAO;EACL,MAAM,OAAO,KAAK,IAAI,EAAE;EACxB,YAAY,KAAe;GAMzB,OAAO,iBALG,+BACP,OAAO,gBAAgB,IAAI,EAAE,GAC9B,KACA,iCAEsB,GAAG,KAAK,EAAE,MAAM,QAAQ,IAAI,QAAQ,GAAG,CAAC;EAClE;EACA,iBAAiB,KAAA;EACjB,iBAAiB,OAAO,gBAAgB,IAAI,EAAE;EAC9C,UAAU,OAAO,SAAS,IAAI,EAAE;EAChC,sBAAsB,IAAI,WAAW,cAAc,IAAI,EAAE,CAAC,GAAG,MAAM;EACnE,qBAAqB,IAAI,WAAW,mBAAmB,IAAI,EAAE,CAAC,GAAG,MAAM;EACvE,wBAAwB,IAAI,OAAO,SAAS,0BAA0B,IAAI,EAAE,CAAC,GAAG,OAAO,IAAI;CAC7F;AACF;AA0BA,SAAS,0BAA0B,YAA8D;CAC/F,MAAM,QAAQ,WAAW,eAAe,cAAc;CACtD,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO,CAAC;CACzD,OAAO,OAAO,KAAK,KAAK;AAC1B;;;;;;;;;;;;;;AAgBA,SAAgB,wBACd,YACmB;CACnB,IAAI,WAAW,WAAW,GAAG,OAAO,CAAC;CAErC,MAAM,QAAQ,IAAI,IAAI,WAAW,KAAK,MAAM,EAAE,EAAE,CAAC;CACjD,MAAM,2BAAW,IAAI,IAAoB;CACzC,MAAM,6BAAa,IAAI,IAAsB;CAE7C,KAAK,MAAM,OAAO,YAAY;EAC5B,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE,GAAG,SAAS,IAAI,IAAI,IAAI,CAAC;EACjD,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE,GAAG,WAAW,IAAI,IAAI,IAAI,CAAC,CAAC;CACxD;CAEA,KAAK,MAAM,OAAO,YAChB,KAAK,MAAM,SAAS,0BAA0B,GAAG,GAAG;EAClD,IAAI,CAAC,MAAM,IAAI,KAAK,GAClB,MAAM,IAAI,MACR,cAAc,IAAI,GAAG,8BAA8B,MAAM,UAAU,MAAM,iFAC3E;EAEF,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,EAAE,KAAK,KAAK,CAAC;EACpD,MAAM,OAAO,WAAW,IAAI,KAAK;EACjC,IAAI,SAAS,KAAA,GAAW,KAAK,KAAK,IAAI,EAAE;CAC1C;CAGF,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,CAAC,IAAI,QAAQ,UACtB,IAAI,QAAQ,GAAG,MAAM,KAAK,EAAE;CAE9B,MAAM,KAAK;CAEX,MAAM,SAAmB,CAAC;CAC1B,OAAO,MAAM,SAAS,GAAG;EACvB,MAAM,KAAK,MAAM,MAAM;EACvB,IAAI,OAAO,KAAA,GAAW;EACtB,OAAO,KAAK,EAAE;EACd,MAAM,WAAW,WAAW,IAAI,EAAE,KAAK,CAAC;EACxC,SAAS,KAAK;EACd,KAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,UAAU,SAAS,IAAI,OAAO,KAAK,KAAK;GAC9C,SAAS,IAAI,SAAS,MAAM;GAC5B,IAAI,WAAW,GAAG,MAAM,KAAK,OAAO;EACtC;CACF;CAEA,IAAI,OAAO,SAAS,WAAW,QAAQ;EACrC,MAAM,eAAe,WAClB,KAAK,MAAM,EAAE,EAAE,CAAC,CAChB,QAAQ,OAAO,CAAC,OAAO,SAAS,EAAE,CAAC,CAAC,CACpC,KAAK;EACR,MAAM,IAAI,MACR,uDAAuD,aAAa,KAAK,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EACxG;CACF;CAEA,OAAO;AACT;AAEA,SAAgB,mBACd,OACoC;CACpC,MAAM,EAAE,QAAQ,QAAQ,SAAS,QAAQ,iBAAiB,CAAC,MAAM;CAEjE,MAAM,aAAa,wBAAwB,cAAc;CACzD,MAAM,gBAAgB,IAAI,IAAI,eAAe,KAAK,QAAQ,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;CACxE,MAAM,wBAAwB,WAC3B,KAAK,OAAO,cAAc,IAAI,EAAE,CAAC,CAAC,CAClC,QAAQ,QAAiE,QAAQ,KAAA,CAAS;CAE7F,MAAM,iBAAiB;EAAC;EAAQ;EAAQ,GAAI,UAAU,CAAC,OAAO,IAAI,CAAC;EAAI,GAAG;CAAqB;CAE/F,MAAM,cAAc,mBAAmB,cAAc;CACrD,MAAM,wBAAwB,8BAA8B,cAAc;CAE1E,OAAO;EACL;EACA;EACA;EACA;EACA,gBAAgB;EAEhB,kBAAkB,wBAAwB,cAAc;EACxD,2BAA2B,iCAAiC,cAAc;EAC1E,cAAc,oBAAoB,QAAQ,QAAQ,SAAS,qBAAqB;EAChF;EACA,wBAAwB,+BAA+B,cAAc;EACrE;EACA,yBAAyB,gCAAgC,cAAc;CACzE;AACF;;;AClfA,SAAS,WAAW,KAAgC,MAA0B;CAC5E,MAAM,MAAM,KAAK;CACjB,IAAI,IAAI,IAAI,GAAG,GACb,MAAM,IAAI,MAAM,6CAA6C,KAAK;CAEpE,IAAI,IAAI,KAAK,IAAI;AACnB;AAEA,SAAS,eAAe,SAA4B,MAAiC;CACnF,OAAO,GAAG,QAAQ,IAAI,KAAK,KAAK,GAAG;AACrC;AAEA,SAAS,mBAAmB,MAAoB,YAAkD;CAChG,MAAM,OAAO,CAAC,GAAG,YAAY,KAAK,EAAE;CACpC,OAAO,CACL;EAAE;EAAM,SAAS;EAAW,SAAS,eAAe,WAAW,IAAI;EAAG,UAAU;CAAK,GACrF,GAAG,KAAK,SAAS,CAAC,CAAC,SAAS,MAAM,mBAAmB,GAAG,IAAI,CAAC,CAC/D;AACF;AAEA,SAAS,iBAAiB,MAAoB,YAAkD;CAC9F,MAAM,OAAO,CAAC,GAAG,YAAY,KAAK,EAAE;CACpC,OAAO,CACL;EAAE;EAAM,SAAS;EAAS,SAAS,eAAe,SAAS,IAAI;EAAG,QAAQ;CAAK,GAC/E,GAAG,KAAK,SAAS,CAAC,CAAC,SAAS,MAAM,iBAAiB,GAAG,IAAI,CAAC,CAC7D;AACF;;;;;;;;;;AAWA,SAAgB,YACd,UACA,QAC4B;CAC5B,OAAO,SAAS,UAAU,QAAQ,CAAC,CAAC;AACtC;AAEA,SAAS,SACP,UACA,QACA,YAC4B;CAC5B,MAAM,OAAO,CAAC,GAAG,YAAY,SAAS,EAAE;CACxC,MAAM,SAA4B,CAAC;CACnC,IAAI,CAAC,SAAS,UAAU,MAAM,GAC5B,OAAO,KAAK;EACV;EACA,SAAS;EACT,SAAS,eAAe,YAAY,IAAI;EACxC;EACA;CACF,CAAC;CAEH,OAAO,KAAK,GAAG,aAAa,SAAS,SAAS,GAAG,OAAO,SAAS,GAAG,IAAI,CAAC;CACzE,OAAO;AACT;;;;;;;;AASA,SAAS,aACP,UACA,QACA,YAC4B;CAC5B,MAAM,8BAAc,IAAI,IAA0B;CAClD,KAAK,MAAM,QAAQ,UACjB,WAAW,aAAa,IAAI;CAG9B,MAAM,4BAAY,IAAI,IAA0B;CAChD,KAAK,MAAM,QAAQ,QACjB,WAAW,WAAW,IAAI;CAG5B,MAAM,SAA4B,CAAC;CAEnC,KAAK,MAAM,CAAC,KAAK,iBAAiB,aAAa;EAC7C,MAAM,aAAa,UAAU,IAAI,GAAG;EACpC,IAAI,eAAe,KAAA,GACjB,OAAO,KAAK,GAAG,mBAAmB,cAAc,UAAU,CAAC;OAE3D,OAAO,KAAK,GAAG,SAAS,cAAc,YAAY,UAAU,CAAC;CAEjE;CAEA,KAAK,MAAM,CAAC,KAAK,eAAe,WAC9B,IAAI,CAAC,YAAY,IAAI,GAAG,GACtB,OAAO,KAAK,GAAG,iBAAiB,YAAY,UAAU,CAAC;CAI3D,OAAO;AACT;;;;;;;;;;;;AC3FA,SAAgB,uBACd,eACA,UACiB;CACjB,IAAI,kBAAkB,YACpB,OAAO;CAET,IAAI,kBAAkB,eAAe,aAAa,sBAChD,OAAO;CAET,IAAI,kBAAkB;MAElB,aAAa,wBACb,aAAa,oBACb,aAAa,yBACb,aAAa,cAEb,OAAO;CAAA;CAGX,OAAO;AACT"}
{
"name": "@prisma-next/framework-components",
"version": "0.14.0-dev.33",
"version": "0.14.0-dev.35",
"license": "Apache-2.0",

@@ -9,6 +9,6 @@ "type": "module",

"dependencies": {
"@prisma-next/contract": "0.14.0-dev.33",
"@prisma-next/operations": "0.14.0-dev.33",
"@prisma-next/ts-render": "0.14.0-dev.33",
"@prisma-next/utils": "0.14.0-dev.33",
"@prisma-next/contract": "0.14.0-dev.35",
"@prisma-next/operations": "0.14.0-dev.35",
"@prisma-next/ts-render": "0.14.0-dev.35",
"@prisma-next/utils": "0.14.0-dev.35",
"@standard-schema/spec": "^1.1.0",

@@ -18,4 +18,4 @@ "arktype": "^2.2.0"

"devDependencies": {
"@prisma-next/tsconfig": "0.14.0-dev.33",
"@prisma-next/tsdown": "0.14.0-dev.33",
"@prisma-next/tsconfig": "0.14.0-dev.35",
"@prisma-next/tsdown": "0.14.0-dev.35",
"tsdown": "0.22.1",

@@ -22,0 +22,0 @@ "typescript": "5.9.3",

@@ -322,3 +322,3 @@ import type { JsonValue } from '@prisma-next/contract/types';

const descriptorId = descriptor.id;
// Descriptor-side metadata is the single source of truth for `targetTypes` / `meta` / `renderOutputType`. Every contributor ships a `codecDescriptors` list on `types.codecTypes`.
// Descriptor-side metadata is the single source of truth for `targetTypes` / `meta` / `renderOutputType`. A component contributes its codecs by listing `codecDescriptors` on `types.codecTypes`; each codecId has exactly one contributor across the stack.
for (const codecDescriptor of codecTypes?.codecDescriptors ?? []) {

@@ -325,0 +325,0 @@ assertUniqueCodecOwner({