@prisma-next/framework-components
Advanced tools
| import { r as CodecLookup } from "./codec-types-yY3eSmi0.mjs"; | ||
| import { R as PslDiagnosticCode, Y as PslSpan, h as AuthoringPslBlockDescriptorNamespace, z as PslExtensionBlock } from "./framework-authoring-Di7Ug2bw.mjs"; | ||
| //#region src/control/psl-ast.d.ts | ||
| interface PslDiagnostic { | ||
| readonly code: PslDiagnosticCode; | ||
| readonly message: string; | ||
| readonly sourceId: string; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslDefaultFunctionValue { | ||
| readonly kind: 'function'; | ||
| readonly name: 'autoincrement' | 'now'; | ||
| } | ||
| interface PslDefaultLiteralValue { | ||
| readonly kind: 'literal'; | ||
| readonly value: string | number | boolean; | ||
| } | ||
| type PslDefaultValue = PslDefaultFunctionValue | PslDefaultLiteralValue; | ||
| type PslAttributeTarget = 'field' | 'model' | 'enum' | 'namedType'; | ||
| interface PslAttributePositionalArgument { | ||
| readonly kind: 'positional'; | ||
| readonly value: string; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslAttributeNamedArgument { | ||
| readonly kind: 'named'; | ||
| readonly name: string; | ||
| readonly value: string; | ||
| readonly span: PslSpan; | ||
| } | ||
| type PslAttributeArgument = PslAttributePositionalArgument | PslAttributeNamedArgument; | ||
| interface PslTypeConstructorCall { | ||
| readonly kind: 'typeConstructor'; | ||
| readonly path: readonly string[]; | ||
| readonly args: readonly PslAttributeArgument[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslAttribute { | ||
| readonly kind: 'attribute'; | ||
| readonly target: PslAttributeTarget; | ||
| readonly name: string; | ||
| readonly args: readonly PslAttributeArgument[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| type PslReferentialAction = string; | ||
| type PslFieldAttribute = PslAttribute; | ||
| interface PslField { | ||
| readonly kind: 'field'; | ||
| readonly name: string; | ||
| /** Unqualified type name, e.g. `"User"` for both `User`, `auth.User`, and `supabase:auth.User`. */ | ||
| readonly typeName: string; | ||
| /** Namespace qualifier from a dot-qualified type reference, e.g. `"auth"` for `auth.User` or `supabase:auth.User`. Absent for unqualified types. */ | ||
| readonly typeNamespaceId?: string; | ||
| /** | ||
| * Contract-space qualifier from a colon-prefix type reference, e.g. `"supabase"` for | ||
| * `supabase:auth.User` or `supabase:User`. Absent for local (same-space) type references. | ||
| * | ||
| * When present, the field references a model from a different contract space. The namespace | ||
| * (`typeNamespaceId`) and model name (`typeName`) identify the target within that space. | ||
| * Physical table resolution against the extension contract is deferred to the aggregate stage (M3). | ||
| */ | ||
| readonly typeContractSpaceId?: string; | ||
| readonly typeConstructor?: PslTypeConstructorCall; | ||
| readonly optional: boolean; | ||
| readonly list: boolean; | ||
| readonly typeRef?: string; | ||
| readonly attributes: readonly PslFieldAttribute[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslUniqueConstraint { | ||
| readonly kind: 'unique'; | ||
| readonly fields: readonly string[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslIndexConstraint { | ||
| readonly kind: 'index'; | ||
| readonly fields: readonly string[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| type PslModelAttribute = PslAttribute; | ||
| interface PslModel { | ||
| readonly kind: 'model'; | ||
| readonly name: string; | ||
| readonly fields: readonly PslField[]; | ||
| readonly attributes: readonly PslModelAttribute[]; | ||
| readonly span: PslSpan; | ||
| /** | ||
| * Optional leading comment line emitted above the `model` keyword by the | ||
| * printer. Producers (e.g. `sqlSchemaIrToPslAst`) attach introspection | ||
| * advisories such as "// WARNING: This table has no primary key in the | ||
| * database" here. The parser leaves this field unset; round-tripping a | ||
| * parsed schema does not re-attach comments. | ||
| */ | ||
| readonly comment?: string; | ||
| } | ||
| /** | ||
| * A reusable group of fields embedded in a model (a `type Name { … }` block) — | ||
| * e.g. a MongoDB embedded document or a Postgres composite type. Unlike | ||
| * {@link PslModel} it has no storage or identity of its own. | ||
| */ | ||
| interface PslCompositeType { | ||
| readonly kind: 'compositeType'; | ||
| readonly name: string; | ||
| readonly fields: readonly PslField[]; | ||
| readonly attributes: readonly PslAttribute[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslNamedTypeDeclaration { | ||
| readonly kind: 'namedType'; | ||
| readonly name: string; | ||
| /** | ||
| * Parser invariant: exactly one of `baseType` and `typeConstructor` is set. | ||
| * Expressing this as a discriminated union trips TypeScript narrowing when | ||
| * the declaration flows through helpers that accept the full union. | ||
| */ | ||
| readonly baseType?: string; | ||
| readonly typeConstructor?: PslTypeConstructorCall; | ||
| readonly attributes: readonly PslAttribute[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslTypesBlock { | ||
| readonly kind: 'types'; | ||
| readonly declarations: readonly PslNamedTypeDeclaration[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| /** | ||
| * Name of the synthesised namespace bucket the framework parser uses for | ||
| * top-level declarations that appear outside any `namespace { … }` block. | ||
| * The double-underscore decoration signals that the identifier is parser- | ||
| * synthesised and never appears in user-authored PSL source — writing | ||
| * `namespace __unspecified__ { … }` is a parse error. | ||
| * | ||
| * Distinct from the IR sentinel `__unbound__`: the PSL bucket describes | ||
| * syntactic absence at the parser layer; the IR sentinel describes a late- | ||
| * bound storage slot at the IR layer. Per-target interpreters decide how | ||
| * (or whether) to map the PSL bucket to the IR sentinel. | ||
| */ | ||
| declare const UNSPECIFIED_PSL_NAMESPACE_ID = "__unspecified__"; | ||
| /** A value in {@link PslNamespace.entries}: a built-in entity node or an extension-contributed {@link PslExtensionBlock}. */ | ||
| type PslNamespaceEntry = PslModel | PslCompositeType | PslExtensionBlock; | ||
| /** | ||
| * A namespace block, or the parser's synthesised `__unspecified__` bucket for | ||
| * declarations outside any `namespace { … }`. Same-name blocks reopen-merge; | ||
| * `span` points at the first opening. | ||
| * | ||
| * Entities are stored canonically (ADR 224) in `entries[kind][name]`, where | ||
| * `kind` is the PSL keyword for built-ins or the block discriminator for | ||
| * extension kinds, e.g. `entries['policy']['ReadPosts']` (the discriminator, | ||
| * not the PSL keyword — a `policy_select` block lands under `'policy'` per | ||
| * ADR 225). | ||
| */ | ||
| interface PslNamespace { | ||
| readonly kind: 'namespace'; | ||
| readonly name: string; | ||
| /** Canonical store: a frozen container of frozen per-kind maps. The accessors below derive from it. */ | ||
| readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>; | ||
| /** Built-in models, from `entries['model']`. Extension kinds: {@link namespacePslExtensionBlocks}. */ | ||
| readonly models: readonly PslModel[]; | ||
| /** Built-in composite types, from `entries['compositeType']`. */ | ||
| readonly compositeTypes: readonly PslCompositeType[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| /** Constructs a {@link PslNamespace}. Use this, never a namespace literal — the accessors must derive from `entries`. */ | ||
| declare function makePslNamespace(init: { | ||
| readonly kind: 'namespace'; | ||
| readonly name: string; | ||
| readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>; | ||
| readonly span: PslSpan; | ||
| }): PslNamespace; | ||
| /** | ||
| * Builds the frozen `entries[kind][name]` container from per-kind arrays. | ||
| * Built-ins key on their PSL keyword; extension blocks key on their `kind` | ||
| * discriminator. Call this rather than hand-building the literal. | ||
| */ | ||
| declare function makePslNamespaceEntries(models: readonly PslModel[], compositeTypes: readonly PslCompositeType[], extensionBlocks: readonly PslExtensionBlock[]): Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>; | ||
| interface PslDocumentAst { | ||
| readonly kind: 'document'; | ||
| readonly sourceId: string; | ||
| readonly namespaces: readonly PslNamespace[]; | ||
| readonly types?: PslTypesBlock; | ||
| readonly span: PslSpan; | ||
| } | ||
| /** | ||
| * Returns all models from every namespace in document order. Convenience | ||
| * for consumers that don't (yet) need namespace-awareness. | ||
| */ | ||
| declare function flatPslModels(ast: PslDocumentAst): readonly PslModel[]; | ||
| /** | ||
| * Returns all composite types from every namespace in document order. | ||
| */ | ||
| declare function flatPslCompositeTypes(ast: PslDocumentAst): readonly PslCompositeType[]; | ||
| /** | ||
| * The set of `entries` kind keys that the framework parser reserves for | ||
| * built-in PSL entity kinds. Any own-enumerable key on `PslNamespace.entries` | ||
| * that is **not** in this set was contributed by an extension-block descriptor. | ||
| * | ||
| * Built-in keys match the PSL keyword used on each block type: | ||
| * `'model'`, `'compositeType'`. The `'enum'` keyword is claimed by the | ||
| * extension-block grammar via a registered descriptor, so `entries['enum']` | ||
| * holds `PslExtensionBlock` nodes and is returned by `namespacePslExtensionBlocks`. | ||
| */ | ||
| declare const BUILTIN_PSL_KIND_KEYS: ReadonlySet<string>; | ||
| /** | ||
| * Returns all extension-contributed blocks in the given namespace, in | ||
| * insertion order (the order the parser encountered them in the source). | ||
| * | ||
| * Reads from `namespace.entries`, skipping the built-in kind keys | ||
| * (`'model'`, `'compositeType'`). All remaining kind maps contain | ||
| * only `PslExtensionBlock` nodes by construction (see `makePslNamespaceEntries`). | ||
| */ | ||
| declare function namespacePslExtensionBlocks(ns: PslNamespace): readonly PslExtensionBlock[]; | ||
| interface ParsePslDocumentInput { | ||
| readonly schema: string; | ||
| readonly sourceId: string; | ||
| /** | ||
| * Registry of declarative block descriptors, keyed by arbitrary path | ||
| * segments with {@link AuthoringPslBlockDescriptor} leaves. The registry | ||
| * teaches the parser which top-level keywords belong to extension | ||
| * contributions: when the parser encounters an unknown keyword, it looks | ||
| * it up here and, when found, reads the block generically into a | ||
| * {@link PslExtensionBlock} node. Absent or undefined means no extension | ||
| * blocks are registered and any unknown keyword yields | ||
| * `PSL_UNSUPPORTED_TOP_LEVEL_BLOCK`. | ||
| * | ||
| * Contrast with the parsed block nodes themselves, which live in | ||
| * {@link PslNamespace.entries} under their discriminator key (read them with | ||
| * {@link namespacePslExtensionBlocks}); this field holds the registry of | ||
| * descriptors that teach the parser how to read those blocks. | ||
| */ | ||
| readonly pslBlockDescriptors?: AuthoringPslBlockDescriptorNamespace; | ||
| /** | ||
| * Codec lookup for validating `value`-kind extension block parameters. | ||
| * When provided alongside `pslBlockDescriptors`, the generic validator runs | ||
| * over every parsed extension block after the full AST is assembled, | ||
| * appending any diagnostics to the parse result. Absent or undefined means | ||
| * no codec validation runs; `ref` resolution still runs when namespace | ||
| * context is available (built from the assembled namespaces). | ||
| */ | ||
| readonly codecLookup?: CodecLookup; | ||
| } | ||
| interface ParsePslDocumentResult { | ||
| readonly ast: PslDocumentAst; | ||
| readonly diagnostics: readonly PslDiagnostic[]; | ||
| readonly ok: boolean; | ||
| } | ||
| //#endregion | ||
| export { makePslNamespace as A, PslReferentialAction as C, UNSPECIFIED_PSL_NAMESPACE_ID as D, PslUniqueConstraint as E, namespacePslExtensionBlocks as M, flatPslCompositeTypes as O, PslNamespaceEntry as S, PslTypesBlock as T, PslIndexConstraint as _, PslAttributeArgument as a, PslNamedTypeDeclaration as b, PslAttributeTarget as c, PslDefaultLiteralValue as d, PslDefaultValue as f, PslFieldAttribute as g, PslField as h, PslAttribute as i, makePslNamespaceEntries as j, flatPslModels as k, PslCompositeType as l, PslDocumentAst as m, ParsePslDocumentInput as n, PslAttributeNamedArgument as o, PslDiagnostic as p, ParsePslDocumentResult as r, PslAttributePositionalArgument as s, BUILTIN_PSL_KIND_KEYS as t, PslDefaultFunctionValue as u, PslModel as v, PslTypeConstructorCall as w, PslNamespace as x, PslModelAttribute as y }; | ||
| //# sourceMappingURL=psl-ast-CiZNxGGb.d.mts.map |
| {"version":3,"file":"psl-ast-CiZNxGGb.d.mts","names":[],"sources":["../src/control/psl-ast.ts"],"mappings":"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"} |
| import { StorageBase, StorageNamespace } from "@prisma-next/contract/types"; | ||
| import { isPlainRecord } from "@prisma-next/contract/is-plain-record"; | ||
| //#region src/ir/ir-node.d.ts | ||
| /** | ||
| * Framework-level IR alphabet. | ||
| * | ||
| * The framework's contribution to Contract IR / Schema IR is a common | ||
| * root for the IR class hierarchy and a freeze affordance. Family | ||
| * abstract bases (e.g. `SqlNode`, `MongoSchemaIRNode`) refine the alphabet | ||
| * for their family shape; targets ship the concrete classes. | ||
| * | ||
| * `kind` is an optional discriminator on the base. Families and leaves | ||
| * that benefit from discriminated-union dispatch declare their own | ||
| * literal `kind` at the level that earns it — Mongo leaves carry | ||
| * per-class literals (`readonly kind = 'mongo-collection' as const`) | ||
| * because Mongo IR has polymorphic walkers; SQL declares a single | ||
| * family-level `kind = 'sql'` on `SqlNode` because SQL IR has no | ||
| * polymorphic dispatch today. No framework consumer dispatches on | ||
| * `IRNode.kind` at the BASE type — every dispatch site narrows | ||
| * through a union of leaves where each leaf carries a literal kind, so | ||
| * requiring `kind` at the base would be unearned. Future leaves that | ||
| * earn polymorphic dispatch override with a required literal at that | ||
| * leaf (e.g. `override readonly kind = 'pack-contributed-kind' as const`). | ||
| * | ||
| * `IRNodeBase` carries no methods: the freeze-and-assign affordance | ||
| * lives in the free `freezeNode` helper below. Keeping `freezeNode` out | ||
| * of the class type means an emitted contract literal type | ||
| * (`{ readonly kind: 'mongo-collection', ... }` or an unkeyed literal | ||
| * like `{ nativeType, codecId, nullable }`) is structurally assignable | ||
| * to its class type — a `protected freeze()` instance method would | ||
| * otherwise leak into the public type surface and require the literal | ||
| * to carry it too. | ||
| * | ||
| * Subclasses construct fields then call `freezeNode(this)` to seal the | ||
| * instance. Frozen instances + plain readonly fields keep IR nodes | ||
| * JSON-clean by construction, so `JSON.stringify(node)` produces canonical | ||
| * JSON without a `toJSON()` method. The `ContractSerializer` SPI handles | ||
| * round-trip from canonical JSON back to typed class instances. | ||
| * | ||
| * The name (`IRNode` / `IRNodeBase`) reflects the dual-hierarchy reality: | ||
| * this base is the common root for both Contract IR and Schema IR class | ||
| * hierarchies, not a Schema-IR-specific alphabet. | ||
| */ | ||
| interface IRNode { | ||
| readonly kind?: string; | ||
| } | ||
| declare abstract class IRNodeBase implements IRNode { | ||
| abstract readonly kind?: string; | ||
| } | ||
| /** | ||
| * Seal an IR class instance after its constructor has assigned all | ||
| * fields. The free-helper form (rather than a `protected freeze()` | ||
| * instance method) keeps the class type structurally narrow so emitted | ||
| * contract literal types remain assignable to their class types. | ||
| * | ||
| * The helper name stays `freezeNode` — it operates on IR nodes | ||
| * regardless of root naming. | ||
| */ | ||
| declare function freezeNode<T extends IRNode>(node: T): T; | ||
| //#endregion | ||
| //#region src/ir/namespace.d.ts | ||
| /** | ||
| * Reserved sentinel namespace id for the late-bound storage slot — | ||
| * the slot whose binding the target resolves at connection time | ||
| * rather than at authoring time. Postgres uses it for `search_path` | ||
| * late binding; SQLite uses it for the trivial singleton; Mongo uses | ||
| * it for the connection's `db` binding. | ||
| * | ||
| * Materialised target-side as a singleton subclass of the target's | ||
| * `NamespaceBase` concretion that overrides the namespace's | ||
| * qualifier-emission methods to elide the prefix entirely. Call sites | ||
| * stay polymorphic and never branch on `id === UNBOUND_NAMESPACE_ID` | ||
| * — the singleton's overrides drop the qualifier so emitted SQL / Mongo | ||
| * commands look unqualified. | ||
| * | ||
| * The double-underscore decoration marks the id as a framework-reserved | ||
| * coordinate when it appears in a JSON envelope (cold-read-as-reserved | ||
| * — no realistic collision with user-declared namespace names). | ||
| * | ||
| * Encoded as an exported const (rather than scattered string literals) | ||
| * so the sentinel-id invariant is single-sourced: any production-source | ||
| * site that constructs an unbound-namespace singleton imports this | ||
| * constant. | ||
| */ | ||
| declare const UNBOUND_NAMESPACE_ID: "__unbound__"; | ||
| /** | ||
| * Framework-level building block for a "namespace" — the database-level | ||
| * grouping under which storage objects (tables, collections, enums, …) | ||
| * reside. Each target's namespace concretion maps the framework concept to | ||
| * a target-native binding: | ||
| * | ||
| * - Postgres: a schema (`CREATE SCHEMA …`); rendered as `"<schema>"`. | ||
| * - SQLite: the singleton `UNBOUND_NAMESPACE_ID`; emitted SQL has no qualifier. | ||
| * - Mongo: the connection's `db` field; addressed as a database name. | ||
| * | ||
| * See `UNBOUND_NAMESPACE_ID` above for the sentinel id and the | ||
| * singleton-subclass pattern that materialises it. | ||
| * | ||
| * The framework promises only the coordinate (`id`) — the named storage | ||
| * entities a namespace contains are family-typed (SQL contributes | ||
| * `table` / `type`, Mongo contributes `collection`, future families pick | ||
| * their own native idiom under `entries`). Generic consumers walking "all | ||
| * named entries" go through a family-typed namespace, not the framework | ||
| * `Namespace`. | ||
| * | ||
| * Every namespace concretion (e.g. family-built SQL namespaces, | ||
| * `MongoUnboundNamespace`, target-promoted namespaces like | ||
| * `PostgresSchema`) carries exactly: `id` (enumerable string), | ||
| * `entries` (frozen object holding entity-kind slot maps), and `kind` | ||
| * (non-enumerable string discriminator set via `Object.defineProperty`). | ||
| * Each slot map under `entries` uses a singular essence key (`table`, | ||
| * `type`, `collection`, …) mapping entity names to IR classes. No other | ||
| * own-enumerable data lives on a namespace; non-entity computed data lives | ||
| * on the surrounding storage or contract IR. The framework's | ||
| * `elementCoordinates(storage)` walk relies on this invariant to enumerate | ||
| * entities structurally without family-specific knowledge. | ||
| */ | ||
| interface Namespace extends IRNode, StorageNamespace { | ||
| readonly kind: string; | ||
| readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>; | ||
| } | ||
| declare abstract class NamespaceBase extends IRNodeBase implements Namespace { | ||
| abstract readonly id: string; | ||
| abstract readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>; | ||
| abstract readonly kind: string; | ||
| } | ||
| //#endregion | ||
| //#region src/ir/storage.d.ts | ||
| /** | ||
| * Canonical address for a named entity in Contract IR / Schema IR. | ||
| * | ||
| * `plane` is `'domain' | 'storage'`: which top-level contract plane the | ||
| * entity lives on. Domain-side walks yield `plane: 'domain'` via | ||
| * {@link domainElementCoordinates}; {@link elementCoordinates} over storage | ||
| * yields `plane: 'storage'`. | ||
| * | ||
| * Cross-plane references obey a directional invariant: domain → storage is | ||
| * allowed; storage → domain is forbidden. That rule is enforced by a | ||
| * separate validator, not by constraining this coordinate shape — the | ||
| * coordinate carries the axis the validator checks. | ||
| * | ||
| * Iteration order over namespace properties follows `Object.entries` order; | ||
| * consumers that depend on ordering must sort. | ||
| */ | ||
| interface EntityCoordinate { | ||
| readonly plane: 'domain' | 'storage'; | ||
| readonly namespaceId: string; | ||
| readonly entityKind: string; | ||
| readonly entityName: string; | ||
| } | ||
| /** | ||
| * Lazy walk over every named storage entity in a `Storage`-shaped | ||
| * value, yielded as {@link EntityCoordinate} tuples with | ||
| * `plane: 'storage'` (the parameter type binds the plane). | ||
| * | ||
| * Iterates each namespace's `entries` kind maps structurally. Skips | ||
| * non-object `entries`; `id` and `kind` are not walked (`kind` is | ||
| * non-enumerable on concretions). For every entity-kind key under | ||
| * `entries` whose value is a non-null object, yields one coordinate per | ||
| * entity name in that map. No family-specific kind vocabulary is required. | ||
| */ | ||
| declare function elementCoordinates(storage: Pick<StorageBase, 'namespaces'>): Generator<EntityCoordinate>; | ||
| /** | ||
| * Looks up a single entity in a `Storage`-shaped value by its full coordinate. | ||
| * Returns `undefined` if the namespace, entity kind, or entity name is absent. | ||
| * The type parameter is a caller assertion — the walk itself is structural | ||
| * and cannot verify the entity's shape. | ||
| */ | ||
| declare function entityAt<T = unknown>(storage: Pick<StorageBase, 'namespaces'>, coord: Pick<EntityCoordinate, 'namespaceId' | 'entityKind' | 'entityName'>): T | undefined; | ||
| /** | ||
| * Framework-level promise that every Contract IR / Schema IR carries a | ||
| * collection of namespaces keyed by namespace id. Family storage | ||
| * concretions (`SqlStorage`, `MongoStorage`) refine the shape with | ||
| * family-specific fields (tables, collections, enums, …); target | ||
| * concretions add target fields where the family vocabulary doesn't | ||
| * reach. | ||
| * | ||
| * Keeping `namespaces` at the framework layer enforces that every storage | ||
| * object — across any target — is namespace-scoped. The framework can | ||
| * therefore walk the namespace map without knowing the family alphabet, and | ||
| * the `(namespace.id, name)` keying that the verifier and planner depend on | ||
| * is honest at every layer. | ||
| * | ||
| * Extends `IRNode` so the framework's IR-walking surfaces (verifiers, | ||
| * serializers) can dispatch on `Storage`-typed fields through the same | ||
| * IR-node alphabet as every other node — the structural dual already | ||
| * holds in code (every concrete storage class extends an IR-node base); | ||
| * the interface promotion makes the typing honest. | ||
| * | ||
| * **Persisted envelope shape is target-owned, not framework-promised.** | ||
| * Whether the `namespaces` map appears in the on-disk JSON envelope is | ||
| * a per-target decision made by `ContractSerializer.serializeContract`. | ||
| * Some targets emit a JSON-clean namespace shape that round-trips | ||
| * through `JSON.stringify` cleanly (SQL today via the family-layer | ||
| * identity serializer); others ship runtime-only fields on their | ||
| * namespace concretions and override `serializeContract` to strip | ||
| * them (Mongo). Future open (F16): extend the per-target | ||
| * `ContractSerializer` integration-test surface with an explicit | ||
| * envelope-shape assertion for each target, so the strip-vs-pass-through | ||
| * choice is locked at test time rather than implied by the override | ||
| * presence/absence. Earned by PR2's per-target namespace lift, when | ||
| * `PostgresSchema` / `SqliteUnboundDatabase` start carrying | ||
| * target-specific fields. | ||
| */ | ||
| interface Storage extends IRNode { | ||
| readonly namespaces: Readonly<Record<string, Namespace>>; | ||
| } | ||
| //#endregion | ||
| export { isPlainRecord as a, UNBOUND_NAMESPACE_ID as c, freezeNode as d, entityAt as i, IRNode as l, Storage as n, Namespace as o, elementCoordinates as r, NamespaceBase as s, EntityCoordinate as t, IRNodeBase as u }; | ||
| //# sourceMappingURL=storage-LiDzCDHm.d.mts.map |
| {"version":3,"file":"storage-LiDzCDHm.d.mts","names":[],"sources":["../src/ir/ir-node.ts","../src/ir/namespace.ts","../src/ir/storage.ts"],"mappings":";;;;;;;;AAyCA;;;;AACe;AAGf;;;;AACwB;AAYxB;;;;;;;;;;;;;;AAAwD;;;;AChCxD;;;;AAA0D;AAkC1D;;;UDnBiB,MAAA;EAAA,SACN,IAAI;AAAA;AAAA,uBAGO,UAAA,YAAsB,MAAM;EAAA,kBAC9B,IAAI;AAAA;;;;;;;;;;iBAYR,UAAA,WAAqB,MAAA,EAAQ,IAAA,EAAM,CAAA,GAAI,CAAA;;;;;AAjBvD;;;;AACe;AAGf;;;;AACwB;AAYxB;;;;;;;;;;;cChCa,oBAAA;;;ADgC2C;;;;AChCxD;;;;AAA0D;AAkC1D;;;;;;;;;;;;;;;;;;;;AAE2D;UAF1C,SAAA,SAAkB,MAAA,EAAQ,gBAAA;EAAA,SAChC,IAAA;EAAA,SACA,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA;AAAA;AAAA,uBAG/B,aAAA,SAAsB,UAAA,YAAsB,SAAA;EAAA,kBAC9C,EAAA;EAAA,kBACA,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA;EAAA,kBACjC,IAAA;AAAA;;;;;;AD1Bd;AAGf;;;;AACwB;AAYxB;;;;;;;UElCiB,gBAAA;EAAA,SACN,KAAA;EAAA,SACA,WAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA;AAAA;;AF8B6C;;;;AChCxD;;;;AAA0D;AAkC1D;iBClBiB,kBAAA,CACf,OAAA,EAAS,IAAA,CAAK,WAAA,kBACb,SAAA,CAAU,gBAAA;;;;;;;iBAmBG,QAAA,cACd,OAAA,EAAS,IAAA,CAAK,WAAA,iBACd,KAAA,EAAO,IAAA,CAAK,gBAAA,iDACX,CAAA;;;;;;;;;;;;ADJwD;AAG3D;;;;;;;;;;;;;;;;;;;;;AAGiC;;UC8ChB,OAAA,SAAgB,MAAA;EAAA,SACtB,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,SAAA;AAAA"} |
| import type { EntityCoordinate } from '../ir/storage'; | ||
| export type SchemaDiffOutcome = 'missing' | 'extra' | 'mismatch'; | ||
| export interface SchemaDiffIssue { | ||
| readonly coordinate: EntityCoordinate; | ||
| readonly outcome: SchemaDiffOutcome; | ||
| readonly message: string; | ||
| /** The expected (contract-side) node, when available. Absent for `extra` outcomes. */ | ||
| readonly expected?: DiffableNode; | ||
| /** The actual (live-DB-side) node, when available. Absent for `missing` outcomes. */ | ||
| readonly actual?: DiffableNode; | ||
| } | ||
| /** A node the generic differ can align and compare. Implemented by target IR nodes. */ | ||
| export interface DiffableNode { | ||
| identity(): EntityCoordinate; | ||
| isEqualTo(other: DiffableNode): boolean; | ||
| } | ||
| /** Canonical string key for a coordinate. Uses pipe-separated fields so null bytes cannot appear. */ | ||
| function stableKey(c: EntityCoordinate): string { | ||
| return `${c.plane}|${c.namespaceId}|${c.entityKind}|${c.entityName}`; | ||
| } | ||
| function outcomeMessage(outcome: SchemaDiffOutcome, c: EntityCoordinate): string { | ||
| return `${outcome}: ${c.entityKind} '${c.entityName}' in namespace '${c.namespaceId}'`; | ||
| } | ||
| /** | ||
| * Align two flat node collections by identity; emit missing/extra/mismatch issues in input order. | ||
| * Intentionally flat — child-node recursion is a separate follow-on concern (the relational port). | ||
| */ | ||
| export function diffNodes( | ||
| expected: readonly DiffableNode[], | ||
| actual: readonly DiffableNode[], | ||
| ): readonly SchemaDiffIssue[] { | ||
| const expectedMap = new Map<string, DiffableNode>(); | ||
| for (const node of expected) { | ||
| expectedMap.set(stableKey(node.identity()), node); | ||
| } | ||
| const actualMap = new Map<string, DiffableNode>(); | ||
| for (const node of actual) { | ||
| actualMap.set(stableKey(node.identity()), node); | ||
| } | ||
| const issues: SchemaDiffIssue[] = []; | ||
| for (const [key, expectedNode] of expectedMap) { | ||
| const actualNode = actualMap.get(key); | ||
| const coordinate = expectedNode.identity(); | ||
| if (actualNode === undefined) { | ||
| issues.push({ | ||
| coordinate, | ||
| outcome: 'missing', | ||
| message: outcomeMessage('missing', coordinate), | ||
| expected: expectedNode, | ||
| }); | ||
| } else if (!expectedNode.isEqualTo(actualNode)) { | ||
| issues.push({ | ||
| coordinate, | ||
| outcome: 'mismatch', | ||
| message: outcomeMessage('mismatch', coordinate), | ||
| expected: expectedNode, | ||
| actual: actualNode, | ||
| }); | ||
| } | ||
| } | ||
| for (const [key, actualNode] of actualMap) { | ||
| if (!expectedMap.has(key)) { | ||
| const coordinate = actualNode.identity(); | ||
| issues.push({ | ||
| coordinate, | ||
| outcome: 'extra', | ||
| message: outcomeMessage('extra', coordinate), | ||
| actual: actualNode, | ||
| }); | ||
| } | ||
| } | ||
| return issues; | ||
| } |
+26
-2
@@ -5,4 +5,5 @@ import { o as CodecRegistry } from "./codec-types-yY3eSmi0.mjs"; | ||
| import { t as TypesImportSpec } from "./types-import-spec-DRKzrJ20.mjs"; | ||
| import { t as EntityCoordinate } from "./storage-LiDzCDHm.mjs"; | ||
| import { t as EmissionSpi } from "./emission-types-C561PwcN.mjs"; | ||
| import { m as PslDocumentAst } from "./psl-ast-CWkHgK17.mjs"; | ||
| import { m as PslDocumentAst } from "./psl-ast-CiZNxGGb.mjs"; | ||
| import { Contract, ContractMarkerRecord, ControlPolicy, LedgerEntryRecord } from "@prisma-next/contract/types"; | ||
@@ -72,2 +73,24 @@ import { ImportRequirement, ImportRequirement as ImportRequirement$1 } from "@prisma-next/ts-render"; | ||
| //#endregion | ||
| //#region src/control/schema-diff.d.ts | ||
| type SchemaDiffOutcome = 'missing' | 'extra' | 'mismatch'; | ||
| interface SchemaDiffIssue { | ||
| readonly coordinate: EntityCoordinate; | ||
| readonly outcome: SchemaDiffOutcome; | ||
| readonly message: string; | ||
| /** The expected (contract-side) node, when available. Absent for `extra` outcomes. */ | ||
| readonly expected?: DiffableNode; | ||
| /** The actual (live-DB-side) node, when available. Absent for `missing` outcomes. */ | ||
| readonly actual?: DiffableNode; | ||
| } | ||
| /** A node the generic differ can align and compare. Implemented by target IR nodes. */ | ||
| interface DiffableNode { | ||
| identity(): EntityCoordinate; | ||
| isEqualTo(other: DiffableNode): boolean; | ||
| } | ||
| /** | ||
| * Align two flat node collections by identity; emit missing/extra/mismatch issues in input order. | ||
| * Intentionally flat — child-node recursion is a separate follow-on concern (the relational port). | ||
| */ | ||
| declare function diffNodes(expected: readonly DiffableNode[], actual: readonly DiffableNode[]): readonly SchemaDiffIssue[]; | ||
| //#endregion | ||
| //#region src/control/control-result-types.d.ts | ||
@@ -174,2 +197,3 @@ declare const VERIFY_CODE_MARKER_MISSING = "PN-RUN-3001"; | ||
| readonly issues: readonly SchemaIssue[]; | ||
| readonly schemaDiffIssues: readonly SchemaDiffIssue[]; | ||
| readonly root: SchemaVerificationNode; | ||
@@ -1159,3 +1183,3 @@ readonly counts: { | ||
| //#endregion | ||
| export { APP_SPACE_ID, type AssembledAuthoringContributions, type BaseSchemaIssue, type ContractSerializer, type ContractSpace, type ContractSpaceHeadRef, type ControlAdapterDescriptor, type ControlAdapterInstance, type ControlDriverDescriptor, type ControlDriverInstance, type ControlExtensionDescriptor, type ControlExtensionInstance, type ControlFamilyDescriptor, type ControlFamilyInstance, type ControlMutationDefaultEntry, type ControlMutationDefaultRegistry, type ControlMutationDefaults, type ControlStack, type ControlTargetDescriptor, type ControlTargetInstance, type CoreSchemaView, type CreateControlStackInput, type DefaultFunctionLoweringContext, type DefaultFunctionLoweringHandler, type DefaultFunctionRegistry, type DefaultFunctionRegistryEntry, type EmitContractResult, type EnumValuesChangedIssue, type ImportRequirement, type IntrospectSchemaResult, type LoweredDefaultResult, type LoweredDefaultValue, type MigratableTargetDescriptor, type MigrationMetadata, type MigrationOperationClass, type MigrationOperationPolicy, type MigrationPackage, type MigrationPlan, type MigrationPlanOperation, type MigrationPlanWithAuthoringSurface, type MigrationPlanner, type MigrationPlannerConflict, type MigrationPlannerFailureResult, type MigrationPlannerResult, type MigrationPlannerSuccessResult, type MigrationRunner, type MigrationRunnerExecutionChecks, type MigrationRunnerFailure, type MigrationRunnerPerSpaceOptions, type MigrationRunnerPerSpaceSuccessValue, type MigrationRunnerResult, type MigrationRunnerSuccessValue, type MigrationScaffoldContext, type MutationDefaultGeneratorDescriptor, type OpFactoryCall, type OperationContext, type OperationPreview, type OperationPreviewCapable, type OperationPreviewStatement, type ParsedDefaultFunctionCall, type PslContractInferCapable, type SchemaIssue, SchemaTreeNode, type SchemaTreeNodeOptions, type SchemaTreeVisitor, type SchemaVerificationNode, type SchemaVerifier, type SchemaVerifyOptions, type SchemaVerifyResult, type SchemaViewCapable, type SchemaViewNodeKind, type SignDatabaseResult, type SourceDiagnostic, type SourceSpan, type TargetMigrationsCapability, VERIFY_CODE_HASH_MISMATCH, VERIFY_CODE_MARKER_MISSING, VERIFY_CODE_SCHEMA_FAILURE, VERIFY_CODE_TARGET_MISMATCH, type VerificationStatus, type VerifierIssueCategory, type VerifierOutcome, type VerifyDatabaseResult, type VerifyDatabaseSchemaResult, assembleAuthoringContributions, assembleControlMutationDefaults, assembleScalarTypeDescriptors, assertUniqueCodecOwner, buildExtensionLoadOrder, createControlStack, dispositionForCategory, extractCodecLookup, extractCodecTypeImports, extractComponentIds, extractQueryOperationTypeImports, hasMigrations, hasOperationPreview, hasPslContractInfer, hasSchemaView }; | ||
| export { APP_SPACE_ID, type AssembledAuthoringContributions, type BaseSchemaIssue, type ContractSerializer, type ContractSpace, type ContractSpaceHeadRef, type ControlAdapterDescriptor, type ControlAdapterInstance, type ControlDriverDescriptor, type ControlDriverInstance, type ControlExtensionDescriptor, type ControlExtensionInstance, type ControlFamilyDescriptor, type ControlFamilyInstance, type ControlMutationDefaultEntry, type ControlMutationDefaultRegistry, type ControlMutationDefaults, type ControlStack, type ControlTargetDescriptor, type ControlTargetInstance, type CoreSchemaView, type CreateControlStackInput, type DefaultFunctionLoweringContext, type DefaultFunctionLoweringHandler, type DefaultFunctionRegistry, type DefaultFunctionRegistryEntry, type DiffableNode, type EmitContractResult, type EnumValuesChangedIssue, type ImportRequirement, type IntrospectSchemaResult, type LoweredDefaultResult, type LoweredDefaultValue, type MigratableTargetDescriptor, type MigrationMetadata, type MigrationOperationClass, type MigrationOperationPolicy, type MigrationPackage, type MigrationPlan, type MigrationPlanOperation, type MigrationPlanWithAuthoringSurface, type MigrationPlanner, type MigrationPlannerConflict, type MigrationPlannerFailureResult, type MigrationPlannerResult, type MigrationPlannerSuccessResult, type MigrationRunner, type MigrationRunnerExecutionChecks, type MigrationRunnerFailure, type MigrationRunnerPerSpaceOptions, type MigrationRunnerPerSpaceSuccessValue, type MigrationRunnerResult, type MigrationRunnerSuccessValue, type MigrationScaffoldContext, type MutationDefaultGeneratorDescriptor, type OpFactoryCall, type OperationContext, type OperationPreview, type OperationPreviewCapable, type OperationPreviewStatement, type ParsedDefaultFunctionCall, type PslContractInferCapable, type SchemaDiffIssue, type SchemaDiffOutcome, type SchemaIssue, SchemaTreeNode, type SchemaTreeNodeOptions, type SchemaTreeVisitor, type SchemaVerificationNode, type SchemaVerifier, type SchemaVerifyOptions, type SchemaVerifyResult, type SchemaViewCapable, type SchemaViewNodeKind, type SignDatabaseResult, type SourceDiagnostic, type SourceSpan, type TargetMigrationsCapability, VERIFY_CODE_HASH_MISMATCH, VERIFY_CODE_MARKER_MISSING, VERIFY_CODE_SCHEMA_FAILURE, VERIFY_CODE_TARGET_MISMATCH, type VerificationStatus, type VerifierIssueCategory, type VerifierOutcome, type VerifyDatabaseResult, type VerifyDatabaseSchemaResult, assembleAuthoringContributions, assembleControlMutationDefaults, assembleScalarTypeDescriptors, assertUniqueCodecOwner, buildExtensionLoadOrder, createControlStack, diffNodes, dispositionForCategory, extractCodecLookup, extractCodecTypeImports, extractComponentIds, extractQueryOperationTypeImports, hasMigrations, hasOperationPreview, hasPslContractInfer, hasSchemaView }; | ||
| //# sourceMappingURL=control.d.mts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"control.d.mts","names":[],"sources":["../src/control/contract-serializer.ts","../src/control/control-result-types.ts","../src/control/control-instances.ts","../src/control/control-stack.ts","../src/control/control-descriptors.ts","../src/control/control-migration-types.ts","../src/control/control-operation-preview.ts","../src/control/control-schema-view.ts","../src/control/control-capabilities.ts","../src/control/control-spaces.ts","../src/control/schema-verifier.ts","../src/control/verifier-disposition.ts"],"mappings":"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"} | ||
| {"version":3,"file":"control.d.mts","names":[],"sources":["../src/control/contract-serializer.ts","../src/control/schema-diff.ts","../src/control/control-result-types.ts","../src/control/control-instances.ts","../src/control/control-stack.ts","../src/control/control-descriptors.ts","../src/control/control-migration-types.ts","../src/control/control-operation-preview.ts","../src/control/control-schema-view.ts","../src/control/control-capabilities.ts","../src/control/control-spaces.ts","../src/control/schema-verifier.ts","../src/control/verifier-disposition.ts"],"mappings":"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"} |
+48
-1
@@ -300,2 +300,49 @@ import { n as materializeCodec, r as resolveCodecDescriptorOrThrow, t as CONTRACT_CODEC_DESCRIPTOR_MISSING } from "./resolve-codec-D8EPZosv.mjs"; | ||
| //#endregion | ||
| //#region src/control/schema-diff.ts | ||
| /** Canonical string key for a coordinate. Uses pipe-separated fields so null bytes cannot appear. */ | ||
| function stableKey(c) { | ||
| return `${c.plane}|${c.namespaceId}|${c.entityKind}|${c.entityName}`; | ||
| } | ||
| function outcomeMessage(outcome, c) { | ||
| return `${outcome}: ${c.entityKind} '${c.entityName}' in namespace '${c.namespaceId}'`; | ||
| } | ||
| /** | ||
| * Align two flat node collections by identity; emit missing/extra/mismatch issues in input order. | ||
| * Intentionally flat — child-node recursion is a separate follow-on concern (the relational port). | ||
| */ | ||
| function diffNodes(expected, actual) { | ||
| const expectedMap = /* @__PURE__ */ new Map(); | ||
| for (const node of expected) expectedMap.set(stableKey(node.identity()), node); | ||
| const actualMap = /* @__PURE__ */ new Map(); | ||
| for (const node of actual) actualMap.set(stableKey(node.identity()), node); | ||
| const issues = []; | ||
| for (const [key, expectedNode] of expectedMap) { | ||
| const actualNode = actualMap.get(key); | ||
| const coordinate = expectedNode.identity(); | ||
| if (actualNode === void 0) issues.push({ | ||
| coordinate, | ||
| outcome: "missing", | ||
| message: outcomeMessage("missing", coordinate), | ||
| expected: expectedNode | ||
| }); | ||
| else if (!expectedNode.isEqualTo(actualNode)) issues.push({ | ||
| coordinate, | ||
| outcome: "mismatch", | ||
| message: outcomeMessage("mismatch", coordinate), | ||
| expected: expectedNode, | ||
| actual: actualNode | ||
| }); | ||
| } | ||
| for (const [key, actualNode] of actualMap) if (!expectedMap.has(key)) { | ||
| const coordinate = actualNode.identity(); | ||
| issues.push({ | ||
| coordinate, | ||
| outcome: "extra", | ||
| message: outcomeMessage("extra", coordinate), | ||
| actual: actualNode | ||
| }); | ||
| } | ||
| return issues; | ||
| } | ||
| //#endregion | ||
| //#region src/control/verifier-disposition.ts | ||
@@ -320,4 +367,4 @@ /** | ||
| //#endregion | ||
| export { APP_SPACE_ID, SchemaTreeNode, VERIFY_CODE_HASH_MISMATCH, VERIFY_CODE_MARKER_MISSING, VERIFY_CODE_SCHEMA_FAILURE, VERIFY_CODE_TARGET_MISMATCH, assembleAuthoringContributions, assembleControlMutationDefaults, assembleScalarTypeDescriptors, assertUniqueCodecOwner, buildExtensionLoadOrder, createControlStack, dispositionForCategory, extractCodecLookup, extractCodecTypeImports, extractComponentIds, extractQueryOperationTypeImports, hasMigrations, hasOperationPreview, hasPslContractInfer, hasSchemaView }; | ||
| export { APP_SPACE_ID, SchemaTreeNode, VERIFY_CODE_HASH_MISMATCH, VERIFY_CODE_MARKER_MISSING, VERIFY_CODE_SCHEMA_FAILURE, VERIFY_CODE_TARGET_MISMATCH, assembleAuthoringContributions, assembleControlMutationDefaults, assembleScalarTypeDescriptors, assertUniqueCodecOwner, buildExtensionLoadOrder, createControlStack, diffNodes, dispositionForCategory, extractCodecLookup, extractCodecTypeImports, extractComponentIds, extractQueryOperationTypeImports, hasMigrations, hasOperationPreview, hasPslContractInfer, hasSchemaView }; | ||
| //# sourceMappingURL=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/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","export 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 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 { 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 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 // 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 };\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","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 { 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 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 // 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 };\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","import type { EntityCoordinate } from '../ir/storage';\n\nexport type SchemaDiffOutcome = 'missing' | 'extra' | 'mismatch';\n\nexport interface SchemaDiffIssue {\n readonly coordinate: EntityCoordinate;\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/** A node the generic differ can align and compare. Implemented by target IR nodes. */\nexport interface DiffableNode {\n identity(): EntityCoordinate;\n isEqualTo(other: DiffableNode): boolean;\n}\n\n/** Canonical string key for a coordinate. Uses pipe-separated fields so null bytes cannot appear. */\nfunction stableKey(c: EntityCoordinate): string {\n return `${c.plane}|${c.namespaceId}|${c.entityKind}|${c.entityName}`;\n}\n\nfunction outcomeMessage(outcome: SchemaDiffOutcome, c: EntityCoordinate): string {\n return `${outcome}: ${c.entityKind} '${c.entityName}' in namespace '${c.namespaceId}'`;\n}\n\n/**\n * Align two flat node collections by identity; emit missing/extra/mismatch issues in input order.\n * Intentionally flat — child-node recursion is a separate follow-on concern (the relational port).\n */\nexport function diffNodes(\n expected: readonly DiffableNode[],\n actual: readonly DiffableNode[],\n): readonly SchemaDiffIssue[] {\n const expectedMap = new Map<string, DiffableNode>();\n for (const node of expected) {\n expectedMap.set(stableKey(node.identity()), node);\n }\n\n const actualMap = new Map<string, DiffableNode>();\n for (const node of actual) {\n actualMap.set(stableKey(node.identity()), node);\n }\n\n const issues: SchemaDiffIssue[] = [];\n\n for (const [key, expectedNode] of expectedMap) {\n const actualNode = actualMap.get(key);\n const coordinate = expectedNode.identity();\n if (actualNode === undefined) {\n issues.push({\n coordinate,\n outcome: 'missing',\n message: outcomeMessage('missing', coordinate),\n expected: expectedNode,\n });\n } else if (!expectedNode.isEqualTo(actualNode)) {\n issues.push({\n coordinate,\n outcome: 'mismatch',\n message: outcomeMessage('mismatch', coordinate),\n expected: expectedNode,\n actual: actualNode,\n });\n }\n }\n\n for (const [key, actualNode] of actualMap) {\n if (!expectedMap.has(key)) {\n const coordinate = actualNode.identity();\n issues.push({\n coordinate,\n outcome: 'extra',\n message: outcomeMessage('extra', coordinate),\n actual: actualNode,\n });\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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"} |
+2
-208
@@ -1,211 +0,5 @@ | ||
| import { ApplicationDomain, StorageBase, StorageNamespace } from "@prisma-next/contract/types"; | ||
| import { isPlainRecord } from "@prisma-next/contract/is-plain-record"; | ||
| import { a as isPlainRecord, c as UNBOUND_NAMESPACE_ID, d as freezeNode, i as entityAt, l as IRNode, n as Storage, o as Namespace, r as elementCoordinates, s as NamespaceBase, t as EntityCoordinate, u as IRNodeBase } from "./storage-LiDzCDHm.mjs"; | ||
| import { ApplicationDomain } from "@prisma-next/contract/types"; | ||
| import { Type } from "arktype"; | ||
| //#region src/ir/ir-node.d.ts | ||
| /** | ||
| * Framework-level IR alphabet. | ||
| * | ||
| * The framework's contribution to Contract IR / Schema IR is a common | ||
| * root for the IR class hierarchy and a freeze affordance. Family | ||
| * abstract bases (e.g. `SqlNode`, `MongoSchemaIRNode`) refine the alphabet | ||
| * for their family shape; targets ship the concrete classes. | ||
| * | ||
| * `kind` is an optional discriminator on the base. Families and leaves | ||
| * that benefit from discriminated-union dispatch declare their own | ||
| * literal `kind` at the level that earns it — Mongo leaves carry | ||
| * per-class literals (`readonly kind = 'mongo-collection' as const`) | ||
| * because Mongo IR has polymorphic walkers; SQL declares a single | ||
| * family-level `kind = 'sql'` on `SqlNode` because SQL IR has no | ||
| * polymorphic dispatch today. No framework consumer dispatches on | ||
| * `IRNode.kind` at the BASE type — every dispatch site narrows | ||
| * through a union of leaves where each leaf carries a literal kind, so | ||
| * requiring `kind` at the base would be unearned. Future leaves that | ||
| * earn polymorphic dispatch override with a required literal at that | ||
| * leaf (e.g. `override readonly kind = 'pack-contributed-kind' as const`). | ||
| * | ||
| * `IRNodeBase` carries no methods: the freeze-and-assign affordance | ||
| * lives in the free `freezeNode` helper below. Keeping `freezeNode` out | ||
| * of the class type means an emitted contract literal type | ||
| * (`{ readonly kind: 'mongo-collection', ... }` or an unkeyed literal | ||
| * like `{ nativeType, codecId, nullable }`) is structurally assignable | ||
| * to its class type — a `protected freeze()` instance method would | ||
| * otherwise leak into the public type surface and require the literal | ||
| * to carry it too. | ||
| * | ||
| * Subclasses construct fields then call `freezeNode(this)` to seal the | ||
| * instance. Frozen instances + plain readonly fields keep IR nodes | ||
| * JSON-clean by construction, so `JSON.stringify(node)` produces canonical | ||
| * JSON without a `toJSON()` method. The `ContractSerializer` SPI handles | ||
| * round-trip from canonical JSON back to typed class instances. | ||
| * | ||
| * The name (`IRNode` / `IRNodeBase`) reflects the dual-hierarchy reality: | ||
| * this base is the common root for both Contract IR and Schema IR class | ||
| * hierarchies, not a Schema-IR-specific alphabet. | ||
| */ | ||
| interface IRNode { | ||
| readonly kind?: string; | ||
| } | ||
| declare abstract class IRNodeBase implements IRNode { | ||
| abstract readonly kind?: string; | ||
| } | ||
| /** | ||
| * Seal an IR class instance after its constructor has assigned all | ||
| * fields. The free-helper form (rather than a `protected freeze()` | ||
| * instance method) keeps the class type structurally narrow so emitted | ||
| * contract literal types remain assignable to their class types. | ||
| * | ||
| * The helper name stays `freezeNode` — it operates on IR nodes | ||
| * regardless of root naming. | ||
| */ | ||
| declare function freezeNode<T extends IRNode>(node: T): T; | ||
| //#endregion | ||
| //#region src/ir/namespace.d.ts | ||
| /** | ||
| * Reserved sentinel namespace id for the late-bound storage slot — | ||
| * the slot whose binding the target resolves at connection time | ||
| * rather than at authoring time. Postgres uses it for `search_path` | ||
| * late binding; SQLite uses it for the trivial singleton; Mongo uses | ||
| * it for the connection's `db` binding. | ||
| * | ||
| * Materialised target-side as a singleton subclass of the target's | ||
| * `NamespaceBase` concretion that overrides the namespace's | ||
| * qualifier-emission methods to elide the prefix entirely. Call sites | ||
| * stay polymorphic and never branch on `id === UNBOUND_NAMESPACE_ID` | ||
| * — the singleton's overrides drop the qualifier so emitted SQL / Mongo | ||
| * commands look unqualified. | ||
| * | ||
| * The double-underscore decoration marks the id as a framework-reserved | ||
| * coordinate when it appears in a JSON envelope (cold-read-as-reserved | ||
| * — no realistic collision with user-declared namespace names). | ||
| * | ||
| * Encoded as an exported const (rather than scattered string literals) | ||
| * so the sentinel-id invariant is single-sourced: any production-source | ||
| * site that constructs an unbound-namespace singleton imports this | ||
| * constant. | ||
| */ | ||
| declare const UNBOUND_NAMESPACE_ID: "__unbound__"; | ||
| /** | ||
| * Framework-level building block for a "namespace" — the database-level | ||
| * grouping under which storage objects (tables, collections, enums, …) | ||
| * reside. Each target's namespace concretion maps the framework concept to | ||
| * a target-native binding: | ||
| * | ||
| * - Postgres: a schema (`CREATE SCHEMA …`); rendered as `"<schema>"`. | ||
| * - SQLite: the singleton `UNBOUND_NAMESPACE_ID`; emitted SQL has no qualifier. | ||
| * - Mongo: the connection's `db` field; addressed as a database name. | ||
| * | ||
| * See `UNBOUND_NAMESPACE_ID` above for the sentinel id and the | ||
| * singleton-subclass pattern that materialises it. | ||
| * | ||
| * The framework promises only the coordinate (`id`) — the named storage | ||
| * entities a namespace contains are family-typed (SQL contributes | ||
| * `table` / `type`, Mongo contributes `collection`, future families pick | ||
| * their own native idiom under `entries`). Generic consumers walking "all | ||
| * named entries" go through a family-typed namespace, not the framework | ||
| * `Namespace`. | ||
| * | ||
| * Every namespace concretion (e.g. family-built SQL namespaces, | ||
| * `MongoUnboundNamespace`, target-promoted namespaces like | ||
| * `PostgresSchema`) carries exactly: `id` (enumerable string), | ||
| * `entries` (frozen object holding entity-kind slot maps), and `kind` | ||
| * (non-enumerable string discriminator set via `Object.defineProperty`). | ||
| * Each slot map under `entries` uses a singular essence key (`table`, | ||
| * `type`, `collection`, …) mapping entity names to IR classes. No other | ||
| * own-enumerable data lives on a namespace; non-entity computed data lives | ||
| * on the surrounding storage or contract IR. The framework's | ||
| * `elementCoordinates(storage)` walk relies on this invariant to enumerate | ||
| * entities structurally without family-specific knowledge. | ||
| */ | ||
| interface Namespace extends IRNode, StorageNamespace { | ||
| readonly kind: string; | ||
| readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>; | ||
| } | ||
| declare abstract class NamespaceBase extends IRNodeBase implements Namespace { | ||
| abstract readonly id: string; | ||
| abstract readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>; | ||
| abstract readonly kind: string; | ||
| } | ||
| //#endregion | ||
| //#region src/ir/storage.d.ts | ||
| /** | ||
| * Canonical address for a named entity in Contract IR / Schema IR. | ||
| * | ||
| * `plane` is `'domain' | 'storage'`: which top-level contract plane the | ||
| * entity lives on. Domain-side walks yield `plane: 'domain'` via | ||
| * {@link domainElementCoordinates}; {@link elementCoordinates} over storage | ||
| * yields `plane: 'storage'`. | ||
| * | ||
| * Cross-plane references obey a directional invariant: domain → storage is | ||
| * allowed; storage → domain is forbidden. That rule is enforced by a | ||
| * separate validator, not by constraining this coordinate shape — the | ||
| * coordinate carries the axis the validator checks. | ||
| * | ||
| * Iteration order over namespace properties follows `Object.entries` order; | ||
| * consumers that depend on ordering must sort. | ||
| */ | ||
| interface EntityCoordinate { | ||
| readonly plane: 'domain' | 'storage'; | ||
| readonly namespaceId: string; | ||
| readonly entityKind: string; | ||
| readonly entityName: string; | ||
| } | ||
| /** | ||
| * Lazy walk over every named storage entity in a `Storage`-shaped | ||
| * value, yielded as {@link EntityCoordinate} tuples with | ||
| * `plane: 'storage'` (the parameter type binds the plane). | ||
| * | ||
| * Iterates each namespace's `entries` kind maps structurally. Skips | ||
| * non-object `entries`; `id` and `kind` are not walked (`kind` is | ||
| * non-enumerable on concretions). For every entity-kind key under | ||
| * `entries` whose value is a non-null object, yields one coordinate per | ||
| * entity name in that map. No family-specific kind vocabulary is required. | ||
| */ | ||
| declare function elementCoordinates(storage: Pick<StorageBase, 'namespaces'>): Generator<EntityCoordinate>; | ||
| /** | ||
| * Looks up a single entity in a `Storage`-shaped value by its full coordinate. | ||
| * Returns `undefined` if the namespace, entity kind, or entity name is absent. | ||
| * The type parameter is a caller assertion — the walk itself is structural | ||
| * and cannot verify the entity's shape. | ||
| */ | ||
| declare function entityAt<T = unknown>(storage: Pick<StorageBase, 'namespaces'>, coord: Pick<EntityCoordinate, 'namespaceId' | 'entityKind' | 'entityName'>): T | undefined; | ||
| /** | ||
| * Framework-level promise that every Contract IR / Schema IR carries a | ||
| * collection of namespaces keyed by namespace id. Family storage | ||
| * concretions (`SqlStorage`, `MongoStorage`) refine the shape with | ||
| * family-specific fields (tables, collections, enums, …); target | ||
| * concretions add target fields where the family vocabulary doesn't | ||
| * reach. | ||
| * | ||
| * Keeping `namespaces` at the framework layer enforces that every storage | ||
| * object — across any target — is namespace-scoped. The framework can | ||
| * therefore walk the namespace map without knowing the family alphabet, and | ||
| * the `(namespace.id, name)` keying that the verifier and planner depend on | ||
| * is honest at every layer. | ||
| * | ||
| * Extends `IRNode` so the framework's IR-walking surfaces (verifiers, | ||
| * serializers) can dispatch on `Storage`-typed fields through the same | ||
| * IR-node alphabet as every other node — the structural dual already | ||
| * holds in code (every concrete storage class extends an IR-node base); | ||
| * the interface promotion makes the typing honest. | ||
| * | ||
| * **Persisted envelope shape is target-owned, not framework-promised.** | ||
| * Whether the `namespaces` map appears in the on-disk JSON envelope is | ||
| * a per-target decision made by `ContractSerializer.serializeContract`. | ||
| * Some targets emit a JSON-clean namespace shape that round-trips | ||
| * through `JSON.stringify` cleanly (SQL today via the family-layer | ||
| * identity serializer); others ship runtime-only fields on their | ||
| * namespace concretions and override `serializeContract` to strip | ||
| * them (Mongo). Future open (F16): extend the per-target | ||
| * `ContractSerializer` integration-test surface with an explicit | ||
| * envelope-shape assertion for each target, so the strip-vs-pass-through | ||
| * choice is locked at test time rather than implied by the override | ||
| * presence/absence. Earned by PR2's per-target namespace lift, when | ||
| * `PostgresSchema` / `SqliteUnboundDatabase` start carrying | ||
| * target-specific fields. | ||
| */ | ||
| interface Storage extends IRNode { | ||
| readonly namespaces: Readonly<Record<string, Namespace>>; | ||
| } | ||
| //#endregion | ||
| //#region src/ir/domain.d.ts | ||
@@ -212,0 +6,0 @@ /** |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/ir/ir-node.ts","../src/ir/namespace.ts","../src/ir/storage.ts","../src/ir/domain.ts","../src/ir/entity-kind.ts","../src/ir/storage-type.ts"],"mappings":";;;;;;;;;;AAyCA;;;;AACe;AAGf;;;;AACwB;AAYxB;;;;;;;;;;;;;;AAAwD;;;;AChCxD;;;;AAA0D;AAkC1D;;UDnBiB,MAAA;EAAA,SACN,IAAI;AAAA;AAAA,uBAGO,UAAA,YAAsB,MAAM;EAAA,kBAC9B,IAAI;AAAA;;;;;;;;;;iBAYR,UAAA,WAAqB,MAAA,EAAQ,IAAA,EAAM,CAAA,GAAI,CAAA;;;;;;AAjBvD;;;;AACe;AAGf;;;;AACwB;AAYxB;;;;;;;;;;cChCa,oBAAA;;;;ADgC2C;;;;AChCxD;;;;AAA0D;AAkC1D;;;;;;;;;;;;;;;;;;;;UAAiB,SAAA,SAAkB,MAAA,EAAQ,gBAAA;EAAA,SAChC,IAAA;EAAA,SACA,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA;AAAA;AAAA,uBAG/B,aAAA,SAAsB,UAAA,YAAsB,SAAA;EAAA,kBAC9C,EAAA;EAAA,kBACA,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA;EAAA,kBACjC,IAAA;AAAA;;;AD3B7B;;;;AACe;AAGf;;;;AACwB;AAYxB;;;;;;AAjBA,UEjBiB,gBAAA;EAAA,SACN,KAAA;EAAA,SACA,WAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA;AAAA;;;AF8B6C;;;;AChCxD;;;;AAA0D;iBCgBzC,kBAAA,CACf,OAAA,EAAS,IAAA,CAAK,WAAA,kBACb,SAAA,CAAU,gBAAA;;;;;;;iBAmBG,QAAA,cACd,OAAA,EAAS,IAAA,CAAK,WAAA,iBACd,KAAA,EAAO,IAAA,CAAK,gBAAA,iDACX,CAAA;;;;;;;;;;;;;ADJwD;AAG3D;;;;;;;;;;;;;;;;;;;;;AAGiC;UC8ChB,OAAA,SAAgB,MAAA;EAAA,SACtB,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,SAAA;AAAA;;;;;;AF1E/C;;;;iBG/BiB,wBAAA,CACf,MAAA,EAAQ,IAAA,CAAK,iBAAA,kBACZ,SAAA,CAAU,gBAAA;;;UCTI,oBAAA;EAAA,SACN,IAAA;EAAA,SAEA,MAAA,EAAQ,IAAA;EAAA,SACR,SAAA,GAAY,KAAA,EAAO,KAAA,KAAU,IAAA;AAAA;AAAA,KAG5B,uBAAA,GAA0B,oBAAoB;;;AJgC3C;AAGf;;;;AACwB;AAYxB;;;;iBIlCgB,wBAAA,CACd,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA,sBAC1C,KAAA,EAAO,WAAA,SAAoB,uBAAA,GAC3B,SAAA,oBACA,IAAA,YACC,MAAA,SAAe,QAAA,CAAS,MAAA;;;;;;;AJY3B;;;;AACe;AAGf;;;;AACwB;AAYxB;;;;UKtCiB,WAAA,SAAoB,MAAM;EAAA,SAChC,IAAI;AAAA"} | ||
| {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/ir/domain.ts","../src/ir/entity-kind.ts","../src/ir/storage-type.ts"],"mappings":";;;;;;;;AAUA;;;;iBAAiB,wBAAA,CACf,MAAA,EAAQ,IAAA,CAAK,iBAAA,kBACZ,SAAA,CAAU,gBAAA;;;UCTI,oBAAA;EAAA,SACN,IAAA;EAAA,SAEA,MAAA,EAAQ,IAAA;EAAA,SACR,SAAA,GAAY,KAAA,EAAO,KAAA,KAAU,IAAA;AAAA;AAAA,KAG5B,uBAAA,GAA0B,oBAAoB;;;;;;;;;;;;;iBAc1C,wBAAA,CACd,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA,sBAC1C,KAAA,EAAO,WAAA,SAAoB,uBAAA,GAC3B,SAAA,oBACA,IAAA,YACC,MAAA,SAAe,QAAA,CAAS,MAAA;;;;;;;ADnB3B;;;;;;;;;;;;;;UEUiB,WAAA,SAAoB,MAAM;EAAA,SAChC,IAAI;AAAA"} |
| import { r as CodecLookup } from "./codec-types-yY3eSmi0.mjs"; | ||
| import { B as PslExtensionBlockAttribute, F as PslBlockParamOption, G as PslExtensionBlockParamRef, H as PslExtensionBlockParamBare, I as PslBlockParamRef, J as PslPosition, K as PslExtensionBlockParamScalarValue, L as PslBlockParamValue, N as PslBlockParam, P as PslBlockParamList, R as PslDiagnosticCode, U as PslExtensionBlockParamList, V as PslExtensionBlockAttributeArg, W as PslExtensionBlockParamOption, Y as PslSpan, h as AuthoringPslBlockDescriptorNamespace, m as AuthoringPslBlockDescriptor, q as PslExtensionBlockParamValue, z as PslExtensionBlock } from "./framework-authoring-Di7Ug2bw.mjs"; | ||
| import { A as makePslNamespace, C as PslReferentialAction, D as UNSPECIFIED_PSL_NAMESPACE_ID, E as PslUniqueConstraint, M as namespacePslExtensionBlocks, O as flatPslCompositeTypes, S as PslNamespaceEntry, T as PslTypesBlock, _ as PslIndexConstraint, a as PslAttributeArgument, b as PslNamedTypeDeclaration, c as PslAttributeTarget, d as PslDefaultLiteralValue, f as PslDefaultValue, g as PslFieldAttribute, h as PslField, i as PslAttribute, j as makePslNamespaceEntries, k as flatPslModels, l as PslCompositeType, m as PslDocumentAst, n as ParsePslDocumentInput, o as PslAttributeNamedArgument, p as PslDiagnostic, r as ParsePslDocumentResult, s as PslAttributePositionalArgument, t as BUILTIN_PSL_KIND_KEYS, u as PslDefaultFunctionValue, v as PslModel, w as PslTypeConstructorCall, x as PslNamespace, y as PslModelAttribute } from "./psl-ast-CWkHgK17.mjs"; | ||
| import { A as makePslNamespace, C as PslReferentialAction, D as UNSPECIFIED_PSL_NAMESPACE_ID, E as PslUniqueConstraint, M as namespacePslExtensionBlocks, O as flatPslCompositeTypes, S as PslNamespaceEntry, T as PslTypesBlock, _ as PslIndexConstraint, a as PslAttributeArgument, b as PslNamedTypeDeclaration, c as PslAttributeTarget, d as PslDefaultLiteralValue, f as PslDefaultValue, g as PslFieldAttribute, h as PslField, i as PslAttribute, j as makePslNamespaceEntries, k as flatPslModels, l as PslCompositeType, m as PslDocumentAst, n as ParsePslDocumentInput, o as PslAttributeNamedArgument, p as PslDiagnostic, r as ParsePslDocumentResult, s as PslAttributePositionalArgument, t as BUILTIN_PSL_KIND_KEYS, u as PslDefaultFunctionValue, v as PslModel, w as PslTypeConstructorCall, x as PslNamespace, y as PslModelAttribute } from "./psl-ast-CiZNxGGb.mjs"; | ||
@@ -5,0 +5,0 @@ //#region src/control/psl-extension-block-validator.d.ts |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"psl-ast.mjs","names":[],"sources":["../src/control/psl-ast.ts","../src/control/psl-extension-block-validator.ts"],"sourcesContent":["export type { AuthoringPslBlockDescriptorNamespace } from '../shared/framework-authoring';\nexport type {\n PslBlockParam,\n PslBlockParamList,\n PslBlockParamOption,\n PslBlockParamRef,\n PslBlockParamValue,\n PslDiagnosticCode,\n PslExtensionBlock,\n PslExtensionBlockAttribute,\n PslExtensionBlockAttributeArg,\n PslExtensionBlockParamBare,\n PslExtensionBlockParamList,\n PslExtensionBlockParamOption,\n PslExtensionBlockParamRef,\n PslExtensionBlockParamScalarValue,\n PslExtensionBlockParamValue,\n PslPosition,\n PslSpan,\n} from '../shared/psl-extension-block';\n\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { CodecLookup } from '../shared/codec-types';\nimport type { AuthoringPslBlockDescriptorNamespace } from '../shared/framework-authoring';\nimport type { PslDiagnosticCode, PslExtensionBlock, PslSpan } from '../shared/psl-extension-block';\n\nexport interface PslDiagnostic {\n readonly code: PslDiagnosticCode;\n readonly message: string;\n readonly sourceId: string;\n readonly span: PslSpan;\n}\n\nexport interface PslDefaultFunctionValue {\n readonly kind: 'function';\n readonly name: 'autoincrement' | 'now';\n}\n\nexport interface PslDefaultLiteralValue {\n readonly kind: 'literal';\n readonly value: string | number | boolean;\n}\n\nexport type PslDefaultValue = PslDefaultFunctionValue | PslDefaultLiteralValue;\n\nexport type PslAttributeTarget = 'field' | 'model' | 'enum' | 'namedType';\n\nexport interface PslAttributePositionalArgument {\n readonly kind: 'positional';\n readonly value: string;\n readonly span: PslSpan;\n}\n\nexport interface PslAttributeNamedArgument {\n readonly kind: 'named';\n readonly name: string;\n readonly value: string;\n readonly span: PslSpan;\n}\n\nexport type PslAttributeArgument = PslAttributePositionalArgument | PslAttributeNamedArgument;\n\nexport interface PslTypeConstructorCall {\n readonly kind: 'typeConstructor';\n readonly path: readonly string[];\n readonly args: readonly PslAttributeArgument[];\n readonly span: PslSpan;\n}\n\nexport interface PslAttribute {\n readonly kind: 'attribute';\n readonly target: PslAttributeTarget;\n readonly name: string;\n readonly args: readonly PslAttributeArgument[];\n readonly span: PslSpan;\n}\n\nexport type PslReferentialAction = string;\n\nexport type PslFieldAttribute = PslAttribute;\n\nexport interface PslField {\n readonly kind: 'field';\n readonly name: string;\n /** Unqualified type name, e.g. `\"User\"` for both `User`, `auth.User`, and `supabase:auth.User`. */\n readonly typeName: string;\n /** Namespace qualifier from a dot-qualified type reference, e.g. `\"auth\"` for `auth.User` or `supabase:auth.User`. Absent for unqualified types. */\n readonly typeNamespaceId?: string;\n /**\n * Contract-space qualifier from a colon-prefix type reference, e.g. `\"supabase\"` for\n * `supabase:auth.User` or `supabase:User`. Absent for local (same-space) type references.\n *\n * When present, the field references a model from a different contract space. The namespace\n * (`typeNamespaceId`) and model name (`typeName`) identify the target within that space.\n * Physical table resolution against the extension contract is deferred to the aggregate stage (M3).\n */\n readonly typeContractSpaceId?: string;\n readonly typeConstructor?: PslTypeConstructorCall;\n readonly optional: boolean;\n readonly list: boolean;\n readonly typeRef?: string;\n readonly attributes: readonly PslFieldAttribute[];\n readonly span: PslSpan;\n}\n\nexport interface PslUniqueConstraint {\n readonly kind: 'unique';\n readonly fields: readonly string[];\n readonly span: PslSpan;\n}\n\nexport interface PslIndexConstraint {\n readonly kind: 'index';\n readonly fields: readonly string[];\n readonly span: PslSpan;\n}\n\nexport type PslModelAttribute = PslAttribute;\n\nexport interface PslModel {\n readonly kind: 'model';\n readonly name: string;\n readonly fields: readonly PslField[];\n readonly attributes: readonly PslModelAttribute[];\n readonly span: PslSpan;\n /**\n * Optional leading comment line emitted above the `model` keyword by the\n * printer. Producers (e.g. `sqlSchemaIrToPslAst`) attach introspection\n * advisories such as \"// WARNING: This table has no primary key in the\n * database\" here. The parser leaves this field unset; round-tripping a\n * parsed schema does not re-attach comments.\n */\n readonly comment?: string;\n}\n\n/**\n * A reusable group of fields embedded in a model (a `type Name { … }` block) —\n * e.g. a MongoDB embedded document or a Postgres composite type. Unlike\n * {@link PslModel} it has no storage or identity of its own.\n */\nexport interface PslCompositeType {\n readonly kind: 'compositeType';\n readonly name: string;\n readonly fields: readonly PslField[];\n readonly attributes: readonly PslAttribute[];\n readonly span: PslSpan;\n}\n\nexport interface PslNamedTypeDeclaration {\n readonly kind: 'namedType';\n readonly name: string;\n /**\n * Parser invariant: exactly one of `baseType` and `typeConstructor` is set.\n * Expressing this as a discriminated union trips TypeScript narrowing when\n * the declaration flows through helpers that accept the full union.\n */\n readonly baseType?: string;\n readonly typeConstructor?: PslTypeConstructorCall;\n readonly attributes: readonly PslAttribute[];\n readonly span: PslSpan;\n}\n\nexport interface PslTypesBlock {\n readonly kind: 'types';\n readonly declarations: readonly PslNamedTypeDeclaration[];\n readonly span: PslSpan;\n}\n\n/**\n * Name of the synthesised namespace bucket the framework parser uses for\n * top-level declarations that appear outside any `namespace { … }` block.\n * The double-underscore decoration signals that the identifier is parser-\n * synthesised and never appears in user-authored PSL source — writing\n * `namespace __unspecified__ { … }` is a parse error.\n *\n * Distinct from the IR sentinel `__unbound__`: the PSL bucket describes\n * syntactic absence at the parser layer; the IR sentinel describes a late-\n * bound storage slot at the IR layer. Per-target interpreters decide how\n * (or whether) to map the PSL bucket to the IR sentinel.\n */\nexport const UNSPECIFIED_PSL_NAMESPACE_ID = '__unspecified__';\n\n/** A value in {@link PslNamespace.entries}: a built-in entity node or an extension-contributed {@link PslExtensionBlock}. */\nexport type PslNamespaceEntry = PslModel | PslCompositeType | PslExtensionBlock;\n\n/**\n * A namespace block, or the parser's synthesised `__unspecified__` bucket for\n * declarations outside any `namespace { … }`. Same-name blocks reopen-merge;\n * `span` points at the first opening.\n *\n * Entities are stored canonically (ADR 224) in `entries[kind][name]`, where\n * `kind` is the PSL keyword for built-ins or the block discriminator for\n * extension kinds, e.g. `entries['policy_select']['ReadPosts']`.\n */\nexport interface PslNamespace {\n readonly kind: 'namespace';\n readonly name: string;\n /** Canonical store: a frozen container of frozen per-kind maps. The accessors below derive from it. */\n readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>;\n /** Built-in models, from `entries['model']`. Extension kinds: {@link namespacePslExtensionBlocks}. */\n readonly models: readonly PslModel[];\n /** Built-in composite types, from `entries['compositeType']`. */\n readonly compositeTypes: readonly PslCompositeType[];\n readonly span: PslSpan;\n}\n\n/**\n * Stores `entries`; exposes `models`/`enums`/`compositeTypes` as getters over\n * it. The getters are prototype members (non-enumerable), so spreading or\n * `JSON.stringify`-ing a namespace copies only `entries`, never a duplicate view.\n */\nclass PslNamespaceNode implements PslNamespace {\n readonly kind = 'namespace' as const;\n readonly name: string;\n readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>;\n readonly span: PslSpan;\n\n constructor(init: {\n readonly name: string;\n readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>;\n readonly span: PslSpan;\n }) {\n this.name = init.name;\n this.entries = init.entries;\n this.span = init.span;\n Object.freeze(this);\n }\n\n get models(): readonly PslModel[] {\n return blindCast<readonly PslModel[], 'entries[model] holds only PslModel by construction'>(\n Object.values(this.entries['model'] ?? {}),\n );\n }\n\n get compositeTypes(): readonly PslCompositeType[] {\n return blindCast<\n readonly PslCompositeType[],\n 'entries[compositeType] holds only PslCompositeType by construction'\n >(Object.values(this.entries['compositeType'] ?? {}));\n }\n}\n\n/** Constructs a {@link PslNamespace}. Use this, never a namespace literal — the accessors must derive from `entries`. */\nexport function makePslNamespace(init: {\n readonly kind: 'namespace';\n readonly name: string;\n readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>;\n readonly span: PslSpan;\n}): PslNamespace {\n return new PslNamespaceNode(init);\n}\n\n/**\n * Builds the frozen `entries[kind][name]` container from per-kind arrays.\n * Built-ins key on their PSL keyword; extension blocks key on their `kind`\n * discriminator. Call this rather than hand-building the literal.\n */\nexport function makePslNamespaceEntries(\n models: readonly PslModel[],\n compositeTypes: readonly PslCompositeType[],\n extensionBlocks: readonly PslExtensionBlock[],\n): Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>> {\n const container: Record<string, Readonly<Record<string, PslNamespaceEntry>>> = {};\n\n if (models.length > 0) {\n const map: Record<string, PslModel> = {};\n for (const m of models) {\n map[m.name] = m;\n }\n container['model'] = Object.freeze(map);\n }\n\n if (compositeTypes.length > 0) {\n const map: Record<string, PslCompositeType> = {};\n for (const ct of compositeTypes) {\n map[ct.name] = ct;\n }\n container['compositeType'] = Object.freeze(map);\n }\n\n for (const block of extensionBlocks) {\n const existing = container[block.kind];\n const newMap: Record<string, PslExtensionBlock> = existing\n ? blindCast<Record<string, PslExtensionBlock>, 'kind map holds only PslExtensionBlock'>({\n ...existing,\n })\n : {};\n newMap[block.name] = block;\n container[block.kind] = Object.freeze(newMap);\n }\n\n return Object.freeze(container);\n}\n\nexport interface PslDocumentAst {\n readonly kind: 'document';\n readonly sourceId: string;\n readonly namespaces: readonly PslNamespace[];\n readonly types?: PslTypesBlock;\n readonly span: PslSpan;\n}\n\n/**\n * Returns all models from every namespace in document order. Convenience\n * for consumers that don't (yet) need namespace-awareness.\n */\nexport function flatPslModels(ast: PslDocumentAst): readonly PslModel[] {\n return ast.namespaces.flatMap((ns) =>\n blindCast<PslModel[], 'model kind map contains only PslModel by construction'>(\n Object.values(ns.entries['model'] ?? {}),\n ),\n );\n}\n\n/**\n * Returns all composite types from every namespace in document order.\n */\nexport function flatPslCompositeTypes(ast: PslDocumentAst): readonly PslCompositeType[] {\n return ast.namespaces.flatMap((ns) =>\n blindCast<\n PslCompositeType[],\n 'compositeType kind map contains only PslCompositeType by construction'\n >(Object.values(ns.entries['compositeType'] ?? {})),\n );\n}\n\n/**\n * The set of `entries` kind keys that the framework parser reserves for\n * built-in PSL entity kinds. Any own-enumerable key on `PslNamespace.entries`\n * that is **not** in this set was contributed by an extension-block descriptor.\n *\n * Built-in keys match the PSL keyword used on each block type:\n * `'model'`, `'compositeType'`. The `'enum'` keyword is claimed by the\n * extension-block grammar via a registered descriptor, so `entries['enum']`\n * holds `PslExtensionBlock` nodes and is returned by `namespacePslExtensionBlocks`.\n */\nexport const BUILTIN_PSL_KIND_KEYS: ReadonlySet<string> = new Set(['model', 'compositeType']);\n\n/**\n * Returns all extension-contributed blocks in the given namespace, in\n * insertion order (the order the parser encountered them in the source).\n *\n * Reads from `namespace.entries`, skipping the built-in kind keys\n * (`'model'`, `'compositeType'`). All remaining kind maps contain\n * only `PslExtensionBlock` nodes by construction (see `makePslNamespaceEntries`).\n */\nexport function namespacePslExtensionBlocks(ns: PslNamespace): readonly PslExtensionBlock[] {\n const result: PslExtensionBlock[] = [];\n for (const [kindKey, kindMap] of Object.entries(ns.entries)) {\n if (BUILTIN_PSL_KIND_KEYS.has(kindKey)) continue;\n for (const entry of Object.values(kindMap)) {\n result.push(\n blindCast<\n PslExtensionBlock,\n 'non-builtin kind maps contain only PslExtensionBlock by construction'\n >(entry),\n );\n }\n }\n return result;\n}\n\nexport interface ParsePslDocumentInput {\n readonly schema: string;\n readonly sourceId: string;\n /**\n * Registry of declarative block descriptors, keyed by arbitrary path\n * segments with {@link AuthoringPslBlockDescriptor} leaves. The registry\n * teaches the parser which top-level keywords belong to extension\n * contributions: when the parser encounters an unknown keyword, it looks\n * it up here and, when found, reads the block generically into a\n * {@link PslExtensionBlock} node. Absent or undefined means no extension\n * blocks are registered and any unknown keyword yields\n * `PSL_UNSUPPORTED_TOP_LEVEL_BLOCK`.\n *\n * Contrast with the parsed block nodes themselves, which live in\n * {@link PslNamespace.entries} under their discriminator key (read them with\n * {@link namespacePslExtensionBlocks}); this field holds the registry of\n * descriptors that teach the parser how to read those blocks.\n */\n readonly pslBlockDescriptors?: AuthoringPslBlockDescriptorNamespace;\n /**\n * Codec lookup for validating `value`-kind extension block parameters.\n * When provided alongside `pslBlockDescriptors`, the generic validator runs\n * over every parsed extension block after the full AST is assembled,\n * appending any diagnostics to the parse result. Absent or undefined means\n * no codec validation runs; `ref` resolution still runs when namespace\n * context is available (built from the assembled namespaces).\n */\n readonly codecLookup?: CodecLookup;\n}\n\nexport interface ParsePslDocumentResult {\n readonly ast: PslDocumentAst;\n readonly diagnostics: readonly PslDiagnostic[];\n readonly ok: boolean;\n}\n","/**\n * Generic validator for extension-contributed top-level PSL blocks.\n *\n * One function — {@link validateExtensionBlock} — takes a parsed\n * {@link PslExtensionBlock}, its {@link AuthoringPslBlockDescriptor}, a\n * {@link CodecLookup} (for `value` parameters), and the set of\n * {@link PslNamespace} objects from the document (for `ref` resolution), and\n * returns the full list of {@link PslDiagnostic} objects for the block.\n *\n * Detection logic per failure mode:\n *\n * 1. **Unknown parameter** — keys present in `node.parameters` that are absent\n * from `descriptor.parameters` (key-set difference). The parser stores\n * unknown parameters as `kind:'value'` stubs; the validator discovers them\n * by comparing the key sets, not by inspecting the captured kind.\n *\n * 2. **Missing required parameter** — `descriptor.parameters` entries with\n * `required: true` whose key is absent from `node.parameters`.\n *\n * 3. **`option` value outside its set** — the captured `token` is not in\n * `descriptor.values`.\n *\n * 4. **`value` rejected by its codec** — the raw string is first parsed as\n * JSON (`JSON.parse(raw)`). If `JSON.parse` throws, the literal is not valid\n * JSON and a `PSL_EXTENSION_INVALID_VALUE` diagnostic is emitted. If parsing\n * succeeds but `codec.decodeJson(jsonValue)` throws, the JSON value is not\n * acceptable to the codec and a `PSL_EXTENSION_INVALID_VALUE` diagnostic is\n * emitted. If `codecLookup.get(codecId)` returns `undefined` (unknown codec\n * id), a `PSL_EXTENSION_INVALID_VALUE` diagnostic is also emitted.\n *\n * 5. **`ref` that does not resolve within its scope** — the captured\n * `identifier` is looked up in the PSL document's `PslNamespace` objects\n * according to `param.scope`:\n * - `same-namespace`: the referent must be in the same namespace as the\n * block (the namespace containing the block).\n * - `same-space`: the referent may be in any namespace in the document.\n * - `cross-space`: pass-through — enforcement is scoped to first-consumer\n * need (RLS roles). This case is documented and clearly flagged; the\n * caller is responsible for wiring cross-space resolution when needed.\n *\n * 6. **`list`** — each element is validated against `param.of` recursively.\n *\n * ### `char`/`varchar` length\n * Not enforced. RLS `using`/`check` strings are unbounded text and the codec\n * already rejects structurally invalid literals; length constraints are a\n * database-side concern, not a PSL authoring constraint.\n *\n * ### `cross-space` scope\n * Implemented as a documented pass-through. The spec permits scoping\n * cross-space enforcement to first-consumer need (RLS roles). When RLS roles\n * arrive, wire `cross-space` resolution through the cross-contract-space\n * coordinate model `(spaceId, namespaceId, entityKind, entityName)`.\n */\n\nimport type { JsonValue } from '@prisma-next/contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { CodecLookup } from '../shared/codec-types';\nimport type { AuthoringPslBlockDescriptor } from '../shared/framework-authoring';\nimport type {\n PslBlockParam,\n PslBlockParamRef,\n PslExtensionBlock,\n PslExtensionBlockParamValue,\n PslSpan,\n} from '../shared/psl-extension-block';\nimport type { PslDiagnostic, PslNamespace } from './psl-ast';\n\n/**\n * Context for ref resolution during extension-block validation.\n *\n * - `ownerNamespace` is the `PslNamespace` that contains the block being\n * validated. Used for `same-namespace` scope checks.\n * - `allNamespaces` is every namespace in the document. Used for `same-space`\n * scope checks.\n */\nexport interface ExtensionBlockRefResolutionContext {\n readonly ownerNamespace: PslNamespace;\n readonly allNamespaces: readonly PslNamespace[];\n}\n\n/**\n * Validate a single parsed extension block against its descriptor.\n *\n * Returns an array of {@link PslDiagnostic} objects (possibly empty). The\n * caller is responsible for threading `sourceId` into each returned diagnostic\n * — the returned objects already have `sourceId` set from the `sourceId`\n * parameter.\n *\n * @param node - The parsed block node produced by the generic framework parser.\n * @param descriptor - The descriptor that claims this block's keyword.\n * @param sourceId - The PSL source file identifier (threaded into diagnostics).\n * @param codecLookup - Used to validate `value`-kind parameter literals via\n * `codecLookup.get(codecId)?.decodeJson(JSON.parse(raw))`.\n * @param refCtx - Namespace context for `ref`-kind scope resolution. Required\n * when any descriptor parameter is `kind: 'ref'`; may be omitted if none are.\n */\nexport function validateExtensionBlock(\n node: PslExtensionBlock,\n descriptor: AuthoringPslBlockDescriptor,\n sourceId: string,\n codecLookup: CodecLookup,\n refCtx?: ExtensionBlockRefResolutionContext,\n): readonly PslDiagnostic[] {\n const diagnostics: PslDiagnostic[] = [];\n\n const descriptorKeys = new Set(Object.keys(descriptor.parameters));\n const nodeKeys = new Set(Object.keys(node.parameters));\n\n // 1. Unknown parameters — keys in the node not in the descriptor.\n if (!descriptor.variadicParameters) {\n for (const key of nodeKeys) {\n if (!descriptorKeys.has(key)) {\n const captured = node.parameters[key];\n diagnostics.push({\n code: 'PSL_EXTENSION_UNKNOWN_PARAMETER',\n message: `Unknown parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\". The descriptor does not declare this parameter.`,\n sourceId,\n span: captured?.span ?? node.span,\n });\n }\n }\n }\n\n // 2. Missing required parameters — required descriptor keys absent from the node.\n for (const [key, param] of Object.entries(descriptor.parameters)) {\n if (param.required === true && !nodeKeys.has(key)) {\n diagnostics.push({\n code: 'PSL_EXTENSION_MISSING_REQUIRED_PARAMETER',\n message: `Required parameter \"${key}\" is missing from \"${descriptor.keyword}\" block \"${node.name}\".`,\n sourceId,\n span: node.span,\n });\n }\n }\n\n // 3–5. Per-parameter validation for parameters that are present.\n for (const [key, param] of Object.entries(descriptor.parameters)) {\n const captured = node.parameters[key];\n if (captured === undefined) {\n continue;\n }\n validateParam(\n node,\n descriptor,\n key,\n param,\n captured,\n sourceId,\n codecLookup,\n refCtx,\n diagnostics,\n );\n }\n\n return diagnostics;\n}\n\nfunction validateParam(\n node: PslExtensionBlock,\n descriptor: AuthoringPslBlockDescriptor,\n key: string,\n param: PslBlockParam,\n captured: PslExtensionBlockParamValue,\n sourceId: string,\n codecLookup: CodecLookup,\n refCtx: ExtensionBlockRefResolutionContext | undefined,\n diagnostics: PslDiagnostic[],\n): void {\n switch (param.kind) {\n case 'option': {\n if (captured.kind !== 'option') {\n return;\n }\n if (!param.values.includes(captured.token)) {\n diagnostics.push({\n code: 'PSL_EXTENSION_OPTION_OUT_OF_SET',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" has value \"${captured.token}\" which is not one of the allowed values: ${param.values.map((v) => `\"${v}\"`).join(', ')}.`,\n sourceId,\n span: captured.span,\n });\n }\n return;\n }\n\n case 'value': {\n if (captured.kind !== 'value') {\n return;\n }\n const codec = codecLookup.get(param.codecId);\n if (codec === undefined) {\n diagnostics.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" references unknown codec \"${param.codecId}\".`,\n sourceId,\n span: captured.span,\n });\n return;\n }\n let jsonValue: unknown;\n try {\n jsonValue = JSON.parse(captured.raw);\n } catch {\n diagnostics.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" is not a valid JSON literal (expected a JSON string, number, boolean, or null): ${captured.raw}`,\n sourceId,\n span: captured.span,\n });\n return;\n }\n try {\n codec.decodeJson(\n blindCast<JsonValue, 'JSON.parse returns a JsonValue-compatible value'>(jsonValue),\n );\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n diagnostics.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" was rejected by codec \"${param.codecId}\": ${reason}`,\n sourceId,\n span: captured.span,\n });\n }\n return;\n }\n\n case 'ref': {\n if (captured.kind !== 'ref') {\n return;\n }\n validateRef(\n node,\n descriptor,\n key,\n param,\n captured.identifier,\n captured.span,\n sourceId,\n refCtx,\n diagnostics,\n );\n return;\n }\n\n case 'list': {\n if (captured.kind !== 'list') {\n return;\n }\n for (const item of captured.items) {\n validateParam(\n node,\n descriptor,\n key,\n param.of,\n item,\n sourceId,\n codecLookup,\n refCtx,\n diagnostics,\n );\n }\n return;\n }\n }\n}\n\nfunction validateRef(\n node: PslExtensionBlock,\n descriptor: AuthoringPslBlockDescriptor,\n key: string,\n param: PslBlockParamRef,\n identifier: string,\n span: PslSpan,\n sourceId: string,\n refCtx: ExtensionBlockRefResolutionContext | undefined,\n diagnostics: PslDiagnostic[],\n): void {\n if (param.scope === 'cross-space') {\n // cross-space enforcement is a documented pass-through. The spec permits\n // scoping cross-space resolution to first-consumer need (RLS roles). When\n // that consumer arrives, wire resolution here through the\n // cross-contract-space coordinate model\n // (spaceId, namespaceId, entityKind, entityName).\n // For now, cross-space refs pass validation unconditionally.\n return;\n }\n\n if (refCtx === undefined) {\n // If no resolution context was provided, skip ref resolution. This matches\n // the closed-grammar invariant: callers that register ref parameters must\n // provide resolution context; callers without namespaces (e.g. unit tests\n // that only exercise other validation modes) can omit it.\n return;\n }\n\n const namespacesToSearch: readonly PslNamespace[] =\n param.scope === 'same-namespace' ? [refCtx.ownerNamespace] : refCtx.allNamespaces;\n\n if (!resolveEntityInNamespaces(identifier, param.refKind, namespacesToSearch)) {\n const scopeLabel =\n param.scope === 'same-namespace' ? 'the same namespace' : 'any namespace in the schema';\n diagnostics.push({\n code: 'PSL_EXTENSION_UNRESOLVED_REF',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" refers to \"${identifier}\" (expected ${param.refKind}), but no entity with that name and kind was found in ${scopeLabel}.`,\n sourceId,\n span,\n });\n }\n}\n\n/**\n * True if an entity named `name` of kind `refKind` exists in any of the given\n * namespaces. Built-in and extension kinds resolve the same way, through\n * `entries[refKind]`.\n */\nfunction resolveEntityInNamespaces(\n name: string,\n refKind: string,\n namespaces: readonly PslNamespace[],\n): boolean {\n for (const ns of namespaces) {\n const kindMap = ns.entries[refKind];\n if (kindMap !== undefined && Object.hasOwn(kindMap, name)) return true;\n }\n return false;\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"psl-ast.mjs","names":[],"sources":["../src/control/psl-ast.ts","../src/control/psl-extension-block-validator.ts"],"sourcesContent":["export type { AuthoringPslBlockDescriptorNamespace } from '../shared/framework-authoring';\nexport type {\n PslBlockParam,\n PslBlockParamList,\n PslBlockParamOption,\n PslBlockParamRef,\n PslBlockParamValue,\n PslDiagnosticCode,\n PslExtensionBlock,\n PslExtensionBlockAttribute,\n PslExtensionBlockAttributeArg,\n PslExtensionBlockParamBare,\n PslExtensionBlockParamList,\n PslExtensionBlockParamOption,\n PslExtensionBlockParamRef,\n PslExtensionBlockParamScalarValue,\n PslExtensionBlockParamValue,\n PslPosition,\n PslSpan,\n} from '../shared/psl-extension-block';\n\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { CodecLookup } from '../shared/codec-types';\nimport type { AuthoringPslBlockDescriptorNamespace } from '../shared/framework-authoring';\nimport type { PslDiagnosticCode, PslExtensionBlock, PslSpan } from '../shared/psl-extension-block';\n\nexport interface PslDiagnostic {\n readonly code: PslDiagnosticCode;\n readonly message: string;\n readonly sourceId: string;\n readonly span: PslSpan;\n}\n\nexport interface PslDefaultFunctionValue {\n readonly kind: 'function';\n readonly name: 'autoincrement' | 'now';\n}\n\nexport interface PslDefaultLiteralValue {\n readonly kind: 'literal';\n readonly value: string | number | boolean;\n}\n\nexport type PslDefaultValue = PslDefaultFunctionValue | PslDefaultLiteralValue;\n\nexport type PslAttributeTarget = 'field' | 'model' | 'enum' | 'namedType';\n\nexport interface PslAttributePositionalArgument {\n readonly kind: 'positional';\n readonly value: string;\n readonly span: PslSpan;\n}\n\nexport interface PslAttributeNamedArgument {\n readonly kind: 'named';\n readonly name: string;\n readonly value: string;\n readonly span: PslSpan;\n}\n\nexport type PslAttributeArgument = PslAttributePositionalArgument | PslAttributeNamedArgument;\n\nexport interface PslTypeConstructorCall {\n readonly kind: 'typeConstructor';\n readonly path: readonly string[];\n readonly args: readonly PslAttributeArgument[];\n readonly span: PslSpan;\n}\n\nexport interface PslAttribute {\n readonly kind: 'attribute';\n readonly target: PslAttributeTarget;\n readonly name: string;\n readonly args: readonly PslAttributeArgument[];\n readonly span: PslSpan;\n}\n\nexport type PslReferentialAction = string;\n\nexport type PslFieldAttribute = PslAttribute;\n\nexport interface PslField {\n readonly kind: 'field';\n readonly name: string;\n /** Unqualified type name, e.g. `\"User\"` for both `User`, `auth.User`, and `supabase:auth.User`. */\n readonly typeName: string;\n /** Namespace qualifier from a dot-qualified type reference, e.g. `\"auth\"` for `auth.User` or `supabase:auth.User`. Absent for unqualified types. */\n readonly typeNamespaceId?: string;\n /**\n * Contract-space qualifier from a colon-prefix type reference, e.g. `\"supabase\"` for\n * `supabase:auth.User` or `supabase:User`. Absent for local (same-space) type references.\n *\n * When present, the field references a model from a different contract space. The namespace\n * (`typeNamespaceId`) and model name (`typeName`) identify the target within that space.\n * Physical table resolution against the extension contract is deferred to the aggregate stage (M3).\n */\n readonly typeContractSpaceId?: string;\n readonly typeConstructor?: PslTypeConstructorCall;\n readonly optional: boolean;\n readonly list: boolean;\n readonly typeRef?: string;\n readonly attributes: readonly PslFieldAttribute[];\n readonly span: PslSpan;\n}\n\nexport interface PslUniqueConstraint {\n readonly kind: 'unique';\n readonly fields: readonly string[];\n readonly span: PslSpan;\n}\n\nexport interface PslIndexConstraint {\n readonly kind: 'index';\n readonly fields: readonly string[];\n readonly span: PslSpan;\n}\n\nexport type PslModelAttribute = PslAttribute;\n\nexport interface PslModel {\n readonly kind: 'model';\n readonly name: string;\n readonly fields: readonly PslField[];\n readonly attributes: readonly PslModelAttribute[];\n readonly span: PslSpan;\n /**\n * Optional leading comment line emitted above the `model` keyword by the\n * printer. Producers (e.g. `sqlSchemaIrToPslAst`) attach introspection\n * advisories such as \"// WARNING: This table has no primary key in the\n * database\" here. The parser leaves this field unset; round-tripping a\n * parsed schema does not re-attach comments.\n */\n readonly comment?: string;\n}\n\n/**\n * A reusable group of fields embedded in a model (a `type Name { … }` block) —\n * e.g. a MongoDB embedded document or a Postgres composite type. Unlike\n * {@link PslModel} it has no storage or identity of its own.\n */\nexport interface PslCompositeType {\n readonly kind: 'compositeType';\n readonly name: string;\n readonly fields: readonly PslField[];\n readonly attributes: readonly PslAttribute[];\n readonly span: PslSpan;\n}\n\nexport interface PslNamedTypeDeclaration {\n readonly kind: 'namedType';\n readonly name: string;\n /**\n * Parser invariant: exactly one of `baseType` and `typeConstructor` is set.\n * Expressing this as a discriminated union trips TypeScript narrowing when\n * the declaration flows through helpers that accept the full union.\n */\n readonly baseType?: string;\n readonly typeConstructor?: PslTypeConstructorCall;\n readonly attributes: readonly PslAttribute[];\n readonly span: PslSpan;\n}\n\nexport interface PslTypesBlock {\n readonly kind: 'types';\n readonly declarations: readonly PslNamedTypeDeclaration[];\n readonly span: PslSpan;\n}\n\n/**\n * Name of the synthesised namespace bucket the framework parser uses for\n * top-level declarations that appear outside any `namespace { … }` block.\n * The double-underscore decoration signals that the identifier is parser-\n * synthesised and never appears in user-authored PSL source — writing\n * `namespace __unspecified__ { … }` is a parse error.\n *\n * Distinct from the IR sentinel `__unbound__`: the PSL bucket describes\n * syntactic absence at the parser layer; the IR sentinel describes a late-\n * bound storage slot at the IR layer. Per-target interpreters decide how\n * (or whether) to map the PSL bucket to the IR sentinel.\n */\nexport const UNSPECIFIED_PSL_NAMESPACE_ID = '__unspecified__';\n\n/** A value in {@link PslNamespace.entries}: a built-in entity node or an extension-contributed {@link PslExtensionBlock}. */\nexport type PslNamespaceEntry = PslModel | PslCompositeType | PslExtensionBlock;\n\n/**\n * A namespace block, or the parser's synthesised `__unspecified__` bucket for\n * declarations outside any `namespace { … }`. Same-name blocks reopen-merge;\n * `span` points at the first opening.\n *\n * Entities are stored canonically (ADR 224) in `entries[kind][name]`, where\n * `kind` is the PSL keyword for built-ins or the block discriminator for\n * extension kinds, e.g. `entries['policy']['ReadPosts']` (the discriminator,\n * not the PSL keyword — a `policy_select` block lands under `'policy'` per\n * ADR 225).\n */\nexport interface PslNamespace {\n readonly kind: 'namespace';\n readonly name: string;\n /** Canonical store: a frozen container of frozen per-kind maps. The accessors below derive from it. */\n readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>;\n /** Built-in models, from `entries['model']`. Extension kinds: {@link namespacePslExtensionBlocks}. */\n readonly models: readonly PslModel[];\n /** Built-in composite types, from `entries['compositeType']`. */\n readonly compositeTypes: readonly PslCompositeType[];\n readonly span: PslSpan;\n}\n\n/**\n * Stores `entries`; exposes `models`/`enums`/`compositeTypes` as getters over\n * it. The getters are prototype members (non-enumerable), so spreading or\n * `JSON.stringify`-ing a namespace copies only `entries`, never a duplicate view.\n */\nclass PslNamespaceNode implements PslNamespace {\n readonly kind = 'namespace' as const;\n readonly name: string;\n readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>;\n readonly span: PslSpan;\n\n constructor(init: {\n readonly name: string;\n readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>;\n readonly span: PslSpan;\n }) {\n this.name = init.name;\n this.entries = init.entries;\n this.span = init.span;\n Object.freeze(this);\n }\n\n get models(): readonly PslModel[] {\n return blindCast<readonly PslModel[], 'entries[model] holds only PslModel by construction'>(\n Object.values(this.entries['model'] ?? {}),\n );\n }\n\n get compositeTypes(): readonly PslCompositeType[] {\n return blindCast<\n readonly PslCompositeType[],\n 'entries[compositeType] holds only PslCompositeType by construction'\n >(Object.values(this.entries['compositeType'] ?? {}));\n }\n}\n\n/** Constructs a {@link PslNamespace}. Use this, never a namespace literal — the accessors must derive from `entries`. */\nexport function makePslNamespace(init: {\n readonly kind: 'namespace';\n readonly name: string;\n readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>;\n readonly span: PslSpan;\n}): PslNamespace {\n return new PslNamespaceNode(init);\n}\n\n/**\n * Builds the frozen `entries[kind][name]` container from per-kind arrays.\n * Built-ins key on their PSL keyword; extension blocks key on their `kind`\n * discriminator. Call this rather than hand-building the literal.\n */\nexport function makePslNamespaceEntries(\n models: readonly PslModel[],\n compositeTypes: readonly PslCompositeType[],\n extensionBlocks: readonly PslExtensionBlock[],\n): Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>> {\n const container: Record<string, Readonly<Record<string, PslNamespaceEntry>>> = {};\n\n if (models.length > 0) {\n const map: Record<string, PslModel> = {};\n for (const m of models) {\n map[m.name] = m;\n }\n container['model'] = Object.freeze(map);\n }\n\n if (compositeTypes.length > 0) {\n const map: Record<string, PslCompositeType> = {};\n for (const ct of compositeTypes) {\n map[ct.name] = ct;\n }\n container['compositeType'] = Object.freeze(map);\n }\n\n for (const block of extensionBlocks) {\n const existing = container[block.kind];\n const newMap: Record<string, PslExtensionBlock> = existing\n ? blindCast<Record<string, PslExtensionBlock>, 'kind map holds only PslExtensionBlock'>({\n ...existing,\n })\n : {};\n newMap[block.name] = block;\n container[block.kind] = Object.freeze(newMap);\n }\n\n return Object.freeze(container);\n}\n\nexport interface PslDocumentAst {\n readonly kind: 'document';\n readonly sourceId: string;\n readonly namespaces: readonly PslNamespace[];\n readonly types?: PslTypesBlock;\n readonly span: PslSpan;\n}\n\n/**\n * Returns all models from every namespace in document order. Convenience\n * for consumers that don't (yet) need namespace-awareness.\n */\nexport function flatPslModels(ast: PslDocumentAst): readonly PslModel[] {\n return ast.namespaces.flatMap((ns) =>\n blindCast<PslModel[], 'model kind map contains only PslModel by construction'>(\n Object.values(ns.entries['model'] ?? {}),\n ),\n );\n}\n\n/**\n * Returns all composite types from every namespace in document order.\n */\nexport function flatPslCompositeTypes(ast: PslDocumentAst): readonly PslCompositeType[] {\n return ast.namespaces.flatMap((ns) =>\n blindCast<\n PslCompositeType[],\n 'compositeType kind map contains only PslCompositeType by construction'\n >(Object.values(ns.entries['compositeType'] ?? {})),\n );\n}\n\n/**\n * The set of `entries` kind keys that the framework parser reserves for\n * built-in PSL entity kinds. Any own-enumerable key on `PslNamespace.entries`\n * that is **not** in this set was contributed by an extension-block descriptor.\n *\n * Built-in keys match the PSL keyword used on each block type:\n * `'model'`, `'compositeType'`. The `'enum'` keyword is claimed by the\n * extension-block grammar via a registered descriptor, so `entries['enum']`\n * holds `PslExtensionBlock` nodes and is returned by `namespacePslExtensionBlocks`.\n */\nexport const BUILTIN_PSL_KIND_KEYS: ReadonlySet<string> = new Set(['model', 'compositeType']);\n\n/**\n * Returns all extension-contributed blocks in the given namespace, in\n * insertion order (the order the parser encountered them in the source).\n *\n * Reads from `namespace.entries`, skipping the built-in kind keys\n * (`'model'`, `'compositeType'`). All remaining kind maps contain\n * only `PslExtensionBlock` nodes by construction (see `makePslNamespaceEntries`).\n */\nexport function namespacePslExtensionBlocks(ns: PslNamespace): readonly PslExtensionBlock[] {\n const result: PslExtensionBlock[] = [];\n for (const [kindKey, kindMap] of Object.entries(ns.entries)) {\n if (BUILTIN_PSL_KIND_KEYS.has(kindKey)) continue;\n for (const entry of Object.values(kindMap)) {\n result.push(\n blindCast<\n PslExtensionBlock,\n 'non-builtin kind maps contain only PslExtensionBlock by construction'\n >(entry),\n );\n }\n }\n return result;\n}\n\nexport interface ParsePslDocumentInput {\n readonly schema: string;\n readonly sourceId: string;\n /**\n * Registry of declarative block descriptors, keyed by arbitrary path\n * segments with {@link AuthoringPslBlockDescriptor} leaves. The registry\n * teaches the parser which top-level keywords belong to extension\n * contributions: when the parser encounters an unknown keyword, it looks\n * it up here and, when found, reads the block generically into a\n * {@link PslExtensionBlock} node. Absent or undefined means no extension\n * blocks are registered and any unknown keyword yields\n * `PSL_UNSUPPORTED_TOP_LEVEL_BLOCK`.\n *\n * Contrast with the parsed block nodes themselves, which live in\n * {@link PslNamespace.entries} under their discriminator key (read them with\n * {@link namespacePslExtensionBlocks}); this field holds the registry of\n * descriptors that teach the parser how to read those blocks.\n */\n readonly pslBlockDescriptors?: AuthoringPslBlockDescriptorNamespace;\n /**\n * Codec lookup for validating `value`-kind extension block parameters.\n * When provided alongside `pslBlockDescriptors`, the generic validator runs\n * over every parsed extension block after the full AST is assembled,\n * appending any diagnostics to the parse result. Absent or undefined means\n * no codec validation runs; `ref` resolution still runs when namespace\n * context is available (built from the assembled namespaces).\n */\n readonly codecLookup?: CodecLookup;\n}\n\nexport interface ParsePslDocumentResult {\n readonly ast: PslDocumentAst;\n readonly diagnostics: readonly PslDiagnostic[];\n readonly ok: boolean;\n}\n","/**\n * Generic validator for extension-contributed top-level PSL blocks.\n *\n * One function — {@link validateExtensionBlock} — takes a parsed\n * {@link PslExtensionBlock}, its {@link AuthoringPslBlockDescriptor}, a\n * {@link CodecLookup} (for `value` parameters), and the set of\n * {@link PslNamespace} objects from the document (for `ref` resolution), and\n * returns the full list of {@link PslDiagnostic} objects for the block.\n *\n * Detection logic per failure mode:\n *\n * 1. **Unknown parameter** — keys present in `node.parameters` that are absent\n * from `descriptor.parameters` (key-set difference). The parser stores\n * unknown parameters as `kind:'value'` stubs; the validator discovers them\n * by comparing the key sets, not by inspecting the captured kind.\n *\n * 2. **Missing required parameter** — `descriptor.parameters` entries with\n * `required: true` whose key is absent from `node.parameters`.\n *\n * 3. **`option` value outside its set** — the captured `token` is not in\n * `descriptor.values`.\n *\n * 4. **`value` rejected by its codec** — the raw string is first parsed as\n * JSON (`JSON.parse(raw)`). If `JSON.parse` throws, the literal is not valid\n * JSON and a `PSL_EXTENSION_INVALID_VALUE` diagnostic is emitted. If parsing\n * succeeds but `codec.decodeJson(jsonValue)` throws, the JSON value is not\n * acceptable to the codec and a `PSL_EXTENSION_INVALID_VALUE` diagnostic is\n * emitted. If `codecLookup.get(codecId)` returns `undefined` (unknown codec\n * id), a `PSL_EXTENSION_INVALID_VALUE` diagnostic is also emitted.\n *\n * 5. **`ref` that does not resolve within its scope** — the captured\n * `identifier` is looked up in the PSL document's `PslNamespace` objects\n * according to `param.scope`:\n * - `same-namespace`: the referent must be in the same namespace as the\n * block (the namespace containing the block).\n * - `same-space`: the referent may be in any namespace in the document.\n * - `cross-space`: pass-through — enforcement is scoped to first-consumer\n * need (RLS roles). This case is documented and clearly flagged; the\n * caller is responsible for wiring cross-space resolution when needed.\n *\n * 6. **`list`** — each element is validated against `param.of` recursively.\n *\n * ### `char`/`varchar` length\n * Not enforced. RLS `using`/`check` strings are unbounded text and the codec\n * already rejects structurally invalid literals; length constraints are a\n * database-side concern, not a PSL authoring constraint.\n *\n * ### `cross-space` scope\n * Implemented as a documented pass-through. The spec permits scoping\n * cross-space enforcement to first-consumer need (RLS roles). When RLS roles\n * arrive, wire `cross-space` resolution through the cross-contract-space\n * coordinate model `(spaceId, namespaceId, entityKind, entityName)`.\n */\n\nimport type { JsonValue } from '@prisma-next/contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { CodecLookup } from '../shared/codec-types';\nimport type { AuthoringPslBlockDescriptor } from '../shared/framework-authoring';\nimport type {\n PslBlockParam,\n PslBlockParamRef,\n PslExtensionBlock,\n PslExtensionBlockParamValue,\n PslSpan,\n} from '../shared/psl-extension-block';\nimport type { PslDiagnostic, PslNamespace } from './psl-ast';\n\n/**\n * Context for ref resolution during extension-block validation.\n *\n * - `ownerNamespace` is the `PslNamespace` that contains the block being\n * validated. Used for `same-namespace` scope checks.\n * - `allNamespaces` is every namespace in the document. Used for `same-space`\n * scope checks.\n */\nexport interface ExtensionBlockRefResolutionContext {\n readonly ownerNamespace: PslNamespace;\n readonly allNamespaces: readonly PslNamespace[];\n}\n\n/**\n * Validate a single parsed extension block against its descriptor.\n *\n * Returns an array of {@link PslDiagnostic} objects (possibly empty). The\n * caller is responsible for threading `sourceId` into each returned diagnostic\n * — the returned objects already have `sourceId` set from the `sourceId`\n * parameter.\n *\n * @param node - The parsed block node produced by the generic framework parser.\n * @param descriptor - The descriptor that claims this block's keyword.\n * @param sourceId - The PSL source file identifier (threaded into diagnostics).\n * @param codecLookup - Used to validate `value`-kind parameter literals via\n * `codecLookup.get(codecId)?.decodeJson(JSON.parse(raw))`.\n * @param refCtx - Namespace context for `ref`-kind scope resolution. Required\n * when any descriptor parameter is `kind: 'ref'`; may be omitted if none are.\n */\nexport function validateExtensionBlock(\n node: PslExtensionBlock,\n descriptor: AuthoringPslBlockDescriptor,\n sourceId: string,\n codecLookup: CodecLookup,\n refCtx?: ExtensionBlockRefResolutionContext,\n): readonly PslDiagnostic[] {\n const diagnostics: PslDiagnostic[] = [];\n\n const descriptorKeys = new Set(Object.keys(descriptor.parameters));\n const nodeKeys = new Set(Object.keys(node.parameters));\n\n // 1. Unknown parameters — keys in the node not in the descriptor.\n if (!descriptor.variadicParameters) {\n for (const key of nodeKeys) {\n if (!descriptorKeys.has(key)) {\n const captured = node.parameters[key];\n diagnostics.push({\n code: 'PSL_EXTENSION_UNKNOWN_PARAMETER',\n message: `Unknown parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\". The descriptor does not declare this parameter.`,\n sourceId,\n span: captured?.span ?? node.span,\n });\n }\n }\n }\n\n // 2. Missing required parameters — required descriptor keys absent from the node.\n for (const [key, param] of Object.entries(descriptor.parameters)) {\n if (param.required === true && !nodeKeys.has(key)) {\n diagnostics.push({\n code: 'PSL_EXTENSION_MISSING_REQUIRED_PARAMETER',\n message: `Required parameter \"${key}\" is missing from \"${descriptor.keyword}\" block \"${node.name}\".`,\n sourceId,\n span: node.span,\n });\n }\n }\n\n // 3–5. Per-parameter validation for parameters that are present.\n for (const [key, param] of Object.entries(descriptor.parameters)) {\n const captured = node.parameters[key];\n if (captured === undefined) {\n continue;\n }\n validateParam(\n node,\n descriptor,\n key,\n param,\n captured,\n sourceId,\n codecLookup,\n refCtx,\n diagnostics,\n );\n }\n\n return diagnostics;\n}\n\nfunction validateParam(\n node: PslExtensionBlock,\n descriptor: AuthoringPslBlockDescriptor,\n key: string,\n param: PslBlockParam,\n captured: PslExtensionBlockParamValue,\n sourceId: string,\n codecLookup: CodecLookup,\n refCtx: ExtensionBlockRefResolutionContext | undefined,\n diagnostics: PslDiagnostic[],\n): void {\n switch (param.kind) {\n case 'option': {\n if (captured.kind !== 'option') {\n return;\n }\n if (!param.values.includes(captured.token)) {\n diagnostics.push({\n code: 'PSL_EXTENSION_OPTION_OUT_OF_SET',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" has value \"${captured.token}\" which is not one of the allowed values: ${param.values.map((v) => `\"${v}\"`).join(', ')}.`,\n sourceId,\n span: captured.span,\n });\n }\n return;\n }\n\n case 'value': {\n if (captured.kind !== 'value') {\n return;\n }\n const codec = codecLookup.get(param.codecId);\n if (codec === undefined) {\n diagnostics.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" references unknown codec \"${param.codecId}\".`,\n sourceId,\n span: captured.span,\n });\n return;\n }\n let jsonValue: unknown;\n try {\n jsonValue = JSON.parse(captured.raw);\n } catch {\n diagnostics.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" is not a valid JSON literal (expected a JSON string, number, boolean, or null): ${captured.raw}`,\n sourceId,\n span: captured.span,\n });\n return;\n }\n try {\n codec.decodeJson(\n blindCast<JsonValue, 'JSON.parse returns a JsonValue-compatible value'>(jsonValue),\n );\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n diagnostics.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" was rejected by codec \"${param.codecId}\": ${reason}`,\n sourceId,\n span: captured.span,\n });\n }\n return;\n }\n\n case 'ref': {\n if (captured.kind !== 'ref') {\n return;\n }\n validateRef(\n node,\n descriptor,\n key,\n param,\n captured.identifier,\n captured.span,\n sourceId,\n refCtx,\n diagnostics,\n );\n return;\n }\n\n case 'list': {\n if (captured.kind !== 'list') {\n return;\n }\n for (const item of captured.items) {\n validateParam(\n node,\n descriptor,\n key,\n param.of,\n item,\n sourceId,\n codecLookup,\n refCtx,\n diagnostics,\n );\n }\n return;\n }\n }\n}\n\nfunction validateRef(\n node: PslExtensionBlock,\n descriptor: AuthoringPslBlockDescriptor,\n key: string,\n param: PslBlockParamRef,\n identifier: string,\n span: PslSpan,\n sourceId: string,\n refCtx: ExtensionBlockRefResolutionContext | undefined,\n diagnostics: PslDiagnostic[],\n): void {\n if (param.scope === 'cross-space') {\n // cross-space enforcement is a documented pass-through. The spec permits\n // scoping cross-space resolution to first-consumer need (RLS roles). When\n // that consumer arrives, wire resolution here through the\n // cross-contract-space coordinate model\n // (spaceId, namespaceId, entityKind, entityName).\n // For now, cross-space refs pass validation unconditionally.\n return;\n }\n\n if (refCtx === undefined) {\n // If no resolution context was provided, skip ref resolution. This matches\n // the closed-grammar invariant: callers that register ref parameters must\n // provide resolution context; callers without namespaces (e.g. unit tests\n // that only exercise other validation modes) can omit it.\n return;\n }\n\n const namespacesToSearch: readonly PslNamespace[] =\n param.scope === 'same-namespace' ? [refCtx.ownerNamespace] : refCtx.allNamespaces;\n\n if (!resolveEntityInNamespaces(identifier, param.refKind, namespacesToSearch)) {\n const scopeLabel =\n param.scope === 'same-namespace' ? 'the same namespace' : 'any namespace in the schema';\n diagnostics.push({\n code: 'PSL_EXTENSION_UNRESOLVED_REF',\n message: `Parameter \"${key}\" in \"${descriptor.keyword}\" block \"${node.name}\" refers to \"${identifier}\" (expected ${param.refKind}), but no entity with that name and kind was found in ${scopeLabel}.`,\n sourceId,\n span,\n });\n }\n}\n\n/**\n * True if an entity named `name` of kind `refKind` exists in any of the given\n * namespaces. Built-in and extension kinds resolve the same way, through\n * `entries[refKind]`.\n */\nfunction resolveEntityInNamespaces(\n name: string,\n refKind: string,\n namespaces: readonly PslNamespace[],\n): boolean {\n for (const ns of namespaces) {\n const kindMap = ns.entries[refKind];\n if (kindMap !== undefined && Object.hasOwn(kindMap, name)) return true;\n }\n return false;\n}\n"],"mappings":"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"} |
+7
-7
| { | ||
| "name": "@prisma-next/framework-components", | ||
| "version": "0.14.0-dev.11", | ||
| "version": "0.14.0-dev.12", | ||
| "license": "Apache-2.0", | ||
@@ -9,6 +9,6 @@ "type": "module", | ||
| "dependencies": { | ||
| "@prisma-next/contract": "0.14.0-dev.11", | ||
| "@prisma-next/operations": "0.14.0-dev.11", | ||
| "@prisma-next/ts-render": "0.14.0-dev.11", | ||
| "@prisma-next/utils": "0.14.0-dev.11", | ||
| "@prisma-next/contract": "0.14.0-dev.12", | ||
| "@prisma-next/operations": "0.14.0-dev.12", | ||
| "@prisma-next/ts-render": "0.14.0-dev.12", | ||
| "@prisma-next/utils": "0.14.0-dev.12", | ||
| "@standard-schema/spec": "^1.1.0", | ||
@@ -18,4 +18,4 @@ "arktype": "^2.2.0" | ||
| "devDependencies": { | ||
| "@prisma-next/tsconfig": "0.14.0-dev.11", | ||
| "@prisma-next/tsdown": "0.14.0-dev.11", | ||
| "@prisma-next/tsconfig": "0.14.0-dev.12", | ||
| "@prisma-next/tsdown": "0.14.0-dev.12", | ||
| "tsdown": "0.22.1", | ||
@@ -22,0 +22,0 @@ "typescript": "5.9.3", |
@@ -0,1 +1,3 @@ | ||
| import type { SchemaDiffIssue } from './schema-diff'; | ||
| export const VERIFY_CODE_MARKER_MISSING = 'PN-RUN-3001'; | ||
@@ -132,2 +134,3 @@ export const VERIFY_CODE_HASH_MISMATCH = 'PN-RUN-3002'; | ||
| readonly issues: readonly SchemaIssue[]; | ||
| readonly schemaDiffIssues: readonly SchemaDiffIssue[]; | ||
| readonly root: SchemaVerificationNode; | ||
@@ -134,0 +137,0 @@ readonly counts: { |
@@ -193,3 +193,5 @@ export type { AuthoringPslBlockDescriptorNamespace } from '../shared/framework-authoring'; | ||
| * `kind` is the PSL keyword for built-ins or the block discriminator for | ||
| * extension kinds, e.g. `entries['policy_select']['ReadPosts']`. | ||
| * extension kinds, e.g. `entries['policy']['ReadPosts']` (the discriminator, | ||
| * not the PSL keyword — a `policy_select` block lands under `'policy'` per | ||
| * ADR 225). | ||
| */ | ||
@@ -196,0 +198,0 @@ export interface PslNamespace { |
@@ -104,2 +104,4 @@ export type { ImportRequirement } from '@prisma-next/ts-render'; | ||
| } from '../control/control-stack'; | ||
| export type { DiffableNode, SchemaDiffIssue, SchemaDiffOutcome } from '../control/schema-diff'; | ||
| export { diffNodes } from '../control/schema-diff'; | ||
| export type { | ||
@@ -106,0 +108,0 @@ SchemaVerifier, |
| import { r as CodecLookup } from "./codec-types-yY3eSmi0.mjs"; | ||
| import { R as PslDiagnosticCode, Y as PslSpan, h as AuthoringPslBlockDescriptorNamespace, z as PslExtensionBlock } from "./framework-authoring-Di7Ug2bw.mjs"; | ||
| //#region src/control/psl-ast.d.ts | ||
| interface PslDiagnostic { | ||
| readonly code: PslDiagnosticCode; | ||
| readonly message: string; | ||
| readonly sourceId: string; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslDefaultFunctionValue { | ||
| readonly kind: 'function'; | ||
| readonly name: 'autoincrement' | 'now'; | ||
| } | ||
| interface PslDefaultLiteralValue { | ||
| readonly kind: 'literal'; | ||
| readonly value: string | number | boolean; | ||
| } | ||
| type PslDefaultValue = PslDefaultFunctionValue | PslDefaultLiteralValue; | ||
| type PslAttributeTarget = 'field' | 'model' | 'enum' | 'namedType'; | ||
| interface PslAttributePositionalArgument { | ||
| readonly kind: 'positional'; | ||
| readonly value: string; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslAttributeNamedArgument { | ||
| readonly kind: 'named'; | ||
| readonly name: string; | ||
| readonly value: string; | ||
| readonly span: PslSpan; | ||
| } | ||
| type PslAttributeArgument = PslAttributePositionalArgument | PslAttributeNamedArgument; | ||
| interface PslTypeConstructorCall { | ||
| readonly kind: 'typeConstructor'; | ||
| readonly path: readonly string[]; | ||
| readonly args: readonly PslAttributeArgument[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslAttribute { | ||
| readonly kind: 'attribute'; | ||
| readonly target: PslAttributeTarget; | ||
| readonly name: string; | ||
| readonly args: readonly PslAttributeArgument[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| type PslReferentialAction = string; | ||
| type PslFieldAttribute = PslAttribute; | ||
| interface PslField { | ||
| readonly kind: 'field'; | ||
| readonly name: string; | ||
| /** Unqualified type name, e.g. `"User"` for both `User`, `auth.User`, and `supabase:auth.User`. */ | ||
| readonly typeName: string; | ||
| /** Namespace qualifier from a dot-qualified type reference, e.g. `"auth"` for `auth.User` or `supabase:auth.User`. Absent for unqualified types. */ | ||
| readonly typeNamespaceId?: string; | ||
| /** | ||
| * Contract-space qualifier from a colon-prefix type reference, e.g. `"supabase"` for | ||
| * `supabase:auth.User` or `supabase:User`. Absent for local (same-space) type references. | ||
| * | ||
| * When present, the field references a model from a different contract space. The namespace | ||
| * (`typeNamespaceId`) and model name (`typeName`) identify the target within that space. | ||
| * Physical table resolution against the extension contract is deferred to the aggregate stage (M3). | ||
| */ | ||
| readonly typeContractSpaceId?: string; | ||
| readonly typeConstructor?: PslTypeConstructorCall; | ||
| readonly optional: boolean; | ||
| readonly list: boolean; | ||
| readonly typeRef?: string; | ||
| readonly attributes: readonly PslFieldAttribute[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslUniqueConstraint { | ||
| readonly kind: 'unique'; | ||
| readonly fields: readonly string[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslIndexConstraint { | ||
| readonly kind: 'index'; | ||
| readonly fields: readonly string[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| type PslModelAttribute = PslAttribute; | ||
| interface PslModel { | ||
| readonly kind: 'model'; | ||
| readonly name: string; | ||
| readonly fields: readonly PslField[]; | ||
| readonly attributes: readonly PslModelAttribute[]; | ||
| readonly span: PslSpan; | ||
| /** | ||
| * Optional leading comment line emitted above the `model` keyword by the | ||
| * printer. Producers (e.g. `sqlSchemaIrToPslAst`) attach introspection | ||
| * advisories such as "// WARNING: This table has no primary key in the | ||
| * database" here. The parser leaves this field unset; round-tripping a | ||
| * parsed schema does not re-attach comments. | ||
| */ | ||
| readonly comment?: string; | ||
| } | ||
| /** | ||
| * A reusable group of fields embedded in a model (a `type Name { … }` block) — | ||
| * e.g. a MongoDB embedded document or a Postgres composite type. Unlike | ||
| * {@link PslModel} it has no storage or identity of its own. | ||
| */ | ||
| interface PslCompositeType { | ||
| readonly kind: 'compositeType'; | ||
| readonly name: string; | ||
| readonly fields: readonly PslField[]; | ||
| readonly attributes: readonly PslAttribute[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslNamedTypeDeclaration { | ||
| readonly kind: 'namedType'; | ||
| readonly name: string; | ||
| /** | ||
| * Parser invariant: exactly one of `baseType` and `typeConstructor` is set. | ||
| * Expressing this as a discriminated union trips TypeScript narrowing when | ||
| * the declaration flows through helpers that accept the full union. | ||
| */ | ||
| readonly baseType?: string; | ||
| readonly typeConstructor?: PslTypeConstructorCall; | ||
| readonly attributes: readonly PslAttribute[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| interface PslTypesBlock { | ||
| readonly kind: 'types'; | ||
| readonly declarations: readonly PslNamedTypeDeclaration[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| /** | ||
| * Name of the synthesised namespace bucket the framework parser uses for | ||
| * top-level declarations that appear outside any `namespace { … }` block. | ||
| * The double-underscore decoration signals that the identifier is parser- | ||
| * synthesised and never appears in user-authored PSL source — writing | ||
| * `namespace __unspecified__ { … }` is a parse error. | ||
| * | ||
| * Distinct from the IR sentinel `__unbound__`: the PSL bucket describes | ||
| * syntactic absence at the parser layer; the IR sentinel describes a late- | ||
| * bound storage slot at the IR layer. Per-target interpreters decide how | ||
| * (or whether) to map the PSL bucket to the IR sentinel. | ||
| */ | ||
| declare const UNSPECIFIED_PSL_NAMESPACE_ID = "__unspecified__"; | ||
| /** A value in {@link PslNamespace.entries}: a built-in entity node or an extension-contributed {@link PslExtensionBlock}. */ | ||
| type PslNamespaceEntry = PslModel | PslCompositeType | PslExtensionBlock; | ||
| /** | ||
| * A namespace block, or the parser's synthesised `__unspecified__` bucket for | ||
| * declarations outside any `namespace { … }`. Same-name blocks reopen-merge; | ||
| * `span` points at the first opening. | ||
| * | ||
| * Entities are stored canonically (ADR 224) in `entries[kind][name]`, where | ||
| * `kind` is the PSL keyword for built-ins or the block discriminator for | ||
| * extension kinds, e.g. `entries['policy_select']['ReadPosts']`. | ||
| */ | ||
| interface PslNamespace { | ||
| readonly kind: 'namespace'; | ||
| readonly name: string; | ||
| /** Canonical store: a frozen container of frozen per-kind maps. The accessors below derive from it. */ | ||
| readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>; | ||
| /** Built-in models, from `entries['model']`. Extension kinds: {@link namespacePslExtensionBlocks}. */ | ||
| readonly models: readonly PslModel[]; | ||
| /** Built-in composite types, from `entries['compositeType']`. */ | ||
| readonly compositeTypes: readonly PslCompositeType[]; | ||
| readonly span: PslSpan; | ||
| } | ||
| /** Constructs a {@link PslNamespace}. Use this, never a namespace literal — the accessors must derive from `entries`. */ | ||
| declare function makePslNamespace(init: { | ||
| readonly kind: 'namespace'; | ||
| readonly name: string; | ||
| readonly entries: Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>; | ||
| readonly span: PslSpan; | ||
| }): PslNamespace; | ||
| /** | ||
| * Builds the frozen `entries[kind][name]` container from per-kind arrays. | ||
| * Built-ins key on their PSL keyword; extension blocks key on their `kind` | ||
| * discriminator. Call this rather than hand-building the literal. | ||
| */ | ||
| declare function makePslNamespaceEntries(models: readonly PslModel[], compositeTypes: readonly PslCompositeType[], extensionBlocks: readonly PslExtensionBlock[]): Readonly<Record<string, Readonly<Record<string, PslNamespaceEntry>>>>; | ||
| interface PslDocumentAst { | ||
| readonly kind: 'document'; | ||
| readonly sourceId: string; | ||
| readonly namespaces: readonly PslNamespace[]; | ||
| readonly types?: PslTypesBlock; | ||
| readonly span: PslSpan; | ||
| } | ||
| /** | ||
| * Returns all models from every namespace in document order. Convenience | ||
| * for consumers that don't (yet) need namespace-awareness. | ||
| */ | ||
| declare function flatPslModels(ast: PslDocumentAst): readonly PslModel[]; | ||
| /** | ||
| * Returns all composite types from every namespace in document order. | ||
| */ | ||
| declare function flatPslCompositeTypes(ast: PslDocumentAst): readonly PslCompositeType[]; | ||
| /** | ||
| * The set of `entries` kind keys that the framework parser reserves for | ||
| * built-in PSL entity kinds. Any own-enumerable key on `PslNamespace.entries` | ||
| * that is **not** in this set was contributed by an extension-block descriptor. | ||
| * | ||
| * Built-in keys match the PSL keyword used on each block type: | ||
| * `'model'`, `'compositeType'`. The `'enum'` keyword is claimed by the | ||
| * extension-block grammar via a registered descriptor, so `entries['enum']` | ||
| * holds `PslExtensionBlock` nodes and is returned by `namespacePslExtensionBlocks`. | ||
| */ | ||
| declare const BUILTIN_PSL_KIND_KEYS: ReadonlySet<string>; | ||
| /** | ||
| * Returns all extension-contributed blocks in the given namespace, in | ||
| * insertion order (the order the parser encountered them in the source). | ||
| * | ||
| * Reads from `namespace.entries`, skipping the built-in kind keys | ||
| * (`'model'`, `'compositeType'`). All remaining kind maps contain | ||
| * only `PslExtensionBlock` nodes by construction (see `makePslNamespaceEntries`). | ||
| */ | ||
| declare function namespacePslExtensionBlocks(ns: PslNamespace): readonly PslExtensionBlock[]; | ||
| interface ParsePslDocumentInput { | ||
| readonly schema: string; | ||
| readonly sourceId: string; | ||
| /** | ||
| * Registry of declarative block descriptors, keyed by arbitrary path | ||
| * segments with {@link AuthoringPslBlockDescriptor} leaves. The registry | ||
| * teaches the parser which top-level keywords belong to extension | ||
| * contributions: when the parser encounters an unknown keyword, it looks | ||
| * it up here and, when found, reads the block generically into a | ||
| * {@link PslExtensionBlock} node. Absent or undefined means no extension | ||
| * blocks are registered and any unknown keyword yields | ||
| * `PSL_UNSUPPORTED_TOP_LEVEL_BLOCK`. | ||
| * | ||
| * Contrast with the parsed block nodes themselves, which live in | ||
| * {@link PslNamespace.entries} under their discriminator key (read them with | ||
| * {@link namespacePslExtensionBlocks}); this field holds the registry of | ||
| * descriptors that teach the parser how to read those blocks. | ||
| */ | ||
| readonly pslBlockDescriptors?: AuthoringPslBlockDescriptorNamespace; | ||
| /** | ||
| * Codec lookup for validating `value`-kind extension block parameters. | ||
| * When provided alongside `pslBlockDescriptors`, the generic validator runs | ||
| * over every parsed extension block after the full AST is assembled, | ||
| * appending any diagnostics to the parse result. Absent or undefined means | ||
| * no codec validation runs; `ref` resolution still runs when namespace | ||
| * context is available (built from the assembled namespaces). | ||
| */ | ||
| readonly codecLookup?: CodecLookup; | ||
| } | ||
| interface ParsePslDocumentResult { | ||
| readonly ast: PslDocumentAst; | ||
| readonly diagnostics: readonly PslDiagnostic[]; | ||
| readonly ok: boolean; | ||
| } | ||
| //#endregion | ||
| export { makePslNamespace as A, PslReferentialAction as C, UNSPECIFIED_PSL_NAMESPACE_ID as D, PslUniqueConstraint as E, namespacePslExtensionBlocks as M, flatPslCompositeTypes as O, PslNamespaceEntry as S, PslTypesBlock as T, PslIndexConstraint as _, PslAttributeArgument as a, PslNamedTypeDeclaration as b, PslAttributeTarget as c, PslDefaultLiteralValue as d, PslDefaultValue as f, PslFieldAttribute as g, PslField as h, PslAttribute as i, makePslNamespaceEntries as j, flatPslModels as k, PslCompositeType as l, PslDocumentAst as m, ParsePslDocumentInput as n, PslAttributeNamedArgument as o, PslDiagnostic as p, ParsePslDocumentResult as r, PslAttributePositionalArgument as s, BUILTIN_PSL_KIND_KEYS as t, PslDefaultFunctionValue as u, PslModel as v, PslTypeConstructorCall as w, PslNamespace as x, PslModelAttribute as y }; | ||
| //# sourceMappingURL=psl-ast-CWkHgK17.d.mts.map |
| {"version":3,"file":"psl-ast-CWkHgK17.d.mts","names":[],"sources":["../src/control/psl-ast.ts"],"mappings":"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"} |
940589
1.17%120
2.56%8930
1.43%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed