@prisma-next/framework-components 0.13.0-dev.2 → 0.13.0-dev.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring.d.mts +2 -2
- package/dist/authoring.mjs +1 -1
- package/dist/{codec-DCQAerzB.d.mts → codec-types-29q8imKF.d.mts} +84 -67
- package/dist/codec-types-29q8imKF.d.mts.map +1 -0
- package/dist/codec.d.mts +23 -2
- package/dist/codec.d.mts.map +1 -1
- package/dist/codec.mjs +2 -1
- package/dist/codec.mjs.map +1 -1
- package/dist/components.d.mts +1 -1
- package/dist/control.d.mts +12 -24
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +11 -1
- package/dist/control.mjs.map +1 -1
- package/dist/execution.d.mts +1 -1
- package/dist/{framework-authoring-R0TYCkvG.d.mts → framework-authoring-BXiebZGn.d.mts} +92 -9
- package/dist/framework-authoring-BXiebZGn.d.mts.map +1 -0
- package/dist/{framework-authoring-CnwPJCO4.mjs → framework-authoring-Dv5F3EFC.mjs} +51 -24
- package/dist/framework-authoring-Dv5F3EFC.mjs.map +1 -0
- package/dist/{framework-components-DDQXmW0b.d.mts → framework-components-B-ABhSOs.d.mts} +3 -3
- package/dist/{framework-components-DDQXmW0b.d.mts.map → framework-components-B-ABhSOs.d.mts.map} +1 -1
- package/dist/{psl-ast-Cn50B-UG.d.mts → psl-ast-CHgjnZ3h.d.mts} +4 -4
- package/dist/{psl-ast-Cn50B-UG.d.mts.map → psl-ast-CHgjnZ3h.d.mts.map} +1 -1
- package/dist/psl-ast.d.mts +4 -4
- package/dist/psl-ast.mjs +11 -9
- package/dist/psl-ast.mjs.map +1 -1
- package/dist/resolve-codec-DR7uyr_c.mjs +47 -0
- package/dist/resolve-codec-DR7uyr_c.mjs.map +1 -0
- package/dist/runtime-error-B2gWOtgH.mjs +37 -0
- package/dist/runtime-error-B2gWOtgH.mjs.map +1 -0
- package/dist/runtime.d.mts +12 -10
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -33
- package/dist/runtime.mjs.map +1 -1
- package/package.json +7 -7
- package/src/control/control-migration-types.ts +5 -22
- package/src/control/control-stack.ts +20 -3
- package/src/control/psl-ast.ts +4 -1
- package/src/control/psl-extension-block-validator.ts +11 -9
- package/src/execution/runtime-error.ts +5 -55
- package/src/exports/authoring.ts +1 -0
- package/src/exports/codec.ts +2 -0
- package/src/exports/control.ts +0 -1
- package/src/shared/codec-types.ts +19 -1
- package/src/shared/framework-authoring.ts +118 -35
- package/src/shared/psl-extension-block.ts +56 -5
- package/src/shared/resolve-codec.ts +64 -0
- package/src/shared/runtime-error.ts +50 -0
- package/dist/codec-DCQAerzB.d.mts.map +0 -1
- package/dist/framework-authoring-CnwPJCO4.mjs.map +0 -1
- package/dist/framework-authoring-R0TYCkvG.d.mts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-authoring-Dv5F3EFC.mjs","names":[],"sources":["../src/shared/framework-authoring.ts"],"sourcesContent":["import type {\n ColumnDefault,\n ExecutionMutationDefaultPhases,\n ExecutionMutationDefaultValue,\n} from '@prisma-next/contract/types';\nimport {\n isColumnDefaultLiteralInputValue,\n isExecutionMutationDefaultValue,\n} from '@prisma-next/contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Type } from 'arktype';\nimport type { CodecLookup } from './codec-types';\nimport type { PslBlockParam } from './psl-extension-block';\n\nexport type AuthoringArgRef = {\n readonly kind: 'arg';\n readonly index: number;\n readonly path?: readonly string[];\n readonly default?: AuthoringTemplateValue;\n};\n\nexport type AuthoringTemplateValue =\n | string\n | number\n | boolean\n | null\n | AuthoringArgRef\n | readonly AuthoringTemplateValue[]\n | { readonly [key: string]: AuthoringTemplateValue };\n\ninterface AuthoringArgumentDescriptorCommon {\n readonly name?: string;\n readonly optional?: boolean;\n}\n\nexport type AuthoringArgumentDescriptor = AuthoringArgumentDescriptorCommon &\n (\n | { readonly kind: 'string' }\n | { readonly kind: 'boolean' }\n | {\n readonly kind: 'number';\n readonly integer?: boolean;\n readonly minimum?: number;\n readonly maximum?: number;\n }\n | { readonly kind: 'stringArray' }\n | {\n readonly kind: 'object';\n readonly properties: Record<string, AuthoringArgumentDescriptor>;\n }\n );\n\nexport interface AuthoringStorageTypeTemplate {\n readonly codecId: string;\n readonly nativeType: AuthoringTemplateValue;\n readonly typeParams?: Record<string, AuthoringTemplateValue>;\n}\n\nexport interface AuthoringTypeConstructorDescriptor {\n readonly kind: 'typeConstructor';\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output: AuthoringStorageTypeTemplate;\n}\n\nexport interface AuthoringColumnDefaultTemplateLiteral {\n readonly kind: 'literal';\n readonly value: AuthoringTemplateValue;\n}\n\nexport interface AuthoringColumnDefaultTemplateFunction {\n readonly kind: 'function';\n readonly expression: AuthoringTemplateValue;\n}\n\nexport type AuthoringColumnDefaultTemplate =\n | AuthoringColumnDefaultTemplateLiteral\n | AuthoringColumnDefaultTemplateFunction;\n\nexport interface AuthoringExecutionDefaultsTemplate {\n readonly onCreate?: AuthoringTemplateValue;\n readonly onUpdate?: AuthoringTemplateValue;\n}\n\nexport interface AuthoringFieldPresetOutput extends AuthoringStorageTypeTemplate {\n readonly nullable?: boolean;\n readonly default?: AuthoringColumnDefaultTemplate;\n readonly executionDefaults?: AuthoringExecutionDefaultsTemplate;\n readonly id?: boolean;\n readonly unique?: boolean;\n}\n\nexport interface AuthoringFieldPresetDescriptor {\n readonly kind: 'fieldPreset';\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output: AuthoringFieldPresetOutput;\n}\n\nexport type AuthoringTypeNamespace = {\n readonly [name: string]: AuthoringTypeConstructorDescriptor | AuthoringTypeNamespace;\n};\n\nexport type AuthoringFieldNamespace = {\n readonly [name: string]: AuthoringFieldPresetDescriptor | AuthoringFieldNamespace;\n};\n\n/**\n * Context surfaced to entity-type factories at call time. Currently a\n * placeholder — sharpened as concrete consumers (enum, namespace, …)\n * discover what the factory actually needs to read (codec lookup,\n * namespace registry, …).\n */\n/**\n * A write-only sink that a factory may push authoring-time diagnostics into.\n * The concrete type pushed must be structurally compatible with whatever the\n * consumer accumulates (typically `ContractSourceDiagnostic[]`); the framework\n * layer deliberately does not depend on that concrete type.\n */\nexport interface AuthoringDiagnosticSink {\n push(d: {\n readonly code: string;\n readonly message: string;\n readonly sourceId: string;\n readonly span?: unknown;\n }): void;\n}\n\nexport interface AuthoringEntityContext {\n readonly family: string;\n readonly target: string;\n /** Codec registry available to factories that need to validate or decode values. */\n readonly codecLookup?: CodecLookup;\n /** Source file identifier threaded into diagnostics emitted by the factory. */\n readonly sourceId?: string;\n /** Push channel for authoring-time diagnostics emitted by the factory. */\n readonly diagnostics?: AuthoringDiagnosticSink;\n}\n\nexport interface AuthoringEntityTypeTemplateOutput {\n readonly template: AuthoringTemplateValue;\n}\n\n/**\n * Default `Input = never` is load-bearing for pack-bag-driven type\n * narrowing. Factory parameter positions are contravariant, so a pack\n * literal declaring `factory: (input: DemoEntityInput) => DemoEntity`\n * is only assignable to the base descriptor's factory shape if the\n * base's input is `never` (the bottom of the contravariant position).\n * The concrete input/output types are recovered at the helper-derivation\n * site via `EntityHelperFunction<Descriptor>`'s conditional inference,\n * which reads them from the pack's `as const` literal factory signature\n * — the base widening does not erase the literal because `satisfies`\n * does not widen the declared type.\n */\nexport interface AuthoringEntityTypeFactoryOutput<Input = never, Output = unknown> {\n readonly factory: (input: Input, ctx: AuthoringEntityContext) => Output;\n}\n\nexport interface AuthoringEntityTypeDescriptor<Input = never, Output = unknown> {\n readonly kind: 'entity';\n readonly discriminator: string;\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output:\n | AuthoringEntityTypeTemplateOutput\n | AuthoringEntityTypeFactoryOutput<Input, Output>;\n /**\n * arktype schema fragment for one entry whose envelope `kind` matches\n * this descriptor's {@link discriminator}. The family validator composes\n * contributed fragments into the per-namespace entry schema at\n * validator construction time so the structural check covers\n * pack-introduced kinds without the family core hard-coding the schema.\n *\n * Hydration uses {@link AuthoringEntityTypeFactoryOutput.factory}\n * directly — the wire shape conforms structurally to the factory's\n * `Input` after `validatorSchema` validates it.\n */\n readonly validatorSchema?: Type<unknown>;\n}\n\nexport type AuthoringEntityTypeNamespace = {\n readonly [name: string]: AuthoringEntityTypeDescriptor | AuthoringEntityTypeNamespace;\n};\n\n/**\n * Declarative descriptor for an extension-contributed top-level PSL block.\n *\n * An extension registers one of these per keyword it contributes. The\n * framework owns the generic parser, validator, and printer — no\n * parsing or printing code runs from the extension.\n *\n * - `keyword` is the PSL top-level identifier this descriptor claims\n * (`policy_select`, `role`, …).\n * - `discriminator` is the routing key used by the printer dispatch and\n * the `entityTypes` lowering factory lookup. Convention:\n * `<target-or-family>-<kind>` (`postgres-policy-select`).\n * - `name.required` declares whether the block must have a name token\n * after the keyword. Currently always `true` — anonymous blocks are\n * not part of the closed-grammar premise — but the field is explicit\n * so the type can evolve without a breaking change.\n * - `parameters` maps parameter names to their value-kind descriptors\n * (`ref` / `value` / `option` / `list`). The generic parser and\n * validator interpret these; the extension supplies no parser or\n * printer function.\n */\nexport interface AuthoringPslBlockDescriptor {\n readonly kind: 'pslBlock';\n readonly keyword: string;\n readonly discriminator: string;\n readonly name: { readonly required: boolean };\n readonly parameters: Record<string, PslBlockParam>;\n /**\n * When `true`, the block body accepts a variadic tail of parameters beyond\n * the declared set. The block body may contain: fields (model-style),\n * `key = value` parameters, and `@@` attributes. With `variadicParameters`,\n * bare identifiers (keys without a `= value`) and undeclared `key = value`\n * pairs flow into the variadic tail — their semantics belong to the\n * lowering, not the parser.\n *\n * A key that IS declared in `parameters` must still be supplied as\n * `key = value`; a bare occurrence of a declared key is a diagnostic.\n *\n * When `false` (default), the validator emits `PSL_EXTENSION_UNKNOWN_PARAMETER`\n * for keys absent from `parameters`.\n */\n readonly variadicParameters?: boolean;\n}\n\nexport type AuthoringPslBlockDescriptorNamespace = {\n readonly [name: string]: AuthoringPslBlockDescriptor | AuthoringPslBlockDescriptorNamespace;\n};\n\nexport interface AuthoringContributions {\n readonly type?: AuthoringTypeNamespace;\n readonly field?: AuthoringFieldNamespace;\n readonly entityTypes?: AuthoringEntityTypeNamespace;\n /**\n * Registry of declarative block descriptors this contribution registers,\n * keyed by arbitrary path segments. Each leaf is an\n * {@link AuthoringPslBlockDescriptor} that claims a PSL top-level keyword.\n * The framework owns the generic parser, validator, and printer; the\n * contribution supplies only these declarative descriptors.\n *\n * Contrast with the parsed block nodes themselves, which live in a\n * namespace's `entries` under their discriminator key; this field holds the\n * registry of descriptors that teach the parser how to read those blocks.\n */\n readonly pslBlockDescriptors?: AuthoringPslBlockDescriptorNamespace;\n}\n\nexport function isAuthoringArgRef(value: unknown): value is AuthoringArgRef {\n if (typeof value !== 'object' || value === null || (value as { kind?: unknown }).kind !== 'arg') {\n return false;\n }\n const { index, path } = value as { index?: unknown; path?: unknown };\n if (typeof index !== 'number' || !Number.isInteger(index) || index < 0) {\n return false;\n }\n if (path !== undefined && (!Array.isArray(path) || path.some((s) => typeof s !== 'string'))) {\n return false;\n }\n return true;\n}\n\nfunction isAuthoringTemplateRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function isAuthoringTypeConstructorDescriptor(\n value: unknown,\n): value is AuthoringTypeConstructorDescriptor {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { kind?: unknown }).kind === 'typeConstructor' &&\n typeof (value as { output?: unknown }).output === 'object' &&\n (value as { output?: unknown }).output !== null\n );\n}\n\nexport function isAuthoringFieldPresetDescriptor(\n value: unknown,\n): value is AuthoringFieldPresetDescriptor {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { kind?: unknown }).kind === 'fieldPreset' &&\n typeof (value as { output?: unknown }).output === 'object' &&\n (value as { output?: unknown }).output !== null\n );\n}\n\nexport function isAuthoringEntityTypeDescriptor(\n value: unknown,\n): value is AuthoringEntityTypeDescriptor {\n if (\n typeof value !== 'object' ||\n value === null ||\n (value as { kind?: unknown }).kind !== 'entity'\n ) {\n return false;\n }\n const discriminator = (value as { discriminator?: unknown }).discriminator;\n if (typeof discriminator !== 'string' || discriminator.length === 0) {\n return false;\n }\n const output = (value as { output?: unknown }).output;\n if (typeof output !== 'object' || output === null) {\n return false;\n }\n const factory = (output as { factory?: unknown }).factory;\n const template = (output as { template?: unknown }).template;\n return typeof factory === 'function' || template !== undefined;\n}\n\nexport function isAuthoringPslBlockDescriptor(\n value: unknown,\n): value is AuthoringPslBlockDescriptor {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const record = blindCast<\n Record<string, unknown>,\n 'type-guard probing an unknown candidate-descriptor object for known property names'\n >(value);\n if (record['kind'] !== 'pslBlock') {\n return false;\n }\n const keyword = record['keyword'];\n if (typeof keyword !== 'string' || keyword.length === 0) {\n return false;\n }\n const discriminator = record['discriminator'];\n if (typeof discriminator !== 'string' || discriminator.length === 0) {\n return false;\n }\n const name = record['name'];\n if (typeof name !== 'object' || name === null) {\n return false;\n }\n const nameRecord = blindCast<\n Record<string, unknown>,\n 'type-guard probing the name property of a candidate pslBlock descriptor'\n >(name);\n if (typeof nameRecord['required'] !== 'boolean') {\n return false;\n }\n const parameters = record['parameters'];\n return typeof parameters === 'object' && parameters !== null && !Array.isArray(parameters);\n}\n\n/**\n * Returns true when `namespace` is a non-leaf key in `contributions.field`.\n *\n * `AuthoringFieldNamespace` permits a leaf descriptor at any depth — including\n * the root — so a top-level `field: { Foo: { kind: 'fieldPreset', ... } }`\n * registration must NOT be treated as a \"namespace\" with sub-paths. Callers\n * use this predicate to gate dot-namespaced lookups (e.g. PSL `@Foo.bar`).\n */\nexport function hasRegisteredFieldNamespace(\n contributions: AuthoringContributions | undefined,\n namespace: string,\n): boolean {\n if (contributions?.field === undefined || !Object.hasOwn(contributions.field, namespace)) {\n return false;\n }\n return !isAuthoringFieldPresetDescriptor(contributions.field[namespace]);\n}\n\nfunction isCopyableNamespaceObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nfunction deepCopyNamespace(\n source: Record<string, unknown>,\n isLeafDescriptor: (value: unknown) => boolean,\n): Record<string, unknown> {\n const copy: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(source)) {\n copy[key] =\n isCopyableNamespaceObject(value) && !isLeafDescriptor(value)\n ? deepCopyNamespace(value, isLeafDescriptor)\n : value;\n }\n return copy;\n}\n\n/**\n * Merges `source` into `target` recursively at the descriptor-namespace\n * level. `isLeafDescriptor` decides which values are descriptors (terminal\n * merge points; same-path registrations across components are reported\n * as duplicates) versus sub-namespaces (recursion targets).\n *\n * Path segments are validated against prototype-pollution names\n * (`__proto__`, `constructor`, `prototype`). A value that is neither a\n * recognized leaf nor a plain object — e.g. a malformed descriptor\n * where the canonical leaf guard rejected it for missing `output` —\n * is reported as an invalid contribution rather than recursed into,\n * which would either silently mangle state or infinite-loop on\n * primitive properties.\n *\n * Within-registry duplicate detection is this walker's job;\n * cross-registry detection runs separately via\n * `assertNoCrossRegistryCollisions` after merging completes.\n */\nexport function mergeAuthoringNamespaces(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n path: readonly string[],\n isLeafDescriptor: (value: unknown) => boolean,\n label: string,\n): void {\n const assertSafePath = (currentPath: readonly string[]) => {\n const blockedSegment = currentPath.find(\n (segment) => segment === '__proto__' || segment === 'constructor' || segment === 'prototype',\n );\n if (blockedSegment) {\n throw new Error(\n `Invalid authoring ${label} helper \"${currentPath.join('.')}\". Helper path segments must not use \"${blockedSegment}\".`,\n );\n }\n };\n\n for (const [key, sourceValue] of Object.entries(source)) {\n const currentPath = [...path, key];\n assertSafePath(currentPath);\n const hasExistingValue = Object.hasOwn(target, key);\n const existingValue = hasExistingValue ? target[key] : undefined;\n\n if (!hasExistingValue) {\n // Deep-copy plain-object sub-namespaces so subsequent merges don't mutate\n // objects owned by source packs. Leaf descriptors and class instances are\n // passed by reference — leaves are identity values; class instances carry\n // prototype getters that spread would destroy.\n target[key] =\n isCopyableNamespaceObject(sourceValue) && !isLeafDescriptor(sourceValue)\n ? deepCopyNamespace(sourceValue, isLeafDescriptor)\n : sourceValue;\n continue;\n }\n\n const existingIsLeaf = isLeafDescriptor(existingValue);\n const sourceIsLeaf = isLeafDescriptor(sourceValue);\n\n if (existingIsLeaf || sourceIsLeaf) {\n throw new Error(\n `Duplicate authoring ${label} helper \"${currentPath.join('.')}\". Helper names must be unique across composed packs.`,\n );\n }\n\n if (!isCopyableNamespaceObject(existingValue) || !isCopyableNamespaceObject(sourceValue)) {\n throw new Error(\n `Invalid authoring ${label} helper \"${currentPath.join('.')}\". Expected a sub-namespace object or a recognized descriptor; received a malformed value.`,\n );\n }\n\n mergeAuthoringNamespaces(existingValue, sourceValue, currentPath, isLeafDescriptor, label);\n }\n}\n\nfunction collectDescriptorPaths(\n namespace: Readonly<Record<string, unknown>>,\n isLeaf: (value: unknown) => boolean,\n path: readonly string[] = [],\n): string[] {\n const paths: string[] = [];\n for (const [key, value] of Object.entries(namespace)) {\n const currentPath = [...path, key];\n if (isLeaf(value)) {\n paths.push(currentPath.join('.'));\n continue;\n }\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n paths.push(\n ...collectDescriptorPaths(value as Readonly<Record<string, unknown>>, isLeaf, currentPath),\n );\n }\n }\n return paths;\n}\n\ninterface DescriptorEntry {\n readonly path: string;\n readonly discriminator: string;\n}\n\nfunction collectDescriptorEntries(\n namespace: Readonly<Record<string, unknown>>,\n isLeaf: (value: unknown) => boolean,\n label: string,\n path: readonly string[] = [],\n): DescriptorEntry[] {\n const entries: DescriptorEntry[] = [];\n for (const [key, value] of Object.entries(namespace)) {\n const currentPath = [...path, key];\n if (isLeaf(value)) {\n const record = blindCast<\n Record<string, unknown>,\n 'discriminator extraction from a leaf already validated by isLeaf'\n >(value);\n const discriminator = record['discriminator'];\n if (typeof discriminator === 'string' && discriminator.length > 0) {\n entries.push({ path: currentPath.join('.'), discriminator });\n }\n continue;\n }\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n const record = blindCast<\n Readonly<Record<string, unknown>>,\n 'walker inspects a non-leaf value for descriptor-shaped keys before recursing'\n >(value);\n // A value carrying descriptor-shaped keys (`kind`/`keyword`/`discriminator`)\n // but failing `isAuthoringPslBlockDescriptor` (e.g. missing `parameters`) is\n // a malformed declarative descriptor. Descending into it as a sub-namespace\n // would silently skip it, so a half-built contribution would pass validation.\n // Reject it at load time instead, naming the path and what's wrong.\n //\n // A valid sub-namespace whose key happens to be named `kind`, `keyword`, or\n // `discriminator` (but which does not look like a descriptor overall) must\n // still descend normally — the check requires descriptor-shaped keys present\n // AND the leaf guard rejecting it.\n if (\n (record['kind'] !== undefined ||\n record['keyword'] !== undefined ||\n record['discriminator'] !== undefined) &&\n !isLeaf(value)\n ) {\n const hasKind = record['kind'] === 'pslBlock';\n const hasKeyword = typeof record['keyword'] === 'string';\n const hasDiscriminator = typeof record['discriminator'] === 'string';\n if (hasKind || (hasKeyword && hasDiscriminator)) {\n throw new Error(\n `Malformed authoring ${label} contribution at \"${currentPath.join('.')}\". The value carries descriptor keys (kind/keyword/discriminator) but does not satisfy the ${label} descriptor shape. Fix the contribution so it is a complete descriptor, or remove the stray keys if it was meant to be a sub-namespace.`,\n );\n }\n }\n entries.push(...collectDescriptorEntries(record, isLeaf, label, currentPath));\n }\n }\n return entries;\n}\n\n/**\n * Throws when two or more entries in the same namespace share a discriminator.\n * Duplicate discriminators within a namespace make dispatch ambiguous — the\n * lowering factory lookup dispatches by discriminator, so one would silently\n * shadow the other. Catch duplicates before building any dispatch map.\n */\nfunction assertUniqueDiscriminators(entries: readonly DescriptorEntry[], label: string): void {\n const seen = new Map<string, string>();\n for (const { path, discriminator } of entries) {\n const existing = seen.get(discriminator);\n if (existing !== undefined) {\n throw new Error(\n `Duplicate ${label} discriminator \"${discriminator}\" registered at both \"${existing}\" and \"${path}\". Each ${label} contribution must use a unique discriminator.`,\n );\n }\n seen.set(discriminator, path);\n }\n}\n\nfunction collectPslBlockDescriptorEntries(\n namespace: Readonly<Record<string, unknown>>,\n path: readonly string[] = [],\n): DescriptorEntry[] {\n const entries: DescriptorEntry[] = [];\n for (const [key, value] of Object.entries(namespace)) {\n const currentPath = [...path, key];\n if (isAuthoringPslBlockDescriptor(value)) {\n entries.push({\n path: currentPath.join('.'),\n discriminator: value.discriminator,\n });\n continue;\n }\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n const record = blindCast<\n Readonly<Record<string, unknown>>,\n 'walker descends into psl block namespace'\n >(value);\n const hasKind = record['kind'] === 'pslBlock';\n const hasKeyword = typeof record['keyword'] === 'string';\n const hasDiscriminator = typeof record['discriminator'] === 'string';\n if (hasKind || (hasKeyword && hasDiscriminator)) {\n throw new Error(\n `Malformed authoring pslBlock contribution at \"${currentPath.join('.')}\". The value carries descriptor keys (kind/keyword/discriminator) but does not satisfy the pslBlock descriptor shape. Fix the contribution so it is a complete descriptor, or remove the stray keys if it was meant to be a sub-namespace.`,\n );\n }\n entries.push(...collectPslBlockDescriptorEntries(record, currentPath));\n }\n }\n return entries;\n}\n\n/**\n * Every `pslBlockDescriptors` entry requires a matching `entityTypes` factory\n * with the same discriminator. An `entityTypes` factory may stand alone (e.g.\n * `enum`, reachable from the TypeScript builder without any PSL block).\n */\nfunction assertPslBlocksHaveFactories(\n entityTypeNamespace: AuthoringEntityTypeNamespace,\n pslBlockNamespace: AuthoringPslBlockDescriptorNamespace,\n): void {\n const blockEntries = collectPslBlockDescriptorEntries(pslBlockNamespace);\n const entityEntries = collectDescriptorEntries(\n entityTypeNamespace,\n isAuthoringEntityTypeDescriptor,\n 'entityType',\n );\n\n assertUniqueDiscriminators(blockEntries, 'pslBlock');\n assertUniqueDiscriminators(entityEntries, 'entityType');\n\n const entityDiscriminators = new Set(entityEntries.map((entry) => entry.discriminator));\n\n for (const block of blockEntries) {\n if (!entityDiscriminators.has(block.discriminator)) {\n throw new Error(\n `Incomplete extension contribution: pslBlock helper \"${block.path}\" registers discriminator \"${block.discriminator}\" but no entityType contribution shares that discriminator. An extension-contributed PSL block requires a matching entityType factory so the parsed AST node can lower to an IR class instance; add an entityType helper with discriminator \"${block.discriminator}\".`,\n );\n }\n }\n}\n\nexport function assertNoCrossRegistryCollisions(\n typeNamespace: AuthoringTypeNamespace,\n fieldNamespace: AuthoringFieldNamespace,\n entityTypeNamespace: AuthoringEntityTypeNamespace = {},\n pslBlockNamespace: AuthoringPslBlockDescriptorNamespace = {},\n): void {\n const typePaths = new Set(\n collectDescriptorPaths(typeNamespace, isAuthoringTypeConstructorDescriptor),\n );\n const fieldPaths = new Set(\n collectDescriptorPaths(fieldNamespace, isAuthoringFieldPresetDescriptor),\n );\n const entityPaths = new Set(\n collectDescriptorPaths(entityTypeNamespace, isAuthoringEntityTypeDescriptor),\n );\n // Within-registry duplicate detection is handled upstream by the merge\n // walker (`mergeAuthoringNamespaces` in control-stack.ts and\n // `mergeHelperNamespaces` in composed-authoring-helpers.ts), which throws\n // on same-path registrations within any single registry before this check\n // runs. This function only handles the cross-registry case.\n //\n // Cross-registry collisions are checked among `type` / `field` /\n // `entityTypes` only — these three are user-facing helper paths that PSL\n // must resolve unambiguously. `pslBlockDescriptors` is an internal\n // framework index consumed by parser and printer dispatch, not a\n // user-facing helper path; the natural authoring pattern is the same\n // path key in `entityTypes` and `pslBlockDescriptors` for a single\n // contribution. The block→factory link is enforced by\n // `assertPslBlocksHaveFactories` via the discriminator string, not by path.\n const ambiguityHint =\n 'Register each path in only one of authoringContributions.field / authoringContributions.type / authoringContributions.entityTypes.';\n for (const fieldPath of fieldPaths) {\n if (typePaths.has(fieldPath)) {\n throw new Error(\n `Ambiguous authoring registry path \"${fieldPath}\". The same path is registered as both a type constructor and a field preset; PSL resolution would be ambiguous. ${ambiguityHint}`,\n );\n }\n }\n for (const entityPath of entityPaths) {\n if (typePaths.has(entityPath) || fieldPaths.has(entityPath)) {\n throw new Error(\n `Ambiguous authoring registry path \"${entityPath}\". The same path is registered as an entity contribution AND as a type constructor or field preset; PSL resolution would be ambiguous. ${ambiguityHint}`,\n );\n }\n }\n\n assertPslBlocksHaveFactories(entityTypeNamespace, pslBlockNamespace);\n}\n\nexport function resolveAuthoringTemplateValue(\n template: AuthoringTemplateValue,\n args: readonly unknown[],\n): unknown {\n if (isAuthoringArgRef(template)) {\n let value = args[template.index];\n\n for (const segment of template.path ?? []) {\n if (!isAuthoringTemplateRecord(value) || !Object.hasOwn(value, segment)) {\n value = undefined;\n break;\n }\n value = (value as Record<string, unknown>)[segment];\n }\n\n if (value === undefined && template.default !== undefined) {\n return resolveAuthoringTemplateValue(template.default, args);\n }\n\n return value;\n }\n if (Array.isArray(template)) {\n return template.map((value) => resolveAuthoringTemplateValue(value, args));\n }\n if (typeof template === 'object' && template !== null) {\n const resolved: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(template)) {\n const resolvedValue = resolveAuthoringTemplateValue(value, args);\n if (resolvedValue !== undefined) {\n resolved[key] = resolvedValue;\n }\n }\n return resolved;\n }\n return template;\n}\n\nfunction validateAuthoringArgument(\n descriptor: AuthoringArgumentDescriptor,\n value: unknown,\n path: string,\n): void {\n if (value === undefined) {\n if (descriptor.optional) {\n return;\n }\n throw new Error(`Missing required authoring helper argument at ${path}`);\n }\n\n if (descriptor.kind === 'string') {\n if (typeof value !== 'string') {\n throw new Error(`Authoring helper argument at ${path} must be a string`);\n }\n return;\n }\n\n if (descriptor.kind === 'boolean') {\n if (typeof value !== 'boolean') {\n throw new Error(`Authoring helper argument at ${path} must be a boolean`);\n }\n return;\n }\n\n if (descriptor.kind === 'stringArray') {\n if (!Array.isArray(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an array of strings`);\n }\n for (const entry of value) {\n if (typeof entry !== 'string') {\n throw new Error(`Authoring helper argument at ${path} must be an array of strings`);\n }\n }\n return;\n }\n\n if (descriptor.kind === 'object') {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an object`);\n }\n\n const input = value as Record<string, unknown>;\n const expectedKeys = new Set(Object.keys(descriptor.properties));\n\n for (const key of Object.keys(input)) {\n if (!expectedKeys.has(key)) {\n throw new Error(`Authoring helper argument at ${path} contains unknown property \"${key}\"`);\n }\n }\n\n for (const [key, propertyDescriptor] of Object.entries(descriptor.properties)) {\n validateAuthoringArgument(propertyDescriptor, input[key], `${path}.${key}`);\n }\n\n return;\n }\n\n if (typeof value !== 'number' || Number.isNaN(value)) {\n throw new Error(`Authoring helper argument at ${path} must be a number`);\n }\n\n if (descriptor.integer && !Number.isInteger(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an integer`);\n }\n if (descriptor.minimum !== undefined && value < descriptor.minimum) {\n throw new Error(\n `Authoring helper argument at ${path} must be >= ${descriptor.minimum}, received ${value}`,\n );\n }\n if (descriptor.maximum !== undefined && value > descriptor.maximum) {\n throw new Error(\n `Authoring helper argument at ${path} must be <= ${descriptor.maximum}, received ${value}`,\n );\n }\n}\n\nexport function validateAuthoringHelperArguments(\n helperPath: string,\n descriptors: readonly AuthoringArgumentDescriptor[] | undefined,\n args: readonly unknown[],\n): void {\n const expected = descriptors ?? [];\n const minimumArgs = expected.reduce(\n (count, descriptor, index) => (descriptor.optional ? count : index + 1),\n 0,\n );\n if (args.length < minimumArgs || args.length > expected.length) {\n throw new Error(\n `${helperPath} expects ${minimumArgs === expected.length ? expected.length : `${minimumArgs}-${expected.length}`} argument(s), received ${args.length}`,\n );\n }\n\n expected.forEach((descriptor, index) => {\n validateAuthoringArgument(descriptor, args[index], `${helperPath}[${index}]`);\n });\n}\n\nfunction resolveAuthoringStorageTypeTemplate(\n template: AuthoringStorageTypeTemplate,\n args: readonly unknown[],\n): {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n} {\n const nativeType = resolveAuthoringTemplateValue(template.nativeType, args);\n if (typeof nativeType !== 'string') {\n throw new Error(\n `Resolved authoring nativeType must be a string for codec \"${template.codecId}\", received ${String(nativeType)}`,\n );\n }\n const typeParams =\n template.typeParams === undefined\n ? undefined\n : resolveAuthoringTemplateValue(template.typeParams, args);\n if (typeParams !== undefined && !isAuthoringTemplateRecord(typeParams)) {\n throw new Error(\n `Resolved authoring typeParams must be an object for codec \"${template.codecId}\", received ${String(typeParams)}`,\n );\n }\n\n return {\n codecId: template.codecId,\n nativeType,\n ...(typeParams === undefined ? {} : { typeParams }),\n };\n}\n\nfunction resolveAuthoringColumnDefaultTemplate(\n template: AuthoringColumnDefaultTemplate,\n args: readonly unknown[],\n): ColumnDefault {\n if (template.kind === 'literal') {\n const value = resolveAuthoringTemplateValue(template.value, args);\n if (value === undefined) {\n throw new Error('Resolved authoring literal default must not be undefined');\n }\n if (!isColumnDefaultLiteralInputValue(value)) {\n throw new Error(\n `Resolved authoring literal default must be a JSON-serializable value or Date, received ${String(value)}`,\n );\n }\n return {\n kind: 'literal',\n value,\n };\n }\n\n const expression = resolveAuthoringTemplateValue(template.expression, args);\n if (expression === undefined || (typeof expression === 'object' && expression !== null)) {\n throw new Error(\n `Resolved authoring function default expression must resolve to a primitive, received ${String(expression)}`,\n );\n }\n return {\n kind: 'function',\n expression: String(expression),\n };\n}\n\nfunction resolveExecutionMutationDefaultPhase(\n phase: 'onCreate' | 'onUpdate',\n template: AuthoringTemplateValue,\n args: readonly unknown[],\n): ExecutionMutationDefaultValue {\n const value = resolveAuthoringTemplateValue(template, args);\n if (!isExecutionMutationDefaultValue(value)) {\n throw new Error(\n `Authoring preset executionDefaults.${phase} did not resolve to a valid generator descriptor (kind: 'generator', id: string).`,\n );\n }\n return value;\n}\n\nfunction resolveAuthoringExecutionDefaultsTemplate(\n template: AuthoringExecutionDefaultsTemplate,\n args: readonly unknown[],\n): ExecutionMutationDefaultPhases {\n return {\n ...ifDefined(\n 'onCreate',\n template.onCreate !== undefined\n ? resolveExecutionMutationDefaultPhase('onCreate', template.onCreate, args)\n : undefined,\n ),\n ...ifDefined(\n 'onUpdate',\n template.onUpdate !== undefined\n ? resolveExecutionMutationDefaultPhase('onUpdate', template.onUpdate, args)\n : undefined,\n ),\n };\n}\n\nexport function instantiateAuthoringTypeConstructor(\n descriptor: AuthoringTypeConstructorDescriptor,\n args: readonly unknown[],\n): {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n} {\n return resolveAuthoringStorageTypeTemplate(descriptor.output, args);\n}\n\nexport function instantiateAuthoringEntityType(\n helperPath: string,\n descriptor: AuthoringEntityTypeDescriptor,\n args: readonly unknown[],\n ctx: AuthoringEntityContext,\n): unknown {\n // Factory-output entities carry their input contract on the factory\n // signature itself — TypeScript narrows callers via\n // `EntityHelperFunction`'s extracted `input` parameter, and the factory\n // is free to do its own runtime validation (e.g. arktype Type). The\n // descriptor-level `args` validator is reserved for template-output\n // entities (which mirror field/type's declarative argument shape).\n if ('factory' in descriptor.output) {\n const input = args[0];\n // The base `AuthoringEntityTypeDescriptor`'s factory is typed\n // `(input: never, ctx) => unknown` so concrete pack-literal factories\n // with narrower input types remain assignable through the\n // contravariant position (see the type's docstring). The runtime\n // delegates input validation to the pack's factory itself, so we\n // forward the supplied input here without a static input contract.\n const factory = descriptor.output.factory as (\n input: unknown,\n ctx: AuthoringEntityContext,\n ) => unknown;\n return factory(input, ctx);\n }\n validateAuthoringHelperArguments(helperPath, descriptor.args, args);\n return resolveAuthoringTemplateValue(descriptor.output.template, args);\n}\n\nexport function instantiateAuthoringFieldPreset(\n descriptor: AuthoringFieldPresetDescriptor,\n args: readonly unknown[],\n): {\n readonly descriptor: {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n };\n readonly nullable: boolean;\n readonly default?: ColumnDefault;\n readonly executionDefaults?: ExecutionMutationDefaultPhases;\n readonly id: boolean;\n readonly unique: boolean;\n} {\n return {\n descriptor: resolveAuthoringStorageTypeTemplate(descriptor.output, args),\n nullable: descriptor.output.nullable ?? false,\n ...ifDefined(\n 'default',\n descriptor.output.default !== undefined\n ? resolveAuthoringColumnDefaultTemplate(descriptor.output.default, args)\n : undefined,\n ),\n ...ifDefined(\n 'executionDefaults',\n descriptor.output.executionDefaults !== undefined\n ? resolveAuthoringExecutionDefaultsTemplate(descriptor.output.executionDefaults, args)\n : undefined,\n ),\n id: descriptor.output.id ?? false,\n unique: descriptor.output.unique ?? false,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { f as AnyCodecDescriptor } from "./codec-types-29q8imKF.mjs";
|
|
2
|
+
import { i as AuthoringContributions } from "./framework-authoring-BXiebZGn.mjs";
|
|
3
3
|
import { t as TypesImportSpec } from "./types-import-spec-DRKzrJ20.mjs";
|
|
4
4
|
import { ColumnDefault, ExecutionMutationDefaultPhases, ExecutionMutationDefaultValue } from "@prisma-next/contract/types";
|
|
5
5
|
|
|
@@ -409,4 +409,4 @@ interface ExtensionInstance<TFamilyId extends string, TTargetId extends string>
|
|
|
409
409
|
}
|
|
410
410
|
//#endregion
|
|
411
411
|
export { LoweredDefaultResult as A, ControlMutationDefaultEntry as C, DefaultFunctionLoweringHandler as D, DefaultFunctionLoweringContext as E, SourceSpan as F, MutationDefaultGeneratorDescriptor as M, ParsedDefaultFunctionCall as N, DefaultFunctionRegistry as O, SourceDiagnostic as P, checkContractComponentRequirements as S, ControlMutationDefaults as T, PackRefBase as _, ComponentMetadata as a, TargetInstance as b, DriverDescriptor as c, ExtensionDescriptor as d, ExtensionInstance as f, FamilyPackRef as g, FamilyInstance as h, ComponentDescriptor as i, LoweredDefaultValue as j, DefaultFunctionRegistryEntry as k, DriverInstance as l, FamilyDescriptor as m, AdapterInstance as n, ContractComponentRequirementsCheckInput as o, ExtensionPackRef as p, AdapterPackRef as r, ContractComponentRequirementsCheckResult as s, AdapterDescriptor as t, DriverPackRef as u, TargetBoundComponentDescriptor as v, ControlMutationDefaultRegistry as w, TargetPackRef as x, TargetDescriptor as y };
|
|
412
|
-
//# sourceMappingURL=framework-components-
|
|
412
|
+
//# sourceMappingURL=framework-components-B-ABhSOs.d.mts.map
|
package/dist/{framework-components-DDQXmW0b.d.mts.map → framework-components-B-ABhSOs.d.mts.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"framework-components-
|
|
1
|
+
{"version":3,"file":"framework-components-B-ABhSOs.d.mts","names":[],"sources":["../src/shared/mutation-default-types.ts","../src/shared/framework-components.ts"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { r as CodecLookup } from "./codec-types-29q8imKF.mjs";
|
|
2
|
+
import { R as PslDiagnosticCode, Y as PslSpan, h as AuthoringPslBlockDescriptorNamespace, z as PslExtensionBlock } from "./framework-authoring-BXiebZGn.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/control/psl-ast.d.ts
|
|
5
5
|
interface PslDiagnostic {
|
|
@@ -229,7 +229,7 @@ declare const BUILTIN_PSL_KIND_KEYS: ReadonlySet<string>;
|
|
|
229
229
|
* Returns all extension-contributed blocks in the given namespace, in
|
|
230
230
|
* insertion order (the order the parser encountered them in the source).
|
|
231
231
|
*
|
|
232
|
-
* Reads from `namespace.entries`, skipping the
|
|
232
|
+
* Reads from `namespace.entries`, skipping the built-in kind keys
|
|
233
233
|
* (`'model'`, `'enum'`, `'compositeType'`). All remaining kind maps contain
|
|
234
234
|
* only `PslExtensionBlock` nodes by construction (see `makePslNamespaceEntries`).
|
|
235
235
|
*/
|
|
@@ -270,4 +270,4 @@ interface ParsePslDocumentResult {
|
|
|
270
270
|
}
|
|
271
271
|
//#endregion
|
|
272
272
|
export { flatPslCompositeTypes as A, PslNamespace as C, PslTypesBlock as D, PslTypeConstructorCall as E, namespacePslExtensionBlocks as F, flatPslModels as M, makePslNamespace as N, PslUniqueConstraint as O, makePslNamespaceEntries as P, PslNamedTypeDeclaration as S, PslReferentialAction as T, PslField as _, PslAttributeArgument as a, PslModel as b, PslAttributeTarget as c, PslDefaultLiteralValue as d, PslDefaultValue as f, PslEnumValue as g, PslEnum as h, PslAttribute as i, flatPslEnums as j, UNSPECIFIED_PSL_NAMESPACE_ID 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, PslFieldAttribute as v, PslNamespaceEntry as w, PslModelAttribute as x, PslIndexConstraint as y };
|
|
273
|
-
//# sourceMappingURL=psl-ast-
|
|
273
|
+
//# sourceMappingURL=psl-ast-CHgjnZ3h.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"psl-ast-
|
|
1
|
+
{"version":3,"file":"psl-ast-CHgjnZ3h.d.mts","names":[],"sources":["../src/control/psl-ast.ts"],"mappings":"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"}
|
package/dist/psl-ast.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { A as flatPslCompositeTypes, C as PslNamespace, D as PslTypesBlock, E as PslTypeConstructorCall, F as namespacePslExtensionBlocks, M as flatPslModels, N as makePslNamespace, O as PslUniqueConstraint, P as makePslNamespaceEntries, S as PslNamedTypeDeclaration, T as PslReferentialAction, _ as PslField, a as PslAttributeArgument, b as PslModel, c as PslAttributeTarget, d as PslDefaultLiteralValue, f as PslDefaultValue, g as PslEnumValue, h as PslEnum, i as PslAttribute, j as flatPslEnums, k as UNSPECIFIED_PSL_NAMESPACE_ID, 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 PslFieldAttribute, w as PslNamespaceEntry, x as PslModelAttribute, y as PslIndexConstraint } from "./psl-ast-
|
|
1
|
+
import { r as CodecLookup } from "./codec-types-29q8imKF.mjs";
|
|
2
|
+
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-BXiebZGn.mjs";
|
|
3
|
+
import { A as flatPslCompositeTypes, C as PslNamespace, D as PslTypesBlock, E as PslTypeConstructorCall, F as namespacePslExtensionBlocks, M as flatPslModels, N as makePslNamespace, O as PslUniqueConstraint, P as makePslNamespaceEntries, S as PslNamedTypeDeclaration, T as PslReferentialAction, _ as PslField, a as PslAttributeArgument, b as PslModel, c as PslAttributeTarget, d as PslDefaultLiteralValue, f as PslDefaultValue, g as PslEnumValue, h as PslEnum, i as PslAttribute, j as flatPslEnums, k as UNSPECIFIED_PSL_NAMESPACE_ID, 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 PslFieldAttribute, w as PslNamespaceEntry, x as PslModelAttribute, y as PslIndexConstraint } from "./psl-ast-CHgjnZ3h.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/control/psl-extension-block-validator.d.ts
|
|
6
6
|
/**
|
|
@@ -33,5 +33,5 @@ interface ExtensionBlockRefResolutionContext {
|
|
|
33
33
|
*/
|
|
34
34
|
declare function validateExtensionBlock(node: PslExtensionBlock, descriptor: AuthoringPslBlockDescriptor, sourceId: string, codecLookup: CodecLookup, refCtx?: ExtensionBlockRefResolutionContext): readonly PslDiagnostic[];
|
|
35
35
|
//#endregion
|
|
36
|
-
export { type AuthoringPslBlockDescriptorNamespace, BUILTIN_PSL_KIND_KEYS, type ExtensionBlockRefResolutionContext, ParsePslDocumentInput, ParsePslDocumentResult, PslAttribute, PslAttributeArgument, PslAttributeNamedArgument, PslAttributePositionalArgument, PslAttributeTarget, type PslBlockParam, type PslBlockParamList, type PslBlockParamOption, type PslBlockParamRef, type PslBlockParamValue, PslCompositeType, PslDefaultFunctionValue, PslDefaultLiteralValue, PslDefaultValue, PslDiagnostic, type PslDiagnosticCode, PslDocumentAst, PslEnum, PslEnumValue, type PslExtensionBlock, type PslExtensionBlockParamList, type PslExtensionBlockParamOption, type PslExtensionBlockParamRef, type PslExtensionBlockParamScalarValue, type PslExtensionBlockParamValue, PslField, PslFieldAttribute, PslIndexConstraint, PslModel, PslModelAttribute, PslNamedTypeDeclaration, PslNamespace, PslNamespaceEntry, type PslPosition, PslReferentialAction, type PslSpan, PslTypeConstructorCall, PslTypesBlock, PslUniqueConstraint, UNSPECIFIED_PSL_NAMESPACE_ID, flatPslCompositeTypes, flatPslEnums, flatPslModels, makePslNamespace, makePslNamespaceEntries, namespacePslExtensionBlocks, validateExtensionBlock };
|
|
36
|
+
export { type AuthoringPslBlockDescriptorNamespace, BUILTIN_PSL_KIND_KEYS, type ExtensionBlockRefResolutionContext, ParsePslDocumentInput, ParsePslDocumentResult, PslAttribute, PslAttributeArgument, PslAttributeNamedArgument, PslAttributePositionalArgument, PslAttributeTarget, type PslBlockParam, type PslBlockParamList, type PslBlockParamOption, type PslBlockParamRef, type PslBlockParamValue, PslCompositeType, PslDefaultFunctionValue, PslDefaultLiteralValue, PslDefaultValue, PslDiagnostic, type PslDiagnosticCode, PslDocumentAst, PslEnum, PslEnumValue, type PslExtensionBlock, type PslExtensionBlockAttribute, type PslExtensionBlockAttributeArg, type PslExtensionBlockParamBare, type PslExtensionBlockParamList, type PslExtensionBlockParamOption, type PslExtensionBlockParamRef, type PslExtensionBlockParamScalarValue, type PslExtensionBlockParamValue, PslField, PslFieldAttribute, PslIndexConstraint, PslModel, PslModelAttribute, PslNamedTypeDeclaration, PslNamespace, PslNamespaceEntry, type PslPosition, PslReferentialAction, type PslSpan, PslTypeConstructorCall, PslTypesBlock, PslUniqueConstraint, UNSPECIFIED_PSL_NAMESPACE_ID, flatPslCompositeTypes, flatPslEnums, flatPslModels, makePslNamespace, makePslNamespaceEntries, namespacePslExtensionBlocks, validateExtensionBlock };
|
|
37
37
|
//# sourceMappingURL=psl-ast.d.mts.map
|
package/dist/psl-ast.mjs
CHANGED
|
@@ -109,7 +109,7 @@ const BUILTIN_PSL_KIND_KEYS = new Set([
|
|
|
109
109
|
* Returns all extension-contributed blocks in the given namespace, in
|
|
110
110
|
* insertion order (the order the parser encountered them in the source).
|
|
111
111
|
*
|
|
112
|
-
* Reads from `namespace.entries`, skipping the
|
|
112
|
+
* Reads from `namespace.entries`, skipping the built-in kind keys
|
|
113
113
|
* (`'model'`, `'enum'`, `'compositeType'`). All remaining kind maps contain
|
|
114
114
|
* only `PslExtensionBlock` nodes by construction (see `makePslNamespaceEntries`).
|
|
115
115
|
*/
|
|
@@ -143,14 +143,16 @@ function validateExtensionBlock(node, descriptor, sourceId, codecLookup, refCtx)
|
|
|
143
143
|
const diagnostics = [];
|
|
144
144
|
const descriptorKeys = new Set(Object.keys(descriptor.parameters));
|
|
145
145
|
const nodeKeys = new Set(Object.keys(node.parameters));
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
146
|
+
if (!descriptor.variadicParameters) {
|
|
147
|
+
for (const key of nodeKeys) if (!descriptorKeys.has(key)) {
|
|
148
|
+
const captured = node.parameters[key];
|
|
149
|
+
diagnostics.push({
|
|
150
|
+
code: "PSL_EXTENSION_UNKNOWN_PARAMETER",
|
|
151
|
+
message: `Unknown parameter "${key}" in "${descriptor.keyword}" block "${node.name}". The descriptor does not declare this parameter.`,
|
|
152
|
+
sourceId,
|
|
153
|
+
span: captured?.span ?? node.span
|
|
154
|
+
});
|
|
155
|
+
}
|
|
154
156
|
}
|
|
155
157
|
for (const [key, param] of Object.entries(descriptor.parameters)) if (param.required === true && !nodeKeys.has(key)) diagnostics.push({
|
|
156
158
|
code: "PSL_EXTENSION_MISSING_REQUIRED_PARAMETER",
|
package/dist/psl-ast.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 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\nexport interface PslEnumValue {\n readonly kind: 'enumValue';\n readonly name: string;\n /**\n * Optional storage label for the enum member, captured from a trailing\n * `@map(\"...\")` attribute on the member line. The parser populates this\n * when the source PSL carries an explicit `@map`. Producers (e.g.\n * `sqlSchemaIrToPslAst`) leave it unset; the printer emits `@map(...)`\n * automatically when normalisation would change the printed member name\n * (so an enum value `'in-progress'` becomes `inProgress @map(\"in-progress\")`\n * in PSL, preserving the round-trip).\n */\n readonly mapName?: string;\n readonly span: PslSpan;\n}\n\nexport interface PslEnum {\n readonly kind: 'enum';\n readonly name: string;\n readonly values: readonly PslEnumValue[];\n readonly attributes: readonly PslAttribute[];\n readonly span: PslSpan;\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 | PslEnum | 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 enums, from `entries['enum']`. */\n readonly enums: readonly PslEnum[];\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 enums(): readonly PslEnum[] {\n return blindCast<readonly PslEnum[], 'entries[enum] holds only PslEnum by construction'>(\n Object.values(this.entries['enum'] ?? {}),\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 enums: readonly PslEnum[],\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 (enums.length > 0) {\n const map: Record<string, PslEnum> = {};\n for (const e of enums) {\n map[e.name] = e;\n }\n container['enum'] = 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 enums from every namespace in document order.\n */\nexport function flatPslEnums(ast: PslDocumentAst): readonly PslEnum[] {\n return ast.namespaces.flatMap((ns) =>\n blindCast<PslEnum[], 'enum kind map contains only PslEnum by construction'>(\n Object.values(ns.entries['enum'] ?? {}),\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'`, `'enum'`, `'compositeType'`.\n */\nexport const BUILTIN_PSL_KIND_KEYS: ReadonlySet<string> = new Set([\n 'model',\n 'enum',\n 'compositeType',\n]);\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 three built-in kind keys\n * (`'model'`, `'enum'`, `'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 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 // 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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"}
|
|
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\nexport interface PslEnumValue {\n readonly kind: 'enumValue';\n readonly name: string;\n /**\n * Optional storage label for the enum member, captured from a trailing\n * `@map(\"...\")` attribute on the member line. The parser populates this\n * when the source PSL carries an explicit `@map`. Producers (e.g.\n * `sqlSchemaIrToPslAst`) leave it unset; the printer emits `@map(...)`\n * automatically when normalisation would change the printed member name\n * (so an enum value `'in-progress'` becomes `inProgress @map(\"in-progress\")`\n * in PSL, preserving the round-trip).\n */\n readonly mapName?: string;\n readonly span: PslSpan;\n}\n\nexport interface PslEnum {\n readonly kind: 'enum';\n readonly name: string;\n readonly values: readonly PslEnumValue[];\n readonly attributes: readonly PslAttribute[];\n readonly span: PslSpan;\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 | PslEnum | 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 enums, from `entries['enum']`. */\n readonly enums: readonly PslEnum[];\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 enums(): readonly PslEnum[] {\n return blindCast<readonly PslEnum[], 'entries[enum] holds only PslEnum by construction'>(\n Object.values(this.entries['enum'] ?? {}),\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 enums: readonly PslEnum[],\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 (enums.length > 0) {\n const map: Record<string, PslEnum> = {};\n for (const e of enums) {\n map[e.name] = e;\n }\n container['enum'] = 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 enums from every namespace in document order.\n */\nexport function flatPslEnums(ast: PslDocumentAst): readonly PslEnum[] {\n return ast.namespaces.flatMap((ns) =>\n blindCast<PslEnum[], 'enum kind map contains only PslEnum by construction'>(\n Object.values(ns.entries['enum'] ?? {}),\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'`, `'enum'`, `'compositeType'`.\n */\nexport const BUILTIN_PSL_KIND_KEYS: ReadonlySet<string> = new Set([\n 'model',\n 'enum',\n 'compositeType',\n]);\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'`, `'enum'`, `'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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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { n as runtimeError } from "./runtime-error-B2gWOtgH.mjs";
|
|
2
|
+
import { blindCast } from "@prisma-next/utils/casts";
|
|
3
|
+
//#region src/shared/resolve-codec.ts
|
|
4
|
+
/**
|
|
5
|
+
* Validates `ref.typeParams` against `descriptor.paramsSchema`.
|
|
6
|
+
*
|
|
7
|
+
* Parameterized codecs that omit `typeParams` have it normalized to `{}` before
|
|
8
|
+
* validation (mirrors `ast-codec-resolver.ts` semantics). Throws
|
|
9
|
+
* `RUNTIME.TYPE_PARAMS_INVALID` when the validator returns a `Promise` or
|
|
10
|
+
* reports issues.
|
|
11
|
+
*/
|
|
12
|
+
function validateCodecTypeParams(descriptor, ref) {
|
|
13
|
+
const normalized = descriptor.isParameterized && ref.typeParams === void 0 ? {
|
|
14
|
+
...ref,
|
|
15
|
+
typeParams: {}
|
|
16
|
+
} : ref;
|
|
17
|
+
const result = blindCast(descriptor.paramsSchema["~standard"].validate(normalized.typeParams));
|
|
18
|
+
if (result instanceof Promise) throw runtimeError("RUNTIME.TYPE_PARAMS_INVALID", `paramsSchema for codec '${ref.codecId}' returned a Promise; runtime validation requires a synchronous Standard Schema validator.`, {
|
|
19
|
+
codecId: ref.codecId,
|
|
20
|
+
typeParams: ref.typeParams
|
|
21
|
+
});
|
|
22
|
+
if ("issues" in result && result.issues) {
|
|
23
|
+
const messages = result.issues.map((issue) => issue.message).join("; ");
|
|
24
|
+
throw runtimeError("RUNTIME.TYPE_PARAMS_INVALID", `Invalid typeParams for codec '${ref.codecId}': ${messages}`, {
|
|
25
|
+
codecId: ref.codecId,
|
|
26
|
+
typeParams: ref.typeParams
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return blindCast(result).value;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolves a `Codec` instance: validates `ref.typeParams` via
|
|
33
|
+
* {@link validateCodecTypeParams} then calls `descriptor.factory(validated)(ctx)`.
|
|
34
|
+
*
|
|
35
|
+
* The descriptor's `factory` is typed against its own `P`; the registry erases
|
|
36
|
+
* `P` to `any`, so the factory is narrowed to `(params: unknown) => (ctx) => Codec`
|
|
37
|
+
* at the call boundary. The `paramsSchema` validates the input above before we
|
|
38
|
+
* forward it, so the narrowing is safe by construction.
|
|
39
|
+
*/
|
|
40
|
+
function materializeCodec(descriptor, ref, ctx) {
|
|
41
|
+
const validated = validateCodecTypeParams(descriptor, ref);
|
|
42
|
+
return blindCast(descriptor.factory)(validated)(ctx);
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { validateCodecTypeParams as n, materializeCodec as t };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=resolve-codec-DR7uyr_c.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-codec-DR7uyr_c.mjs","names":[],"sources":["../src/shared/resolve-codec.ts"],"sourcesContent":["import { blindCast } from '@prisma-next/utils/casts';\nimport type { Codec } from './codec';\nimport type { AnyCodecDescriptor } from './codec-descriptor';\nimport type { CodecInstanceContext, CodecRef } from './codec-types';\nimport { runtimeError } from './runtime-error';\n\n/**\n * Validates `ref.typeParams` against `descriptor.paramsSchema`.\n *\n * Parameterized codecs that omit `typeParams` have it normalized to `{}` before\n * validation (mirrors `ast-codec-resolver.ts` semantics). Throws\n * `RUNTIME.TYPE_PARAMS_INVALID` when the validator returns a `Promise` or\n * reports issues.\n */\nexport function validateCodecTypeParams(descriptor: AnyCodecDescriptor, ref: CodecRef): unknown {\n const normalized =\n descriptor.isParameterized && ref.typeParams === undefined ? { ...ref, typeParams: {} } : ref;\n\n const result = blindCast<\n { value: unknown } | { issues: ReadonlyArray<{ message: string }> } | Promise<unknown>,\n 'Standard Schema validate returns unknown; the spec guarantees this union shape'\n >(descriptor.paramsSchema['~standard'].validate(normalized.typeParams));\n\n if (result instanceof Promise) {\n throw runtimeError(\n 'RUNTIME.TYPE_PARAMS_INVALID',\n `paramsSchema for codec '${ref.codecId}' returned a Promise; runtime validation requires a synchronous Standard Schema validator.`,\n { codecId: ref.codecId, typeParams: ref.typeParams },\n );\n }\n\n if ('issues' in result && result.issues) {\n const messages = result.issues.map((issue) => issue.message).join('; ');\n throw runtimeError(\n 'RUNTIME.TYPE_PARAMS_INVALID',\n `Invalid typeParams for codec '${ref.codecId}': ${messages}`,\n { codecId: ref.codecId, typeParams: ref.typeParams },\n );\n }\n\n return blindCast<{ value: unknown }, 'issues guard above rules out the issues branch'>(result)\n .value;\n}\n\n/**\n * Resolves a `Codec` instance: validates `ref.typeParams` via\n * {@link validateCodecTypeParams} then calls `descriptor.factory(validated)(ctx)`.\n *\n * The descriptor's `factory` is typed against its own `P`; the registry erases\n * `P` to `any`, so the factory is narrowed to `(params: unknown) => (ctx) => Codec`\n * at the call boundary. The `paramsSchema` validates the input above before we\n * forward it, so the narrowing is safe by construction.\n */\nexport function materializeCodec(\n descriptor: AnyCodecDescriptor,\n ref: CodecRef,\n ctx: CodecInstanceContext,\n): Codec {\n const validated = validateCodecTypeParams(descriptor, ref);\n return blindCast<\n (params: unknown) => (ctx: CodecInstanceContext) => Codec,\n 'registry erases P to any; paramsSchema validates input before forwarding'\n >(descriptor.factory)(validated)(ctx);\n}\n"],"mappings":";;;;;;;;;;;AAcA,SAAgB,wBAAwB,YAAgC,KAAwB;CAC9F,MAAM,aACJ,WAAW,mBAAmB,IAAI,eAAe,KAAA,IAAY;EAAE,GAAG;EAAK,YAAY,CAAC;CAAE,IAAI;CAE5F,MAAM,SAAS,UAGb,WAAW,aAAa,YAAY,CAAC,SAAS,WAAW,UAAU,CAAC;CAEtE,IAAI,kBAAkB,SACpB,MAAM,aACJ,+BACA,2BAA2B,IAAI,QAAQ,6FACvC;EAAE,SAAS,IAAI;EAAS,YAAY,IAAI;CAAW,CACrD;CAGF,IAAI,YAAY,UAAU,OAAO,QAAQ;EACvC,MAAM,WAAW,OAAO,OAAO,KAAK,UAAU,MAAM,OAAO,CAAC,CAAC,KAAK,IAAI;EACtE,MAAM,aACJ,+BACA,iCAAiC,IAAI,QAAQ,KAAK,YAClD;GAAE,SAAS,IAAI;GAAS,YAAY,IAAI;EAAW,CACrD;CACF;CAEA,OAAO,UAAgF,MAAM,CAAC,CAC3F;AACL;;;;;;;;;;AAWA,SAAgB,iBACd,YACA,KACA,KACO;CACP,MAAM,YAAY,wBAAwB,YAAY,GAAG;CACzD,OAAO,UAGL,WAAW,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG;AACtC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/shared/runtime-error.ts
|
|
2
|
+
/**
|
|
3
|
+
* Type guard for the runtime-error envelope produced by `runtimeError`.
|
|
4
|
+
*
|
|
5
|
+
* Prefer this over duck-typing on `error.code` directly so consumers stay
|
|
6
|
+
* insulated from the envelope's internal shape.
|
|
7
|
+
*/
|
|
8
|
+
function isRuntimeError(error) {
|
|
9
|
+
return error instanceof Error && "code" in error && typeof error.code === "string" && "category" in error && "severity" in error;
|
|
10
|
+
}
|
|
11
|
+
function runtimeError(code, message, details) {
|
|
12
|
+
const error = Object.assign(new Error(message), {
|
|
13
|
+
code,
|
|
14
|
+
category: resolveCategory(code),
|
|
15
|
+
severity: "error",
|
|
16
|
+
...details !== void 0 ? { details } : {}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(error, "name", {
|
|
19
|
+
value: "RuntimeError",
|
|
20
|
+
configurable: true
|
|
21
|
+
});
|
|
22
|
+
return error;
|
|
23
|
+
}
|
|
24
|
+
function resolveCategory(code) {
|
|
25
|
+
const prefix = code.split(".")[0] ?? "RUNTIME";
|
|
26
|
+
switch (prefix) {
|
|
27
|
+
case "PLAN":
|
|
28
|
+
case "CONTRACT":
|
|
29
|
+
case "LINT":
|
|
30
|
+
case "BUDGET": return prefix;
|
|
31
|
+
default: return "RUNTIME";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { runtimeError as n, isRuntimeError as t };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=runtime-error-B2gWOtgH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-error-B2gWOtgH.mjs","names":[],"sources":["../src/shared/runtime-error.ts"],"sourcesContent":["export interface RuntimeErrorEnvelope extends Error {\n readonly code: string;\n readonly category: 'PLAN' | 'CONTRACT' | 'LINT' | 'BUDGET' | 'RUNTIME';\n readonly severity: 'error';\n readonly details?: Record<string, unknown>;\n}\n\n/**\n * Type guard for the runtime-error envelope produced by `runtimeError`.\n *\n * Prefer this over duck-typing on `error.code` directly so consumers stay\n * insulated from the envelope's internal shape.\n */\nexport function isRuntimeError(error: unknown): error is RuntimeErrorEnvelope {\n return (\n error instanceof Error &&\n 'code' in error &&\n typeof (error as { code?: unknown }).code === 'string' &&\n 'category' in error &&\n 'severity' in error\n );\n}\n\nexport function runtimeError(\n code: string,\n message: string,\n details?: Record<string, unknown>,\n): RuntimeErrorEnvelope {\n const error = Object.assign(new Error(message), {\n code,\n category: resolveCategory(code),\n severity: 'error' as const,\n ...(details !== undefined ? { details } : {}),\n });\n Object.defineProperty(error, 'name', { value: 'RuntimeError', configurable: true });\n return error;\n}\n\nfunction resolveCategory(code: string): RuntimeErrorEnvelope['category'] {\n const prefix = code.split('.')[0] ?? 'RUNTIME';\n switch (prefix) {\n case 'PLAN':\n case 'CONTRACT':\n case 'LINT':\n case 'BUDGET':\n return prefix;\n default:\n return 'RUNTIME';\n }\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,eAAe,OAA+C;CAC5E,OACE,iBAAiB,SACjB,UAAU,SACV,OAAQ,MAA6B,SAAS,YAC9C,cAAc,SACd,cAAc;AAElB;AAEA,SAAgB,aACd,MACA,SACA,SACsB;CACtB,MAAM,QAAQ,OAAO,OAAO,IAAI,MAAM,OAAO,GAAG;EAC9C;EACA,UAAU,gBAAgB,IAAI;EAC9B,UAAU;EACV,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;CAC7C,CAAC;CACD,OAAO,eAAe,OAAO,QAAQ;EAAE,OAAO;EAAgB,cAAc;CAAK,CAAC;CAClF,OAAO;AACT;AAEA,SAAS,gBAAgB,MAAgD;CACvE,MAAM,SAAS,KAAK,MAAM,GAAG,CAAC,CAAC,MAAM;CACrC,QAAQ,QAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;EACT,SACE,OAAO;CACX;AACF"}
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as CodecCallContext } from "./codec-types-29q8imKF.mjs";
|
|
2
2
|
import { PlanMeta } from "@prisma-next/contract/types";
|
|
3
3
|
|
|
4
4
|
//#region src/annotations.d.ts
|
|
@@ -617,13 +617,23 @@ declare function checkMiddlewareCompatibility(middleware: RuntimeMiddleware, run
|
|
|
617
617
|
*/
|
|
618
618
|
declare function runBeforeExecuteChain<TExec extends ExecutionPlan, TMutator extends ParamRefMutator = ParamRefMutator>(plan: TExec, middleware: ReadonlyArray<RuntimeMiddleware<TExec, TMutator>>, ctx: RuntimeMiddlewareContext, paramsMutator?: TMutator): Promise<void>;
|
|
619
619
|
//#endregion
|
|
620
|
-
//#region src/
|
|
620
|
+
//#region src/shared/runtime-error.d.ts
|
|
621
621
|
interface RuntimeErrorEnvelope extends Error {
|
|
622
622
|
readonly code: string;
|
|
623
623
|
readonly category: 'PLAN' | 'CONTRACT' | 'LINT' | 'BUDGET' | 'RUNTIME';
|
|
624
624
|
readonly severity: 'error';
|
|
625
625
|
readonly details?: Record<string, unknown>;
|
|
626
626
|
}
|
|
627
|
+
/**
|
|
628
|
+
* Type guard for the runtime-error envelope produced by `runtimeError`.
|
|
629
|
+
*
|
|
630
|
+
* Prefer this over duck-typing on `error.code` directly so consumers stay
|
|
631
|
+
* insulated from the envelope's internal shape.
|
|
632
|
+
*/
|
|
633
|
+
declare function isRuntimeError(error: unknown): error is RuntimeErrorEnvelope;
|
|
634
|
+
declare function runtimeError(code: string, message: string, details?: Record<string, unknown>): RuntimeErrorEnvelope;
|
|
635
|
+
//#endregion
|
|
636
|
+
//#region src/execution/runtime-error.d.ts
|
|
627
637
|
/**
|
|
628
638
|
* Stable code emitted by the runtime when an in-flight `execute()`
|
|
629
639
|
* is cancelled via the per-query `AbortSignal`. The envelope's
|
|
@@ -641,14 +651,6 @@ interface RuntimeErrorEnvelope extends Error {
|
|
|
641
651
|
declare const RUNTIME_ABORTED: "RUNTIME.ABORTED";
|
|
642
652
|
/** Discriminator placed in `details.phase` of a `RUNTIME.ABORTED` envelope. */
|
|
643
653
|
type RuntimeAbortedPhase = 'encode' | 'decode' | 'stream' | 'beforeExecute' | 'afterExecute' | 'onRow';
|
|
644
|
-
/**
|
|
645
|
-
* Type guard for the runtime-error envelope produced by `runtimeError`.
|
|
646
|
-
*
|
|
647
|
-
* Prefer this over duck-typing on `error.code` directly so consumers stay
|
|
648
|
-
* insulated from the envelope's internal shape.
|
|
649
|
-
*/
|
|
650
|
-
declare function isRuntimeError(error: unknown): error is RuntimeErrorEnvelope;
|
|
651
|
-
declare function runtimeError(code: string, message: string, details?: Record<string, unknown>): RuntimeErrorEnvelope;
|
|
652
654
|
/**
|
|
653
655
|
* Construct a `RUNTIME.ABORTED` envelope. Phase distinguishes where the
|
|
654
656
|
* abort was observed — codec call sites (`encode` / `decode` / `stream`)
|