@prisma-next/framework-components
Advanced tools
| import { blindCast } from '@prisma-next/utils/casts'; | ||
| import { UNBOUND_NAMESPACE_ID } from './namespace'; | ||
| import type { Storage } from './storage'; | ||
| /** | ||
| * Extracts the entries map of a contract's single default namespace | ||
| * (`UNBOUND_NAMESPACE_ID`). Both single-namespace families (Mongo, SQLite) | ||
| * store all entities under this one namespace. | ||
| */ | ||
| export type DefaultNamespaceEntries<TStorage extends { readonly namespaces: object }> = | ||
| TStorage['namespaces'] extends Record<typeof UNBOUND_NAMESPACE_ID, { readonly entries: infer E }> | ||
| ? E | ||
| : never; | ||
| /** | ||
| * Generic single-namespace projection shape — one namespace's entity-kind slots. | ||
| * A family supplies: | ||
| * - `TEntries` — the family's `*NamespaceEntries` type for the namespace. | ||
| * - `TBuiltinKinds` — the union of the family's statically-named built-in kind | ||
| * keys (Mongo `'collection'`; SQL `'table' | 'valueSet'`). | ||
| * | ||
| * Each built-in kind becomes a top-level accessor; the remaining pack-contributed | ||
| * kinds stay under `.entries` (keyed by their registered singular kind string). | ||
| * | ||
| * A built-in kind that the emitted contract does not carry resolves to an empty | ||
| * map (`Record<string, never>`), matching the runtime which always materializes | ||
| * each built-in slot. The `& string` index-signature member of `TEntries` is | ||
| * excluded from `.entries` so only the literal pack-kind keys remain. | ||
| */ | ||
| export type SingleNamespaceView<TEntries, TBuiltinKinds extends string> = { | ||
| readonly [K in TBuiltinKinds]-?: K extends keyof TEntries | ||
| ? NonNullable<TEntries[K]> | ||
| : Record<string, never>; | ||
| } & { | ||
| readonly entries: { | ||
| readonly [K in Exclude<keyof TEntries, TBuiltinKinds | number | symbol> as string extends K | ||
| ? never | ||
| : K]: TEntries[K]; | ||
| }; | ||
| }; | ||
| /** The `entries` shape of one namespace in a storage map. */ | ||
| type EntriesOf<TNamespace> = TNamespace extends { readonly entries: infer E } ? E : never; | ||
| /** | ||
| * The namespace-keyed entity-view map — every storage namespace keyed by its raw | ||
| * id, each projected to its {@link SingleNamespaceView}. Mirrors | ||
| * `NamespacedEnums` from `@prisma-next/contract/enum-accessor`: the migration | ||
| * author's storage-side `view.namespace.<nsId>` is the twin of the runtime's | ||
| * `db.enums.<nsId>`. Nesting the schema map under one fixed `namespace` member | ||
| * makes it collision-proof — a schema named `storage` is `view.namespace.storage`, | ||
| * never a contract-root key. | ||
| */ | ||
| export type NamespacedEntities< | ||
| TStorage extends { readonly namespaces: object }, | ||
| TBuiltinKinds extends string, | ||
| > = { | ||
| readonly [Ns in keyof TStorage['namespaces']]: SingleNamespaceView< | ||
| EntriesOf<TStorage['namespaces'][Ns]>, | ||
| TBuiltinKinds | ||
| >; | ||
| }; | ||
| /** | ||
| * Projects one namespace's `entries` into the view shape: each built-in kind | ||
| * becomes a top-level slot (materialized empty if absent), and the remaining | ||
| * pack-contributed kinds sit under `.entries`. Shared by the single-namespace | ||
| * builder and the namespace-map builder. | ||
| */ | ||
| export function promoteBuiltinKinds<TView>( | ||
| entries: Readonly<Record<string, unknown>>, | ||
| builtinKinds: readonly string[], | ||
| ): TView { | ||
| const view: Record<string, unknown> = {}; | ||
| const rest: Record<string, unknown> = {}; | ||
| for (const [kind, kindMap] of Object.entries(entries)) { | ||
| if (builtinKinds.includes(kind)) { | ||
| view[kind] = kindMap; | ||
| } else { | ||
| rest[kind] = kindMap; | ||
| } | ||
| } | ||
| for (const kind of builtinKinds) { | ||
| if (!(kind in view)) { | ||
| view[kind] = {}; | ||
| } | ||
| } | ||
| view['entries'] = rest; | ||
| return blindCast<TView, 'view is built to the SingleNamespaceView shape the caller parametrizes'>( | ||
| view, | ||
| ); | ||
| } | ||
| /** | ||
| * Builds one namespace's entity view: promotes the given built-in kind slots to | ||
| * top-level for the default (`UNBOUND_NAMESPACE_ID`) namespace. Single-namespace | ||
| * targets (Mongo, SQLite) use this to unwrap their sole namespace to the root. | ||
| * | ||
| * Throws if the contract has no default (`UNBOUND_NAMESPACE_ID`) namespace. | ||
| */ | ||
| export function buildSingleNamespaceView<TView>( | ||
| storage: Storage, | ||
| builtinKinds: readonly string[], | ||
| ): TView { | ||
| const defaultNs = storage.namespaces[UNBOUND_NAMESPACE_ID]; | ||
| if (defaultNs === undefined) { | ||
| throw new Error(`ContractView: contract has no default namespace (${UNBOUND_NAMESPACE_ID})`); | ||
| } | ||
| const entries = blindCast< | ||
| Record<string, unknown>, | ||
| 'Namespace.entries is the open ADR 224 dictionary Record<string, Record<string, unknown>>' | ||
| >(defaultNs.entries); | ||
| return promoteBuiltinKinds<TView>(entries, builtinKinds); | ||
| } | ||
| /** | ||
| * Builds the namespace-keyed entity-view map (`{ <nsId>: SingleNamespaceView }`) | ||
| * for every namespace in the storage, keyed by raw namespace id. Mirrors | ||
| * `buildNamespacedEnums(domain)` — the storage-side twin. | ||
| */ | ||
| export function buildNamespacedEntities<TMap>( | ||
| storage: Storage, | ||
| builtinKinds: readonly string[], | ||
| ): TMap { | ||
| const out: Record<string, unknown> = {}; | ||
| for (const [nsId, ns] of Object.entries(storage.namespaces)) { | ||
| out[nsId] = promoteBuiltinKinds( | ||
| blindCast< | ||
| Readonly<Record<string, unknown>>, | ||
| 'Namespace.entries is the open ADR 224 dictionary Record<string, Record<string, unknown>>' | ||
| >(ns.entries), | ||
| builtinKinds, | ||
| ); | ||
| } | ||
| return blindCast< | ||
| TMap, | ||
| 'each namespace projected to its SingleNamespaceView; keys mirror the storage namespace ids' | ||
| >(out); | ||
| } |
+68
-1
@@ -211,2 +211,69 @@ import { ApplicationDomain, StorageBase, StorageNamespace } from "@prisma-next/contract/types"; | ||
| //#endregion | ||
| //#region src/ir/contract-view.d.ts | ||
| /** | ||
| * Extracts the entries map of a contract's single default namespace | ||
| * (`UNBOUND_NAMESPACE_ID`). Both single-namespace families (Mongo, SQLite) | ||
| * store all entities under this one namespace. | ||
| */ | ||
| type DefaultNamespaceEntries<TStorage extends { | ||
| readonly namespaces: object; | ||
| }> = TStorage['namespaces'] extends Record<typeof UNBOUND_NAMESPACE_ID, { | ||
| readonly entries: infer E; | ||
| }> ? E : never; | ||
| /** | ||
| * Generic single-namespace projection shape — one namespace's entity-kind slots. | ||
| * A family supplies: | ||
| * - `TEntries` — the family's `*NamespaceEntries` type for the namespace. | ||
| * - `TBuiltinKinds` — the union of the family's statically-named built-in kind | ||
| * keys (Mongo `'collection'`; SQL `'table' | 'valueSet'`). | ||
| * | ||
| * Each built-in kind becomes a top-level accessor; the remaining pack-contributed | ||
| * kinds stay under `.entries` (keyed by their registered singular kind string). | ||
| * | ||
| * A built-in kind that the emitted contract does not carry resolves to an empty | ||
| * map (`Record<string, never>`), matching the runtime which always materializes | ||
| * each built-in slot. The `& string` index-signature member of `TEntries` is | ||
| * excluded from `.entries` so only the literal pack-kind keys remain. | ||
| */ | ||
| type SingleNamespaceView<TEntries, TBuiltinKinds extends string> = { readonly [K in TBuiltinKinds]-?: K extends keyof TEntries ? NonNullable<TEntries[K]> : Record<string, never> } & { | ||
| readonly entries: { readonly [K in Exclude<keyof TEntries, TBuiltinKinds | number | symbol> as string extends K ? never : K]: TEntries[K] }; | ||
| }; | ||
| /** The `entries` shape of one namespace in a storage map. */ | ||
| type EntriesOf<TNamespace> = TNamespace extends { | ||
| readonly entries: infer E; | ||
| } ? E : never; | ||
| /** | ||
| * The namespace-keyed entity-view map — every storage namespace keyed by its raw | ||
| * id, each projected to its {@link SingleNamespaceView}. Mirrors | ||
| * `NamespacedEnums` from `@prisma-next/contract/enum-accessor`: the migration | ||
| * author's storage-side `view.namespace.<nsId>` is the twin of the runtime's | ||
| * `db.enums.<nsId>`. Nesting the schema map under one fixed `namespace` member | ||
| * makes it collision-proof — a schema named `storage` is `view.namespace.storage`, | ||
| * never a contract-root key. | ||
| */ | ||
| type NamespacedEntities<TStorage extends { | ||
| readonly namespaces: object; | ||
| }, TBuiltinKinds extends string> = { readonly [Ns in keyof TStorage['namespaces']]: SingleNamespaceView<EntriesOf<TStorage['namespaces'][Ns]>, TBuiltinKinds> }; | ||
| /** | ||
| * Projects one namespace's `entries` into the view shape: each built-in kind | ||
| * becomes a top-level slot (materialized empty if absent), and the remaining | ||
| * pack-contributed kinds sit under `.entries`. Shared by the single-namespace | ||
| * builder and the namespace-map builder. | ||
| */ | ||
| declare function promoteBuiltinKinds<TView>(entries: Readonly<Record<string, unknown>>, builtinKinds: readonly string[]): TView; | ||
| /** | ||
| * Builds one namespace's entity view: promotes the given built-in kind slots to | ||
| * top-level for the default (`UNBOUND_NAMESPACE_ID`) namespace. Single-namespace | ||
| * targets (Mongo, SQLite) use this to unwrap their sole namespace to the root. | ||
| * | ||
| * Throws if the contract has no default (`UNBOUND_NAMESPACE_ID`) namespace. | ||
| */ | ||
| declare function buildSingleNamespaceView<TView>(storage: Storage, builtinKinds: readonly string[]): TView; | ||
| /** | ||
| * Builds the namespace-keyed entity-view map (`{ <nsId>: SingleNamespaceView }`) | ||
| * for every namespace in the storage, keyed by raw namespace id. Mirrors | ||
| * `buildNamespacedEnums(domain)` — the storage-side twin. | ||
| */ | ||
| declare function buildNamespacedEntities<TMap>(storage: Storage, builtinKinds: readonly string[]): TMap; | ||
| //#endregion | ||
| //#region src/ir/domain.d.ts | ||
@@ -266,3 +333,3 @@ /** | ||
| //#endregion | ||
| export { type AnyEntityKindDescriptor, type EntityCoordinate, type EntityKindDescriptor, type IRNode, IRNodeBase, type Namespace, NamespaceBase, type Storage, type StorageType, UNBOUND_NAMESPACE_ID, domainElementCoordinates, elementCoordinates, entityAt, freezeNode, hydrateNamespaceEntities, isPlainRecord }; | ||
| export { type AnyEntityKindDescriptor, type DefaultNamespaceEntries, type EntityCoordinate, type EntityKindDescriptor, type IRNode, IRNodeBase, type Namespace, NamespaceBase, type NamespacedEntities, type SingleNamespaceView, type Storage, type StorageType, UNBOUND_NAMESPACE_ID, buildNamespacedEntities, buildSingleNamespaceView, domainElementCoordinates, elementCoordinates, entityAt, freezeNode, hydrateNamespaceEntities, isPlainRecord, promoteBuiltinKinds }; | ||
| //# sourceMappingURL=ir.d.mts.map |
@@ -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/ir-node.ts","../src/ir/namespace.ts","../src/ir/storage.ts","../src/ir/contract-view.ts","../src/ir/domain.ts","../src/ir/entity-kind.ts","../src/ir/storage-type.ts"],"mappings":"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"} |
+83
-44
| import { blindCast } from "@prisma-next/utils/casts"; | ||
| import { isPlainRecord } from "@prisma-next/contract/is-plain-record"; | ||
| //#region src/ir/ir-node.ts | ||
| var IRNodeBase = class {}; | ||
| /** | ||
| * 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. | ||
| */ | ||
| function freezeNode(node) { | ||
| Object.freeze(node); | ||
| return node; | ||
| } | ||
| //#endregion | ||
| //#region src/ir/namespace.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. | ||
| */ | ||
| const UNBOUND_NAMESPACE_ID = "__unbound__"; | ||
| var NamespaceBase = class extends IRNodeBase {}; | ||
| //#endregion | ||
| //#region src/ir/contract-view.ts | ||
| /** | ||
| * Projects one namespace's `entries` into the view shape: each built-in kind | ||
| * becomes a top-level slot (materialized empty if absent), and the remaining | ||
| * pack-contributed kinds sit under `.entries`. Shared by the single-namespace | ||
| * builder and the namespace-map builder. | ||
| */ | ||
| function promoteBuiltinKinds(entries, builtinKinds) { | ||
| const view = {}; | ||
| const rest = {}; | ||
| for (const [kind, kindMap] of Object.entries(entries)) if (builtinKinds.includes(kind)) view[kind] = kindMap; | ||
| else rest[kind] = kindMap; | ||
| for (const kind of builtinKinds) if (!(kind in view)) view[kind] = {}; | ||
| view["entries"] = rest; | ||
| return blindCast(view); | ||
| } | ||
| /** | ||
| * Builds one namespace's entity view: promotes the given built-in kind slots to | ||
| * top-level for the default (`UNBOUND_NAMESPACE_ID`) namespace. Single-namespace | ||
| * targets (Mongo, SQLite) use this to unwrap their sole namespace to the root. | ||
| * | ||
| * Throws if the contract has no default (`UNBOUND_NAMESPACE_ID`) namespace. | ||
| */ | ||
| function buildSingleNamespaceView(storage, builtinKinds) { | ||
| const defaultNs = storage.namespaces[UNBOUND_NAMESPACE_ID]; | ||
| if (defaultNs === void 0) throw new Error(`ContractView: contract has no default namespace (${UNBOUND_NAMESPACE_ID})`); | ||
| return promoteBuiltinKinds(blindCast(defaultNs.entries), builtinKinds); | ||
| } | ||
| /** | ||
| * Builds the namespace-keyed entity-view map (`{ <nsId>: SingleNamespaceView }`) | ||
| * for every namespace in the storage, keyed by raw namespace id. Mirrors | ||
| * `buildNamespacedEnums(domain)` — the storage-side twin. | ||
| */ | ||
| function buildNamespacedEntities(storage, builtinKinds) { | ||
| const out = {}; | ||
| for (const [nsId, ns] of Object.entries(storage.namespaces)) out[nsId] = promoteBuiltinKinds(blindCast(ns.entries), builtinKinds); | ||
| return blindCast(out); | ||
| } | ||
| //#endregion | ||
| //#region src/ir/domain.ts | ||
@@ -51,45 +133,2 @@ /** | ||
| //#endregion | ||
| //#region src/ir/ir-node.ts | ||
| var IRNodeBase = class {}; | ||
| /** | ||
| * 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. | ||
| */ | ||
| function freezeNode(node) { | ||
| Object.freeze(node); | ||
| return node; | ||
| } | ||
| //#endregion | ||
| //#region src/ir/namespace.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. | ||
| */ | ||
| const UNBOUND_NAMESPACE_ID = "__unbound__"; | ||
| var NamespaceBase = class extends IRNodeBase {}; | ||
| //#endregion | ||
| //#region src/ir/storage.ts | ||
@@ -139,4 +178,4 @@ /** | ||
| //#endregion | ||
| export { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, domainElementCoordinates, elementCoordinates, entityAt, freezeNode, hydrateNamespaceEntities, isPlainRecord }; | ||
| export { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, buildNamespacedEntities, buildSingleNamespaceView, domainElementCoordinates, elementCoordinates, entityAt, freezeNode, hydrateNamespaceEntities, isPlainRecord, promoteBuiltinKinds }; | ||
| //# sourceMappingURL=ir.mjs.map |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"ir.mjs","names":[],"sources":["../src/ir/domain.ts","../src/ir/entity-kind.ts","../src/ir/ir-node.ts","../src/ir/namespace.ts","../src/ir/storage.ts"],"sourcesContent":["import type { ApplicationDomain } from '@prisma-next/contract/types';\nimport type { EntityCoordinate } from './storage';\n\n/**\n * Lazy walk over every named domain entity in a {@link ApplicationDomain},\n * yielded as {@link EntityCoordinate} tuples with `plane: 'domain'`.\n *\n * Same structural rules as {@link elementCoordinates} over storage: skip\n * scalar `id`; each other object-valued property is an entity-kind slot.\n */\nexport function* domainElementCoordinates(\n domain: Pick<ApplicationDomain, 'namespaces'>,\n): Generator<EntityCoordinate> {\n for (const [namespaceId, ns] of Object.entries(domain.namespaces)) {\n for (const [entityKind, slot] of Object.entries(ns)) {\n if (entityKind === 'id') continue;\n if (slot === null || typeof slot !== 'object') continue;\n for (const entityName of Object.keys(slot)) {\n yield { plane: 'domain', namespaceId, entityKind, entityName };\n }\n }\n }\n}\n","import { blindCast } from '@prisma-next/utils/casts';\nimport type { Type } from 'arktype';\n\nexport interface EntityKindDescriptor<Input, Node> {\n readonly kind: string;\n // Type<unknown>, not Type<Input>: AnyEntityKindDescriptor widens Input to never, which would force an unusable Type<never>; concrete descriptors still carry their real schema.\n readonly schema: Type<unknown>;\n readonly construct: (input: Input) => Node;\n}\n\nexport type AnyEntityKindDescriptor = EntityKindDescriptor<never, unknown>;\n\n/**\n * Hydrates a namespace's entities from raw JSON maps into IR class instances.\n *\n * For each kind in `entries`: if the descriptor map has a descriptor,\n * construct each inner-map value; otherwise freeze-and-carry (`'carry'`)\n * or throw naming the kind and nsId (`'fail'`).\n *\n * The single boundary cast hands `value` to `descriptor.construct` as its\n * `Input`. The value satisfies the kind's `Input` either by the\n * entries-input contract at authoring time or by prior `validateStorage`\n * validation at hydration time.\n */\nexport function hydrateNamespaceEntities(\n entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>,\n kinds: ReadonlyMap<string, AnyEntityKindDescriptor>,\n onUnknown: 'carry' | 'fail',\n nsId?: string,\n): Record<string, Readonly<Record<string, unknown>>> {\n const result: Record<string, Readonly<Record<string, unknown>>> = {};\n for (const [kind, rawMap] of Object.entries(entries)) {\n const descriptor = kinds.get(kind);\n if (descriptor !== undefined) {\n const built: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(rawMap)) {\n built[name] = descriptor.construct(\n blindCast<\n never,\n \"value is this kind's descriptor Input: when authoring, the typed entries-input contract produces it; when hydrating, it was validated against descriptor.schema before this loop. The never target is AnyEntityKindDescriptor's erased Input parameter.\"\n >(value),\n );\n }\n result[kind] = Object.freeze(built);\n } else if (onUnknown === 'carry') {\n result[kind] = Object.freeze(rawMap);\n } else {\n throw new Error(\n `Unknown entries key \"${kind}\" in namespace \"${nsId ?? '?'}\"; no hydration factory registered for this entity kind`,\n );\n }\n }\n return result;\n}\n","/**\n * Framework-level IR alphabet.\n *\n * The framework's contribution to Contract IR / Schema IR is a common\n * root for the IR class hierarchy and a freeze affordance. Family\n * abstract bases (e.g. `SqlNode`, `MongoSchemaIRNode`) refine the alphabet\n * for their family shape; targets ship the concrete classes.\n *\n * `kind` is an optional discriminator on the base. Families and leaves\n * that benefit from discriminated-union dispatch declare their own\n * literal `kind` at the level that earns it — Mongo leaves carry\n * per-class literals (`readonly kind = 'mongo-collection' as const`)\n * because Mongo IR has polymorphic walkers; SQL declares a single\n * family-level `kind = 'sql'` on `SqlNode` because SQL IR has no\n * polymorphic dispatch today. No framework consumer dispatches on\n * `IRNode.kind` at the BASE type — every dispatch site narrows\n * through a union of leaves where each leaf carries a literal kind, so\n * requiring `kind` at the base would be unearned. Future leaves that\n * earn polymorphic dispatch override with a required literal at that\n * leaf (e.g. `override readonly kind = 'pack-contributed-kind' as const`).\n *\n * `IRNodeBase` carries no methods: the freeze-and-assign affordance\n * lives in the free `freezeNode` helper below. Keeping `freezeNode` out\n * of the class type means an emitted contract literal type\n * (`{ readonly kind: 'mongo-collection', ... }` or an unkeyed literal\n * like `{ nativeType, codecId, nullable }`) is structurally assignable\n * to its class type — a `protected freeze()` instance method would\n * otherwise leak into the public type surface and require the literal\n * to carry it too.\n *\n * Subclasses construct fields then call `freezeNode(this)` to seal the\n * instance. Frozen instances + plain readonly fields keep IR nodes\n * JSON-clean by construction, so `JSON.stringify(node)` produces canonical\n * JSON without a `toJSON()` method. The `ContractSerializer` SPI handles\n * round-trip from canonical JSON back to typed class instances.\n *\n * The name (`IRNode` / `IRNodeBase`) reflects the dual-hierarchy reality:\n * this base is the common root for both Contract IR and Schema IR class\n * hierarchies, not a Schema-IR-specific alphabet.\n */\n\nexport interface IRNode {\n readonly kind?: string;\n}\n\nexport abstract class IRNodeBase implements IRNode {\n abstract readonly kind?: string;\n}\n\n/**\n * Seal an IR class instance after its constructor has assigned all\n * fields. The free-helper form (rather than a `protected freeze()`\n * instance method) keeps the class type structurally narrow so emitted\n * contract literal types remain assignable to their class types.\n *\n * The helper name stays `freezeNode` — it operates on IR nodes\n * regardless of root naming.\n */\nexport function freezeNode<T extends IRNode>(node: T): T {\n Object.freeze(node);\n return node;\n}\n","import type { StorageNamespace } from '@prisma-next/contract/types';\nimport { type IRNode, IRNodeBase } from './ir-node';\n\n/**\n * Reserved sentinel namespace id for the late-bound storage slot —\n * the slot whose binding the target resolves at connection time\n * rather than at authoring time. Postgres uses it for `search_path`\n * late binding; SQLite uses it for the trivial singleton; Mongo uses\n * it for the connection's `db` binding.\n *\n * Materialised target-side as a singleton subclass of the target's\n * `NamespaceBase` concretion that overrides the namespace's\n * qualifier-emission methods to elide the prefix entirely. Call sites\n * stay polymorphic and never branch on `id === UNBOUND_NAMESPACE_ID`\n * — the singleton's overrides drop the qualifier so emitted SQL / Mongo\n * commands look unqualified.\n *\n * The double-underscore decoration marks the id as a framework-reserved\n * coordinate when it appears in a JSON envelope (cold-read-as-reserved\n * — no realistic collision with user-declared namespace names).\n *\n * Encoded as an exported const (rather than scattered string literals)\n * so the sentinel-id invariant is single-sourced: any production-source\n * site that constructs an unbound-namespace singleton imports this\n * constant.\n */\nexport const UNBOUND_NAMESPACE_ID = '__unbound__' as const;\n\n/**\n * Framework-level building block for a \"namespace\" — the database-level\n * grouping under which storage objects (tables, collections, enums, …)\n * reside. Each target's namespace concretion maps the framework concept to\n * a target-native binding:\n *\n * - Postgres: a schema (`CREATE SCHEMA …`); rendered as `\"<schema>\"`.\n * - SQLite: the singleton `UNBOUND_NAMESPACE_ID`; emitted SQL has no qualifier.\n * - Mongo: the connection's `db` field; addressed as a database name.\n *\n * See `UNBOUND_NAMESPACE_ID` above for the sentinel id and the\n * singleton-subclass pattern that materialises it.\n *\n * The framework promises only the coordinate (`id`) — the named storage\n * entities a namespace contains are family-typed (SQL contributes\n * `table` / `type`, Mongo contributes `collection`, future families pick\n * their own native idiom under `entries`). Generic consumers walking \"all\n * named entries\" go through a family-typed namespace, not the framework\n * `Namespace`.\n *\n * Every namespace concretion (e.g. family-built SQL namespaces,\n * `MongoUnboundNamespace`, target-promoted namespaces like\n * `PostgresSchema`) carries exactly: `id` (enumerable string),\n * `entries` (frozen object holding entity-kind slot maps), and `kind`\n * (non-enumerable string discriminator set via `Object.defineProperty`).\n * Each slot map under `entries` uses a singular essence key (`table`,\n * `type`, `collection`, …) mapping entity names to IR classes. No other\n * own-enumerable data lives on a namespace; non-entity computed data lives\n * on the surrounding storage or contract IR. The framework's\n * `elementCoordinates(storage)` walk relies on this invariant to enumerate\n * entities structurally without family-specific knowledge.\n */\nexport interface Namespace extends IRNode, StorageNamespace {\n readonly kind: string;\n readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>;\n}\n\nexport abstract class NamespaceBase extends IRNodeBase implements Namespace {\n abstract readonly id: string;\n abstract readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>;\n abstract override readonly kind: string;\n}\n","import { isPlainRecord } from '@prisma-next/contract/is-plain-record';\nimport type { StorageBase } from '@prisma-next/contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { IRNode } from './ir-node';\nimport type { Namespace } from './namespace';\n\nexport { isPlainRecord };\n\n/**\n * Canonical address for a named entity in Contract IR / Schema IR.\n *\n * `plane` is `'domain' | 'storage'`: which top-level contract plane the\n * entity lives on. Domain-side walks yield `plane: 'domain'` via\n * {@link domainElementCoordinates}; {@link elementCoordinates} over storage\n * yields `plane: 'storage'`.\n *\n * Cross-plane references obey a directional invariant: domain → storage is\n * allowed; storage → domain is forbidden. That rule is enforced by a\n * separate validator, not by constraining this coordinate shape — the\n * coordinate carries the axis the validator checks.\n *\n * Iteration order over namespace properties follows `Object.entries` order;\n * consumers that depend on ordering must sort.\n */\nexport interface EntityCoordinate {\n readonly plane: 'domain' | 'storage';\n readonly namespaceId: string;\n readonly entityKind: string;\n readonly entityName: string;\n}\n\n/**\n * Lazy walk over every named storage entity in a `Storage`-shaped\n * value, yielded as {@link EntityCoordinate} tuples with\n * `plane: 'storage'` (the parameter type binds the plane).\n *\n * Iterates each namespace's `entries` kind maps structurally. Skips\n * non-object `entries`; `id` and `kind` are not walked (`kind` is\n * non-enumerable on concretions). For every entity-kind key under\n * `entries` whose value is a non-null object, yields one coordinate per\n * entity name in that map. No family-specific kind vocabulary is required.\n */\nexport function* elementCoordinates(\n storage: Pick<StorageBase, 'namespaces'>,\n): Generator<EntityCoordinate> {\n for (const [namespaceId, ns] of Object.entries(storage.namespaces)) {\n const entries = ns.entries;\n if (entries === null || typeof entries !== 'object') continue;\n for (const [entityKind, kindMap] of Object.entries(entries)) {\n if (kindMap === null || typeof kindMap !== 'object') continue;\n for (const entityName of Object.keys(kindMap)) {\n yield { plane: 'storage', namespaceId, entityKind, entityName };\n }\n }\n }\n}\n\n/**\n * Looks up a single entity in a `Storage`-shaped value by its full coordinate.\n * Returns `undefined` if the namespace, entity kind, or entity name is absent.\n * The type parameter is a caller assertion — the walk itself is structural\n * and cannot verify the entity's shape.\n */\nexport function entityAt<T = unknown>(\n storage: Pick<StorageBase, 'namespaces'>,\n coord: Pick<EntityCoordinate, 'namespaceId' | 'entityKind' | 'entityName'>,\n): T | undefined {\n const ns = storage.namespaces[coord.namespaceId];\n if (ns === undefined) return undefined;\n const entries = ns.entries;\n if (!isPlainRecord(entries)) return undefined;\n const kindMap = entries[coord.entityKind];\n if (!isPlainRecord(kindMap)) return undefined;\n if (!Object.hasOwn(kindMap, coord.entityName)) return undefined;\n return blindCast<T | undefined, 'caller asserts the entity type at this coordinate'>(\n kindMap[coord.entityName],\n );\n}\n\n/**\n * Framework-level promise that every Contract IR / Schema IR carries a\n * collection of namespaces keyed by namespace id. Family storage\n * concretions (`SqlStorage`, `MongoStorage`) refine the shape with\n * family-specific fields (tables, collections, enums, …); target\n * concretions add target fields where the family vocabulary doesn't\n * reach.\n *\n * Keeping `namespaces` at the framework layer enforces that every storage\n * object — across any target — is namespace-scoped. The framework can\n * therefore walk the namespace map without knowing the family alphabet, and\n * the `(namespace.id, name)` keying that the verifier and planner depend on\n * is honest at every layer.\n *\n * Extends `IRNode` so the framework's IR-walking surfaces (verifiers,\n * serializers) can dispatch on `Storage`-typed fields through the same\n * IR-node alphabet as every other node — the structural dual already\n * holds in code (every concrete storage class extends an IR-node base);\n * the interface promotion makes the typing honest.\n *\n * **Persisted envelope shape is target-owned, not framework-promised.**\n * Whether the `namespaces` map appears in the on-disk JSON envelope is\n * a per-target decision made by `ContractSerializer.serializeContract`.\n * Some targets emit a JSON-clean namespace shape that round-trips\n * through `JSON.stringify` cleanly (SQL today via the family-layer\n * identity serializer); others ship runtime-only fields on their\n * namespace concretions and override `serializeContract` to strip\n * them (Mongo). Future open (F16): extend the per-target\n * `ContractSerializer` integration-test surface with an explicit\n * envelope-shape assertion for each target, so the strip-vs-pass-through\n * choice is locked at test time rather than implied by the override\n * presence/absence. Earned by PR2's per-target namespace lift, when\n * `PostgresSchema` / `SqliteUnboundDatabase` start carrying\n * target-specific fields.\n */\nexport interface Storage extends IRNode {\n readonly namespaces: Readonly<Record<string, Namespace>>;\n}\n"],"mappings":";;;;;;;;;;AAUA,UAAiB,yBACf,QAC6B;CAC7B,KAAK,MAAM,CAAC,aAAa,OAAO,OAAO,QAAQ,OAAO,UAAU,GAC9D,KAAK,MAAM,CAAC,YAAY,SAAS,OAAO,QAAQ,EAAE,GAAG;EACnD,IAAI,eAAe,MAAM;EACzB,IAAI,SAAS,QAAQ,OAAO,SAAS,UAAU;EAC/C,KAAK,MAAM,cAAc,OAAO,KAAK,IAAI,GACvC,MAAM;GAAE,OAAO;GAAU;GAAa;GAAY;EAAW;CAEjE;AAEJ;;;;;;;;;;;;;;;ACEA,SAAgB,yBACd,SACA,OACA,WACA,MACmD;CACnD,MAAM,SAA4D,CAAC;CACnE,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,OAAO,GAAG;EACpD,MAAM,aAAa,MAAM,IAAI,IAAI;EACjC,IAAI,eAAe,KAAA,GAAW;GAC5B,MAAM,QAAiC,CAAC;GACxC,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,GAC/C,MAAM,QAAQ,WAAW,UACvB,UAGE,KAAK,CACT;GAEF,OAAO,QAAQ,OAAO,OAAO,KAAK;EACpC,OAAO,IAAI,cAAc,SACvB,OAAO,QAAQ,OAAO,OAAO,MAAM;OAEnC,MAAM,IAAI,MACR,wBAAwB,KAAK,kBAAkB,QAAQ,IAAI,wDAC7D;CAEJ;CACA,OAAO;AACT;;;ACRA,IAAsB,aAAtB,MAAmD,CAEnD;;;;;;;;;;AAWA,SAAgB,WAA6B,MAAY;CACvD,OAAO,OAAO,IAAI;CAClB,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;ACnCA,MAAa,uBAAuB;AAuCpC,IAAsB,gBAAtB,cAA4C,WAAgC,CAI5E;;;;;;;;;;;;;;AC3BA,UAAiB,mBACf,SAC6B;CAC7B,KAAK,MAAM,CAAC,aAAa,OAAO,OAAO,QAAQ,QAAQ,UAAU,GAAG;EAClE,MAAM,UAAU,GAAG;EACnB,IAAI,YAAY,QAAQ,OAAO,YAAY,UAAU;EACrD,KAAK,MAAM,CAAC,YAAY,YAAY,OAAO,QAAQ,OAAO,GAAG;GAC3D,IAAI,YAAY,QAAQ,OAAO,YAAY,UAAU;GACrD,KAAK,MAAM,cAAc,OAAO,KAAK,OAAO,GAC1C,MAAM;IAAE,OAAO;IAAW;IAAa;IAAY;GAAW;EAElE;CACF;AACF;;;;;;;AAQA,SAAgB,SACd,SACA,OACe;CACf,MAAM,KAAK,QAAQ,WAAW,MAAM;CACpC,IAAI,OAAO,KAAA,GAAW,OAAO,KAAA;CAC7B,MAAM,UAAU,GAAG;CACnB,IAAI,CAAC,cAAc,OAAO,GAAG,OAAO,KAAA;CACpC,MAAM,UAAU,QAAQ,MAAM;CAC9B,IAAI,CAAC,cAAc,OAAO,GAAG,OAAO,KAAA;CACpC,IAAI,CAAC,OAAO,OAAO,SAAS,MAAM,UAAU,GAAG,OAAO,KAAA;CACtD,OAAO,UACL,QAAQ,MAAM,WAChB;AACF"} | ||
| {"version":3,"file":"ir.mjs","names":[],"sources":["../src/ir/ir-node.ts","../src/ir/namespace.ts","../src/ir/contract-view.ts","../src/ir/domain.ts","../src/ir/entity-kind.ts","../src/ir/storage.ts"],"sourcesContent":["/**\n * Framework-level IR alphabet.\n *\n * The framework's contribution to Contract IR / Schema IR is a common\n * root for the IR class hierarchy and a freeze affordance. Family\n * abstract bases (e.g. `SqlNode`, `MongoSchemaIRNode`) refine the alphabet\n * for their family shape; targets ship the concrete classes.\n *\n * `kind` is an optional discriminator on the base. Families and leaves\n * that benefit from discriminated-union dispatch declare their own\n * literal `kind` at the level that earns it — Mongo leaves carry\n * per-class literals (`readonly kind = 'mongo-collection' as const`)\n * because Mongo IR has polymorphic walkers; SQL declares a single\n * family-level `kind = 'sql'` on `SqlNode` because SQL IR has no\n * polymorphic dispatch today. No framework consumer dispatches on\n * `IRNode.kind` at the BASE type — every dispatch site narrows\n * through a union of leaves where each leaf carries a literal kind, so\n * requiring `kind` at the base would be unearned. Future leaves that\n * earn polymorphic dispatch override with a required literal at that\n * leaf (e.g. `override readonly kind = 'pack-contributed-kind' as const`).\n *\n * `IRNodeBase` carries no methods: the freeze-and-assign affordance\n * lives in the free `freezeNode` helper below. Keeping `freezeNode` out\n * of the class type means an emitted contract literal type\n * (`{ readonly kind: 'mongo-collection', ... }` or an unkeyed literal\n * like `{ nativeType, codecId, nullable }`) is structurally assignable\n * to its class type — a `protected freeze()` instance method would\n * otherwise leak into the public type surface and require the literal\n * to carry it too.\n *\n * Subclasses construct fields then call `freezeNode(this)` to seal the\n * instance. Frozen instances + plain readonly fields keep IR nodes\n * JSON-clean by construction, so `JSON.stringify(node)` produces canonical\n * JSON without a `toJSON()` method. The `ContractSerializer` SPI handles\n * round-trip from canonical JSON back to typed class instances.\n *\n * The name (`IRNode` / `IRNodeBase`) reflects the dual-hierarchy reality:\n * this base is the common root for both Contract IR and Schema IR class\n * hierarchies, not a Schema-IR-specific alphabet.\n */\n\nexport interface IRNode {\n readonly kind?: string;\n}\n\nexport abstract class IRNodeBase implements IRNode {\n abstract readonly kind?: string;\n}\n\n/**\n * Seal an IR class instance after its constructor has assigned all\n * fields. The free-helper form (rather than a `protected freeze()`\n * instance method) keeps the class type structurally narrow so emitted\n * contract literal types remain assignable to their class types.\n *\n * The helper name stays `freezeNode` — it operates on IR nodes\n * regardless of root naming.\n */\nexport function freezeNode<T extends IRNode>(node: T): T {\n Object.freeze(node);\n return node;\n}\n","import type { StorageNamespace } from '@prisma-next/contract/types';\nimport { type IRNode, IRNodeBase } from './ir-node';\n\n/**\n * Reserved sentinel namespace id for the late-bound storage slot —\n * the slot whose binding the target resolves at connection time\n * rather than at authoring time. Postgres uses it for `search_path`\n * late binding; SQLite uses it for the trivial singleton; Mongo uses\n * it for the connection's `db` binding.\n *\n * Materialised target-side as a singleton subclass of the target's\n * `NamespaceBase` concretion that overrides the namespace's\n * qualifier-emission methods to elide the prefix entirely. Call sites\n * stay polymorphic and never branch on `id === UNBOUND_NAMESPACE_ID`\n * — the singleton's overrides drop the qualifier so emitted SQL / Mongo\n * commands look unqualified.\n *\n * The double-underscore decoration marks the id as a framework-reserved\n * coordinate when it appears in a JSON envelope (cold-read-as-reserved\n * — no realistic collision with user-declared namespace names).\n *\n * Encoded as an exported const (rather than scattered string literals)\n * so the sentinel-id invariant is single-sourced: any production-source\n * site that constructs an unbound-namespace singleton imports this\n * constant.\n */\nexport const UNBOUND_NAMESPACE_ID = '__unbound__' as const;\n\n/**\n * Framework-level building block for a \"namespace\" — the database-level\n * grouping under which storage objects (tables, collections, enums, …)\n * reside. Each target's namespace concretion maps the framework concept to\n * a target-native binding:\n *\n * - Postgres: a schema (`CREATE SCHEMA …`); rendered as `\"<schema>\"`.\n * - SQLite: the singleton `UNBOUND_NAMESPACE_ID`; emitted SQL has no qualifier.\n * - Mongo: the connection's `db` field; addressed as a database name.\n *\n * See `UNBOUND_NAMESPACE_ID` above for the sentinel id and the\n * singleton-subclass pattern that materialises it.\n *\n * The framework promises only the coordinate (`id`) — the named storage\n * entities a namespace contains are family-typed (SQL contributes\n * `table` / `type`, Mongo contributes `collection`, future families pick\n * their own native idiom under `entries`). Generic consumers walking \"all\n * named entries\" go through a family-typed namespace, not the framework\n * `Namespace`.\n *\n * Every namespace concretion (e.g. family-built SQL namespaces,\n * `MongoUnboundNamespace`, target-promoted namespaces like\n * `PostgresSchema`) carries exactly: `id` (enumerable string),\n * `entries` (frozen object holding entity-kind slot maps), and `kind`\n * (non-enumerable string discriminator set via `Object.defineProperty`).\n * Each slot map under `entries` uses a singular essence key (`table`,\n * `type`, `collection`, …) mapping entity names to IR classes. No other\n * own-enumerable data lives on a namespace; non-entity computed data lives\n * on the surrounding storage or contract IR. The framework's\n * `elementCoordinates(storage)` walk relies on this invariant to enumerate\n * entities structurally without family-specific knowledge.\n */\nexport interface Namespace extends IRNode, StorageNamespace {\n readonly kind: string;\n readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>;\n}\n\nexport abstract class NamespaceBase extends IRNodeBase implements Namespace {\n abstract readonly id: string;\n abstract readonly entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>;\n abstract override readonly kind: string;\n}\n","import { blindCast } from '@prisma-next/utils/casts';\nimport { UNBOUND_NAMESPACE_ID } from './namespace';\nimport type { Storage } from './storage';\n\n/**\n * Extracts the entries map of a contract's single default namespace\n * (`UNBOUND_NAMESPACE_ID`). Both single-namespace families (Mongo, SQLite)\n * store all entities under this one namespace.\n */\nexport type DefaultNamespaceEntries<TStorage extends { readonly namespaces: object }> =\n TStorage['namespaces'] extends Record<typeof UNBOUND_NAMESPACE_ID, { readonly entries: infer E }>\n ? E\n : never;\n\n/**\n * Generic single-namespace projection shape — one namespace's entity-kind slots.\n * A family supplies:\n * - `TEntries` — the family's `*NamespaceEntries` type for the namespace.\n * - `TBuiltinKinds` — the union of the family's statically-named built-in kind\n * keys (Mongo `'collection'`; SQL `'table' | 'valueSet'`).\n *\n * Each built-in kind becomes a top-level accessor; the remaining pack-contributed\n * kinds stay under `.entries` (keyed by their registered singular kind string).\n *\n * A built-in kind that the emitted contract does not carry resolves to an empty\n * map (`Record<string, never>`), matching the runtime which always materializes\n * each built-in slot. The `& string` index-signature member of `TEntries` is\n * excluded from `.entries` so only the literal pack-kind keys remain.\n */\nexport type SingleNamespaceView<TEntries, TBuiltinKinds extends string> = {\n readonly [K in TBuiltinKinds]-?: K extends keyof TEntries\n ? NonNullable<TEntries[K]>\n : Record<string, never>;\n} & {\n readonly entries: {\n readonly [K in Exclude<keyof TEntries, TBuiltinKinds | number | symbol> as string extends K\n ? never\n : K]: TEntries[K];\n };\n};\n\n/** The `entries` shape of one namespace in a storage map. */\ntype EntriesOf<TNamespace> = TNamespace extends { readonly entries: infer E } ? E : never;\n\n/**\n * The namespace-keyed entity-view map — every storage namespace keyed by its raw\n * id, each projected to its {@link SingleNamespaceView}. Mirrors\n * `NamespacedEnums` from `@prisma-next/contract/enum-accessor`: the migration\n * author's storage-side `view.namespace.<nsId>` is the twin of the runtime's\n * `db.enums.<nsId>`. Nesting the schema map under one fixed `namespace` member\n * makes it collision-proof — a schema named `storage` is `view.namespace.storage`,\n * never a contract-root key.\n */\nexport type NamespacedEntities<\n TStorage extends { readonly namespaces: object },\n TBuiltinKinds extends string,\n> = {\n readonly [Ns in keyof TStorage['namespaces']]: SingleNamespaceView<\n EntriesOf<TStorage['namespaces'][Ns]>,\n TBuiltinKinds\n >;\n};\n\n/**\n * Projects one namespace's `entries` into the view shape: each built-in kind\n * becomes a top-level slot (materialized empty if absent), and the remaining\n * pack-contributed kinds sit under `.entries`. Shared by the single-namespace\n * builder and the namespace-map builder.\n */\nexport function promoteBuiltinKinds<TView>(\n entries: Readonly<Record<string, unknown>>,\n builtinKinds: readonly string[],\n): TView {\n const view: Record<string, unknown> = {};\n const rest: Record<string, unknown> = {};\n for (const [kind, kindMap] of Object.entries(entries)) {\n if (builtinKinds.includes(kind)) {\n view[kind] = kindMap;\n } else {\n rest[kind] = kindMap;\n }\n }\n for (const kind of builtinKinds) {\n if (!(kind in view)) {\n view[kind] = {};\n }\n }\n view['entries'] = rest;\n return blindCast<TView, 'view is built to the SingleNamespaceView shape the caller parametrizes'>(\n view,\n );\n}\n\n/**\n * Builds one namespace's entity view: promotes the given built-in kind slots to\n * top-level for the default (`UNBOUND_NAMESPACE_ID`) namespace. Single-namespace\n * targets (Mongo, SQLite) use this to unwrap their sole namespace to the root.\n *\n * Throws if the contract has no default (`UNBOUND_NAMESPACE_ID`) namespace.\n */\nexport function buildSingleNamespaceView<TView>(\n storage: Storage,\n builtinKinds: readonly string[],\n): TView {\n const defaultNs = storage.namespaces[UNBOUND_NAMESPACE_ID];\n if (defaultNs === undefined) {\n throw new Error(`ContractView: contract has no default namespace (${UNBOUND_NAMESPACE_ID})`);\n }\n const entries = blindCast<\n Record<string, unknown>,\n 'Namespace.entries is the open ADR 224 dictionary Record<string, Record<string, unknown>>'\n >(defaultNs.entries);\n return promoteBuiltinKinds<TView>(entries, builtinKinds);\n}\n\n/**\n * Builds the namespace-keyed entity-view map (`{ <nsId>: SingleNamespaceView }`)\n * for every namespace in the storage, keyed by raw namespace id. Mirrors\n * `buildNamespacedEnums(domain)` — the storage-side twin.\n */\nexport function buildNamespacedEntities<TMap>(\n storage: Storage,\n builtinKinds: readonly string[],\n): TMap {\n const out: Record<string, unknown> = {};\n for (const [nsId, ns] of Object.entries(storage.namespaces)) {\n out[nsId] = promoteBuiltinKinds(\n blindCast<\n Readonly<Record<string, unknown>>,\n 'Namespace.entries is the open ADR 224 dictionary Record<string, Record<string, unknown>>'\n >(ns.entries),\n builtinKinds,\n );\n }\n return blindCast<\n TMap,\n 'each namespace projected to its SingleNamespaceView; keys mirror the storage namespace ids'\n >(out);\n}\n","import type { ApplicationDomain } from '@prisma-next/contract/types';\nimport type { EntityCoordinate } from './storage';\n\n/**\n * Lazy walk over every named domain entity in a {@link ApplicationDomain},\n * yielded as {@link EntityCoordinate} tuples with `plane: 'domain'`.\n *\n * Same structural rules as {@link elementCoordinates} over storage: skip\n * scalar `id`; each other object-valued property is an entity-kind slot.\n */\nexport function* domainElementCoordinates(\n domain: Pick<ApplicationDomain, 'namespaces'>,\n): Generator<EntityCoordinate> {\n for (const [namespaceId, ns] of Object.entries(domain.namespaces)) {\n for (const [entityKind, slot] of Object.entries(ns)) {\n if (entityKind === 'id') continue;\n if (slot === null || typeof slot !== 'object') continue;\n for (const entityName of Object.keys(slot)) {\n yield { plane: 'domain', namespaceId, entityKind, entityName };\n }\n }\n }\n}\n","import { blindCast } from '@prisma-next/utils/casts';\nimport type { Type } from 'arktype';\n\nexport interface EntityKindDescriptor<Input, Node> {\n readonly kind: string;\n // Type<unknown>, not Type<Input>: AnyEntityKindDescriptor widens Input to never, which would force an unusable Type<never>; concrete descriptors still carry their real schema.\n readonly schema: Type<unknown>;\n readonly construct: (input: Input) => Node;\n}\n\nexport type AnyEntityKindDescriptor = EntityKindDescriptor<never, unknown>;\n\n/**\n * Hydrates a namespace's entities from raw JSON maps into IR class instances.\n *\n * For each kind in `entries`: if the descriptor map has a descriptor,\n * construct each inner-map value; otherwise freeze-and-carry (`'carry'`)\n * or throw naming the kind and nsId (`'fail'`).\n *\n * The single boundary cast hands `value` to `descriptor.construct` as its\n * `Input`. The value satisfies the kind's `Input` either by the\n * entries-input contract at authoring time or by prior `validateStorage`\n * validation at hydration time.\n */\nexport function hydrateNamespaceEntities(\n entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>,\n kinds: ReadonlyMap<string, AnyEntityKindDescriptor>,\n onUnknown: 'carry' | 'fail',\n nsId?: string,\n): Record<string, Readonly<Record<string, unknown>>> {\n const result: Record<string, Readonly<Record<string, unknown>>> = {};\n for (const [kind, rawMap] of Object.entries(entries)) {\n const descriptor = kinds.get(kind);\n if (descriptor !== undefined) {\n const built: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(rawMap)) {\n built[name] = descriptor.construct(\n blindCast<\n never,\n \"value is this kind's descriptor Input: when authoring, the typed entries-input contract produces it; when hydrating, it was validated against descriptor.schema before this loop. The never target is AnyEntityKindDescriptor's erased Input parameter.\"\n >(value),\n );\n }\n result[kind] = Object.freeze(built);\n } else if (onUnknown === 'carry') {\n result[kind] = Object.freeze(rawMap);\n } else {\n throw new Error(\n `Unknown entries key \"${kind}\" in namespace \"${nsId ?? '?'}\"; no hydration factory registered for this entity kind`,\n );\n }\n }\n return result;\n}\n","import { isPlainRecord } from '@prisma-next/contract/is-plain-record';\nimport type { StorageBase } from '@prisma-next/contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { IRNode } from './ir-node';\nimport type { Namespace } from './namespace';\n\nexport { isPlainRecord };\n\n/**\n * Canonical address for a named entity in Contract IR / Schema IR.\n *\n * `plane` is `'domain' | 'storage'`: which top-level contract plane the\n * entity lives on. Domain-side walks yield `plane: 'domain'` via\n * {@link domainElementCoordinates}; {@link elementCoordinates} over storage\n * yields `plane: 'storage'`.\n *\n * Cross-plane references obey a directional invariant: domain → storage is\n * allowed; storage → domain is forbidden. That rule is enforced by a\n * separate validator, not by constraining this coordinate shape — the\n * coordinate carries the axis the validator checks.\n *\n * Iteration order over namespace properties follows `Object.entries` order;\n * consumers that depend on ordering must sort.\n */\nexport interface EntityCoordinate {\n readonly plane: 'domain' | 'storage';\n readonly namespaceId: string;\n readonly entityKind: string;\n readonly entityName: string;\n}\n\n/**\n * Lazy walk over every named storage entity in a `Storage`-shaped\n * value, yielded as {@link EntityCoordinate} tuples with\n * `plane: 'storage'` (the parameter type binds the plane).\n *\n * Iterates each namespace's `entries` kind maps structurally. Skips\n * non-object `entries`; `id` and `kind` are not walked (`kind` is\n * non-enumerable on concretions). For every entity-kind key under\n * `entries` whose value is a non-null object, yields one coordinate per\n * entity name in that map. No family-specific kind vocabulary is required.\n */\nexport function* elementCoordinates(\n storage: Pick<StorageBase, 'namespaces'>,\n): Generator<EntityCoordinate> {\n for (const [namespaceId, ns] of Object.entries(storage.namespaces)) {\n const entries = ns.entries;\n if (entries === null || typeof entries !== 'object') continue;\n for (const [entityKind, kindMap] of Object.entries(entries)) {\n if (kindMap === null || typeof kindMap !== 'object') continue;\n for (const entityName of Object.keys(kindMap)) {\n yield { plane: 'storage', namespaceId, entityKind, entityName };\n }\n }\n }\n}\n\n/**\n * Looks up a single entity in a `Storage`-shaped value by its full coordinate.\n * Returns `undefined` if the namespace, entity kind, or entity name is absent.\n * The type parameter is a caller assertion — the walk itself is structural\n * and cannot verify the entity's shape.\n */\nexport function entityAt<T = unknown>(\n storage: Pick<StorageBase, 'namespaces'>,\n coord: Pick<EntityCoordinate, 'namespaceId' | 'entityKind' | 'entityName'>,\n): T | undefined {\n const ns = storage.namespaces[coord.namespaceId];\n if (ns === undefined) return undefined;\n const entries = ns.entries;\n if (!isPlainRecord(entries)) return undefined;\n const kindMap = entries[coord.entityKind];\n if (!isPlainRecord(kindMap)) return undefined;\n if (!Object.hasOwn(kindMap, coord.entityName)) return undefined;\n return blindCast<T | undefined, 'caller asserts the entity type at this coordinate'>(\n kindMap[coord.entityName],\n );\n}\n\n/**\n * Framework-level promise that every Contract IR / Schema IR carries a\n * collection of namespaces keyed by namespace id. Family storage\n * concretions (`SqlStorage`, `MongoStorage`) refine the shape with\n * family-specific fields (tables, collections, enums, …); target\n * concretions add target fields where the family vocabulary doesn't\n * reach.\n *\n * Keeping `namespaces` at the framework layer enforces that every storage\n * object — across any target — is namespace-scoped. The framework can\n * therefore walk the namespace map without knowing the family alphabet, and\n * the `(namespace.id, name)` keying that the verifier and planner depend on\n * is honest at every layer.\n *\n * Extends `IRNode` so the framework's IR-walking surfaces (verifiers,\n * serializers) can dispatch on `Storage`-typed fields through the same\n * IR-node alphabet as every other node — the structural dual already\n * holds in code (every concrete storage class extends an IR-node base);\n * the interface promotion makes the typing honest.\n *\n * **Persisted envelope shape is target-owned, not framework-promised.**\n * Whether the `namespaces` map appears in the on-disk JSON envelope is\n * a per-target decision made by `ContractSerializer.serializeContract`.\n * Some targets emit a JSON-clean namespace shape that round-trips\n * through `JSON.stringify` cleanly (SQL today via the family-layer\n * identity serializer); others ship runtime-only fields on their\n * namespace concretions and override `serializeContract` to strip\n * them (Mongo). Future open (F16): extend the per-target\n * `ContractSerializer` integration-test surface with an explicit\n * envelope-shape assertion for each target, so the strip-vs-pass-through\n * choice is locked at test time rather than implied by the override\n * presence/absence. Earned by PR2's per-target namespace lift, when\n * `PostgresSchema` / `SqliteUnboundDatabase` start carrying\n * target-specific fields.\n */\nexport interface Storage extends IRNode {\n readonly namespaces: Readonly<Record<string, Namespace>>;\n}\n"],"mappings":"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"} |
+7
-7
| { | ||
| "name": "@prisma-next/framework-components", | ||
| "version": "0.14.0-dev.31", | ||
| "version": "0.14.0-dev.32", | ||
| "license": "Apache-2.0", | ||
@@ -9,6 +9,6 @@ "type": "module", | ||
| "dependencies": { | ||
| "@prisma-next/contract": "0.14.0-dev.31", | ||
| "@prisma-next/operations": "0.14.0-dev.31", | ||
| "@prisma-next/ts-render": "0.14.0-dev.31", | ||
| "@prisma-next/utils": "0.14.0-dev.31", | ||
| "@prisma-next/contract": "0.14.0-dev.32", | ||
| "@prisma-next/operations": "0.14.0-dev.32", | ||
| "@prisma-next/ts-render": "0.14.0-dev.32", | ||
| "@prisma-next/utils": "0.14.0-dev.32", | ||
| "@standard-schema/spec": "^1.1.0", | ||
@@ -18,4 +18,4 @@ "arktype": "^2.2.0" | ||
| "devDependencies": { | ||
| "@prisma-next/tsconfig": "0.14.0-dev.31", | ||
| "@prisma-next/tsdown": "0.14.0-dev.31", | ||
| "@prisma-next/tsconfig": "0.14.0-dev.32", | ||
| "@prisma-next/tsdown": "0.14.0-dev.32", | ||
| "tsdown": "0.22.1", | ||
@@ -22,0 +22,0 @@ "typescript": "5.9.3", |
+10
-0
@@ -0,1 +1,11 @@ | ||
| export type { | ||
| DefaultNamespaceEntries, | ||
| NamespacedEntities, | ||
| SingleNamespaceView, | ||
| } from '../ir/contract-view'; | ||
| export { | ||
| buildNamespacedEntities, | ||
| buildSingleNamespaceView, | ||
| promoteBuiltinKinds, | ||
| } from '../ir/contract-view'; | ||
| export { domainElementCoordinates } from '../ir/domain'; | ||
@@ -2,0 +12,0 @@ export type { AnyEntityKindDescriptor, EntityKindDescriptor } from '../ir/entity-kind'; |
976056
1.89%120
0.84%9274
1.99%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed