@prisma-next/framework-components 0.13.0-dev.16 → 0.13.0-dev.18

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.
Files changed (30) hide show
  1. package/dist/authoring.d.mts +2 -2
  2. package/dist/authoring.mjs +1 -1
  3. package/dist/{codec-DCQAerzB.d.mts → codec-types-7Qng7VFc.d.mts} +67 -67
  4. package/dist/codec-types-7Qng7VFc.d.mts.map +1 -0
  5. package/dist/codec.d.mts +1 -1
  6. package/dist/components.d.mts +1 -1
  7. package/dist/control.d.mts +4 -4
  8. package/dist/control.mjs +1 -1
  9. package/dist/execution.d.mts +1 -1
  10. package/dist/{framework-authoring-CnwPJCO4.mjs → framework-authoring-CLCzDm3Y.mjs} +35 -15
  11. package/dist/framework-authoring-CLCzDm3Y.mjs.map +1 -0
  12. package/dist/{framework-authoring-R0TYCkvG.d.mts → framework-authoring-DMAwH52s.d.mts} +90 -7
  13. package/dist/framework-authoring-DMAwH52s.d.mts.map +1 -0
  14. package/dist/{framework-components-DDQXmW0b.d.mts → framework-components-DXqiWAJX.d.mts} +3 -3
  15. package/dist/{framework-components-DDQXmW0b.d.mts.map → framework-components-DXqiWAJX.d.mts.map} +1 -1
  16. package/dist/{psl-ast-Cn50B-UG.d.mts → psl-ast-Mq7MlfKe.d.mts} +4 -4
  17. package/dist/{psl-ast-Cn50B-UG.d.mts.map → psl-ast-Mq7MlfKe.d.mts.map} +1 -1
  18. package/dist/psl-ast.d.mts +4 -4
  19. package/dist/psl-ast.mjs +11 -9
  20. package/dist/psl-ast.mjs.map +1 -1
  21. package/dist/runtime.d.mts +1 -1
  22. package/package.json +7 -7
  23. package/src/control/psl-ast.ts +4 -1
  24. package/src/control/psl-extension-block-validator.ts +11 -9
  25. package/src/exports/authoring.ts +1 -0
  26. package/src/shared/framework-authoring.ts +86 -26
  27. package/src/shared/psl-extension-block.ts +56 -5
  28. package/dist/codec-DCQAerzB.d.mts.map +0 -1
  29. package/dist/framework-authoring-CnwPJCO4.mjs.map +0 -1
  30. package/dist/framework-authoring-R0TYCkvG.d.mts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-authoring-DMAwH52s.d.mts","names":[],"sources":["../src/shared/psl-extension-block.ts","../src/shared/framework-authoring.ts"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { i as AuthoringContributions } from "./framework-authoring-R0TYCkvG.mjs";
2
- import { r as AnyCodecDescriptor } from "./codec-DCQAerzB.mjs";
1
+ import { d as AnyCodecDescriptor } from "./codec-types-7Qng7VFc.mjs";
2
+ import { i as AuthoringContributions } from "./framework-authoring-DMAwH52s.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-DDQXmW0b.d.mts.map
412
+ //# sourceMappingURL=framework-components-DXqiWAJX.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"framework-components-DDQXmW0b.d.mts","names":[],"sources":["../src/shared/mutation-default-types.ts","../src/shared/framework-components.ts"],"mappings":"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"}
1
+ {"version":3,"file":"framework-components-DXqiWAJX.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 { G as PslSpan, L as PslDiagnosticCode, R as PslExtensionBlock, m as AuthoringPslBlockDescriptorNamespace } from "./framework-authoring-R0TYCkvG.mjs";
2
- import { c as CodecLookup } from "./codec-DCQAerzB.mjs";
1
+ import { r as CodecLookup } from "./codec-types-7Qng7VFc.mjs";
2
+ import { R as PslDiagnosticCode, Y as PslSpan, h as AuthoringPslBlockDescriptorNamespace, z as PslExtensionBlock } from "./framework-authoring-DMAwH52s.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 three built-in kind keys
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-Cn50B-UG.d.mts.map
273
+ //# sourceMappingURL=psl-ast-Mq7MlfKe.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"psl-ast-Cn50B-UG.d.mts","names":[],"sources":["../src/control/psl-ast.ts"],"mappings":"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"}
1
+ {"version":3,"file":"psl-ast-Mq7MlfKe.d.mts","names":[],"sources":["../src/control/psl-ast.ts"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { B as PslExtensionBlockParamOption, F as PslBlockParamRef, G as PslSpan, H as PslExtensionBlockParamScalarValue, I as PslBlockParamValue, L as PslDiagnosticCode, M as PslBlockParam, N as PslBlockParamList, P as PslBlockParamOption, R as PslExtensionBlock, U as PslExtensionBlockParamValue, V as PslExtensionBlockParamRef, W as PslPosition, m as AuthoringPslBlockDescriptorNamespace, p as AuthoringPslBlockDescriptor, z as PslExtensionBlockParamList } from "./framework-authoring-R0TYCkvG.mjs";
2
- import { c as CodecLookup } from "./codec-DCQAerzB.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-Cn50B-UG.mjs";
1
+ import { r as CodecLookup } from "./codec-types-7Qng7VFc.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-DMAwH52s.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-Mq7MlfKe.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 three built-in kind keys
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
- for (const key of nodeKeys) if (!descriptorKeys.has(key)) {
147
- const captured = node.parameters[key];
148
- diagnostics.push({
149
- code: "PSL_EXTENSION_UNKNOWN_PARAMETER",
150
- message: `Unknown parameter "${key}" in "${descriptor.keyword}" block "${node.name}". The descriptor does not declare this parameter.`,
151
- sourceId,
152
- span: captured?.span ?? node.span
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",
@@ -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":";;;;;;;;;;;;;;AAyMA,MAAa,+BAA+B;;;;;;AAiC5C,IAAM,mBAAN,MAA+C;CAC7C,OAAgB;CAChB;CACA;CACA;CAEA,YAAY,MAIT;EACD,KAAK,OAAO,KAAK;EACjB,KAAK,UAAU,KAAK;EACpB,KAAK,OAAO,KAAK;EACjB,OAAO,OAAO,IAAI;CACpB;CAEA,IAAI,SAA8B;EAChC,OAAO,UACL,OAAO,OAAO,KAAK,QAAQ,YAAY,CAAC,CAAC,CAC3C;CACF;CAEA,IAAI,QAA4B;EAC9B,OAAO,UACL,OAAO,OAAO,KAAK,QAAQ,WAAW,CAAC,CAAC,CAC1C;CACF;CAEA,IAAI,iBAA8C;EAChD,OAAO,UAGL,OAAO,OAAO,KAAK,QAAQ,oBAAoB,CAAC,CAAC,CAAC;CACtD;AACF;;AAGA,SAAgB,iBAAiB,MAKhB;CACf,OAAO,IAAI,iBAAiB,IAAI;AAClC;;;;;;AAOA,SAAgB,wBACd,QACA,OACA,gBACA,iBACuE;CACvE,MAAM,YAAyE,CAAC;CAEhF,IAAI,OAAO,SAAS,GAAG;EACrB,MAAM,MAAgC,CAAC;EACvC,KAAK,MAAM,KAAK,QACd,IAAI,EAAE,QAAQ;EAEhB,UAAU,WAAW,OAAO,OAAO,GAAG;CACxC;CAEA,IAAI,MAAM,SAAS,GAAG;EACpB,MAAM,MAA+B,CAAC;EACtC,KAAK,MAAM,KAAK,OACd,IAAI,EAAE,QAAQ;EAEhB,UAAU,UAAU,OAAO,OAAO,GAAG;CACvC;CAEA,IAAI,eAAe,SAAS,GAAG;EAC7B,MAAM,MAAwC,CAAC;EAC/C,KAAK,MAAM,MAAM,gBACf,IAAI,GAAG,QAAQ;EAEjB,UAAU,mBAAmB,OAAO,OAAO,GAAG;CAChD;CAEA,KAAK,MAAM,SAAS,iBAAiB;EACnC,MAAM,WAAW,UAAU,MAAM;EACjC,MAAM,SAA4C,WAC9C,UAAsF,EACpF,GAAG,SACL,CAAC,IACD,CAAC;EACL,OAAO,MAAM,QAAQ;EACrB,UAAU,MAAM,QAAQ,OAAO,OAAO,MAAM;CAC9C;CAEA,OAAO,OAAO,OAAO,SAAS;AAChC;;;;;AAcA,SAAgB,cAAc,KAA0C;CACtE,OAAO,IAAI,WAAW,SAAS,OAC7B,UACE,OAAO,OAAO,GAAG,QAAQ,YAAY,CAAC,CAAC,CACzC,CACF;AACF;;;;AAKA,SAAgB,aAAa,KAAyC;CACpE,OAAO,IAAI,WAAW,SAAS,OAC7B,UACE,OAAO,OAAO,GAAG,QAAQ,WAAW,CAAC,CAAC,CACxC,CACF;AACF;;;;AAKA,SAAgB,sBAAsB,KAAkD;CACtF,OAAO,IAAI,WAAW,SAAS,OAC7B,UAGE,OAAO,OAAO,GAAG,QAAQ,oBAAoB,CAAC,CAAC,CAAC,CACpD;AACF;;;;;;;;;AAUA,MAAa,wBAA6C,IAAI,IAAI;CAChE;CACA;CACA;AACF,CAAC;;;;;;;;;AAUD,SAAgB,4BAA4B,IAAgD;CAC1F,MAAM,SAA8B,CAAC;CACrC,KAAK,MAAM,CAAC,SAAS,YAAY,OAAO,QAAQ,GAAG,OAAO,GAAG;EAC3D,IAAI,sBAAsB,IAAI,OAAO,GAAG;EACxC,KAAK,MAAM,SAAS,OAAO,OAAO,OAAO,GACvC,OAAO,KACL,UAGE,KAAK,CACT;CAEJ;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;AC3TA,SAAgB,uBACd,MACA,YACA,UACA,aACA,QAC0B;CAC1B,MAAM,cAA+B,CAAC;CAEtC,MAAM,iBAAiB,IAAI,IAAI,OAAO,KAAK,WAAW,UAAU,CAAC;CACjE,MAAM,WAAW,IAAI,IAAI,OAAO,KAAK,KAAK,UAAU,CAAC;CAGrD,KAAK,MAAM,OAAO,UAChB,IAAI,CAAC,eAAe,IAAI,GAAG,GAAG;EAC5B,MAAM,WAAW,KAAK,WAAW;EACjC,YAAY,KAAK;GACf,MAAM;GACN,SAAS,sBAAsB,IAAI,QAAQ,WAAW,QAAQ,WAAW,KAAK,KAAK;GACnF;GACA,MAAM,UAAU,QAAQ,KAAK;EAC/B,CAAC;CACH;CAIF,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,UAAU,GAC7D,IAAI,MAAM,aAAa,QAAQ,CAAC,SAAS,IAAI,GAAG,GAC9C,YAAY,KAAK;EACf,MAAM;EACN,SAAS,uBAAuB,IAAI,qBAAqB,WAAW,QAAQ,WAAW,KAAK,KAAK;EACjG;EACA,MAAM,KAAK;CACb,CAAC;CAKL,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,UAAU,GAAG;EAChE,MAAM,WAAW,KAAK,WAAW;EACjC,IAAI,aAAa,KAAA,GACf;EAEF,cACE,MACA,YACA,KACA,OACA,UACA,UACA,aACA,QACA,WACF;CACF;CAEA,OAAO;AACT;AAEA,SAAS,cACP,MACA,YACA,KACA,OACA,UACA,UACA,aACA,QACA,aACM;CACN,QAAQ,MAAM,MAAd;EACE,KAAK;GACH,IAAI,SAAS,SAAS,UACpB;GAEF,IAAI,CAAC,MAAM,OAAO,SAAS,SAAS,KAAK,GACvC,YAAY,KAAK;IACf,MAAM;IACN,SAAS,cAAc,IAAI,QAAQ,WAAW,QAAQ,WAAW,KAAK,KAAK,eAAe,SAAS,MAAM,4CAA4C,MAAM,OAAO,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;IAClM;IACA,MAAM,SAAS;GACjB,CAAC;GAEH;EAGF,KAAK,SAAS;GACZ,IAAI,SAAS,SAAS,SACpB;GAEF,MAAM,QAAQ,YAAY,IAAI,MAAM,OAAO;GAC3C,IAAI,UAAU,KAAA,GAAW;IACvB,YAAY,KAAK;KACf,MAAM;KACN,SAAS,cAAc,IAAI,QAAQ,WAAW,QAAQ,WAAW,KAAK,KAAK,8BAA8B,MAAM,QAAQ;KACvH;KACA,MAAM,SAAS;IACjB,CAAC;IACD;GACF;GACA,IAAI;GACJ,IAAI;IACF,YAAY,KAAK,MAAM,SAAS,GAAG;GACrC,QAAQ;IACN,YAAY,KAAK;KACf,MAAM;KACN,SAAS,cAAc,IAAI,QAAQ,WAAW,QAAQ,WAAW,KAAK,KAAK,oFAAoF,SAAS;KACxK;KACA,MAAM,SAAS;IACjB,CAAC;IACD;GACF;GACA,IAAI;IACF,MAAM,WACJ,UAAwE,SAAS,CACnF;GACF,SAAS,KAAK;IACZ,MAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;IAC9D,YAAY,KAAK;KACf,MAAM;KACN,SAAS,cAAc,IAAI,QAAQ,WAAW,QAAQ,WAAW,KAAK,KAAK,2BAA2B,MAAM,QAAQ,KAAK;KACzH;KACA,MAAM,SAAS;IACjB,CAAC;GACH;GACA;EACF;EAEA,KAAK;GACH,IAAI,SAAS,SAAS,OACpB;GAEF,YACE,MACA,YACA,KACA,OACA,SAAS,YACT,SAAS,MACT,UACA,QACA,WACF;GACA;EAGF,KAAK;GACH,IAAI,SAAS,SAAS,QACpB;GAEF,KAAK,MAAM,QAAQ,SAAS,OAC1B,cACE,MACA,YACA,KACA,MAAM,IACN,MACA,UACA,aACA,QACA,WACF;GAEF;CAEJ;AACF;AAEA,SAAS,YACP,MACA,YACA,KACA,OACA,YACA,MACA,UACA,QACA,aACM;CACN,IAAI,MAAM,UAAU,eAOlB;CAGF,IAAI,WAAW,KAAA,GAKb;CAGF,MAAM,qBACJ,MAAM,UAAU,mBAAmB,CAAC,OAAO,cAAc,IAAI,OAAO;CAEtE,IAAI,CAAC,0BAA0B,YAAY,MAAM,SAAS,kBAAkB,GAAG;EAC7E,MAAM,aACJ,MAAM,UAAU,mBAAmB,uBAAuB;EAC5D,YAAY,KAAK;GACf,MAAM;GACN,SAAS,cAAc,IAAI,QAAQ,WAAW,QAAQ,WAAW,KAAK,KAAK,eAAe,WAAW,cAAc,MAAM,QAAQ,wDAAwD,WAAW;GACpM;GACA;EACF,CAAC;CACH;AACF;;;;;;AAOA,SAAS,0BACP,MACA,SACA,YACS;CACT,KAAK,MAAM,MAAM,YAAY;EAC3B,MAAM,UAAU,GAAG,QAAQ;EAC3B,IAAI,YAAY,KAAA,KAAa,OAAO,OAAO,SAAS,IAAI,GAAG,OAAO;CACpE;CACA,OAAO;AACT"}
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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"}
@@ -1,4 +1,4 @@
1
- import { o as CodecCallContext } from "./codec-DCQAerzB.mjs";
1
+ import { t as CodecCallContext } from "./codec-types-7Qng7VFc.mjs";
2
2
  import { PlanMeta } from "@prisma-next/contract/types";
3
3
 
4
4
  //#region src/annotations.d.ts
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
2
  "name": "@prisma-next/framework-components",
3
- "version": "0.13.0-dev.16",
3
+ "version": "0.13.0-dev.18",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "Framework component types, assembly logic, and stack creation for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/contract": "0.13.0-dev.16",
10
- "@prisma-next/operations": "0.13.0-dev.16",
11
- "@prisma-next/ts-render": "0.13.0-dev.16",
12
- "@prisma-next/utils": "0.13.0-dev.16",
9
+ "@prisma-next/contract": "0.13.0-dev.18",
10
+ "@prisma-next/operations": "0.13.0-dev.18",
11
+ "@prisma-next/ts-render": "0.13.0-dev.18",
12
+ "@prisma-next/utils": "0.13.0-dev.18",
13
13
  "@standard-schema/spec": "^1.1.0",
14
14
  "arktype": "^2.2.0"
15
15
  },
16
16
  "devDependencies": {
17
- "@prisma-next/tsconfig": "0.13.0-dev.16",
18
- "@prisma-next/tsdown": "0.13.0-dev.16",
17
+ "@prisma-next/tsconfig": "0.13.0-dev.18",
18
+ "@prisma-next/tsdown": "0.13.0-dev.18",
19
19
  "tsdown": "0.22.1",
20
20
  "typescript": "5.9.3",
21
21
  "vitest": "4.1.8"
@@ -7,6 +7,9 @@ export type {
7
7
  PslBlockParamValue,
8
8
  PslDiagnosticCode,
9
9
  PslExtensionBlock,
10
+ PslExtensionBlockAttribute,
11
+ PslExtensionBlockAttributeArg,
12
+ PslExtensionBlockParamBare,
10
13
  PslExtensionBlockParamList,
11
14
  PslExtensionBlockParamOption,
12
15
  PslExtensionBlockParamRef,
@@ -391,7 +394,7 @@ export const BUILTIN_PSL_KIND_KEYS: ReadonlySet<string> = new Set([
391
394
  * Returns all extension-contributed blocks in the given namespace, in
392
395
  * insertion order (the order the parser encountered them in the source).
393
396
  *
394
- * Reads from `namespace.entries`, skipping the three built-in kind keys
397
+ * Reads from `namespace.entries`, skipping the built-in kind keys
395
398
  * (`'model'`, `'enum'`, `'compositeType'`). All remaining kind maps contain
396
399
  * only `PslExtensionBlock` nodes by construction (see `makePslNamespaceEntries`).
397
400
  */
@@ -107,15 +107,17 @@ export function validateExtensionBlock(
107
107
  const nodeKeys = new Set(Object.keys(node.parameters));
108
108
 
109
109
  // 1. Unknown parameters — keys in the node not in the descriptor.
110
- for (const key of nodeKeys) {
111
- if (!descriptorKeys.has(key)) {
112
- const captured = node.parameters[key];
113
- diagnostics.push({
114
- code: 'PSL_EXTENSION_UNKNOWN_PARAMETER',
115
- message: `Unknown parameter "${key}" in "${descriptor.keyword}" block "${node.name}". The descriptor does not declare this parameter.`,
116
- sourceId,
117
- span: captured?.span ?? node.span,
118
- });
110
+ if (!descriptor.variadicParameters) {
111
+ for (const key of nodeKeys) {
112
+ if (!descriptorKeys.has(key)) {
113
+ const captured = node.parameters[key];
114
+ diagnostics.push({
115
+ code: 'PSL_EXTENSION_UNKNOWN_PARAMETER',
116
+ message: `Unknown parameter "${key}" in "${descriptor.keyword}" block "${node.name}". The descriptor does not declare this parameter.`,
117
+ sourceId,
118
+ span: captured?.span ?? node.span,
119
+ });
120
+ }
119
121
  }
120
122
  }
121
123
 
@@ -3,6 +3,7 @@ export type {
3
3
  AuthoringArgumentDescriptor,
4
4
  AuthoringColumnDefaultTemplate,
5
5
  AuthoringContributions,
6
+ AuthoringDiagnosticSink,
6
7
  AuthoringEntityContext,
7
8
  AuthoringEntityTypeDescriptor,
8
9
  AuthoringEntityTypeFactoryOutput,
@@ -10,6 +10,7 @@ import {
10
10
  import { blindCast } from '@prisma-next/utils/casts';
11
11
  import { ifDefined } from '@prisma-next/utils/defined';
12
12
  import type { Type } from 'arktype';
13
+ import type { CodecLookup } from './codec-types';
13
14
  import type { PslBlockParam } from './psl-extension-block';
14
15
 
15
16
  export type AuthoringArgRef = {
@@ -109,9 +110,30 @@ export type AuthoringFieldNamespace = {
109
110
  * discover what the factory actually needs to read (codec lookup,
110
111
  * namespace registry, …).
111
112
  */
113
+ /**
114
+ * A write-only sink that a factory may push authoring-time diagnostics into.
115
+ * The concrete type pushed must be structurally compatible with whatever the
116
+ * consumer accumulates (typically `ContractSourceDiagnostic[]`); the framework
117
+ * layer deliberately does not depend on that concrete type.
118
+ */
119
+ export interface AuthoringDiagnosticSink {
120
+ push(d: {
121
+ readonly code: string;
122
+ readonly message: string;
123
+ readonly sourceId: string;
124
+ readonly span?: unknown;
125
+ }): void;
126
+ }
127
+
112
128
  export interface AuthoringEntityContext {
113
129
  readonly family: string;
114
130
  readonly target: string;
131
+ /** Codec registry available to factories that need to validate or decode values. */
132
+ readonly codecLookup?: CodecLookup;
133
+ /** Source file identifier threaded into diagnostics emitted by the factory. */
134
+ readonly sourceId?: string;
135
+ /** Push channel for authoring-time diagnostics emitted by the factory. */
136
+ readonly diagnostics?: AuthoringDiagnosticSink;
115
137
  }
116
138
 
117
139
  export interface AuthoringEntityTypeTemplateOutput {
@@ -186,6 +208,21 @@ export interface AuthoringPslBlockDescriptor {
186
208
  readonly discriminator: string;
187
209
  readonly name: { readonly required: boolean };
188
210
  readonly parameters: Record<string, PslBlockParam>;
211
+ /**
212
+ * When `true`, the block body accepts a variadic tail of parameters beyond
213
+ * the declared set. The block body may contain: fields (model-style),
214
+ * `key = value` parameters, and `@@` attributes. With `variadicParameters`,
215
+ * bare identifiers (keys without a `= value`) and undeclared `key = value`
216
+ * pairs flow into the variadic tail — their semantics belong to the
217
+ * lowering, not the parser.
218
+ *
219
+ * A key that IS declared in `parameters` must still be supplied as
220
+ * `key = value`; a bare occurrence of a declared key is a diagnostic.
221
+ *
222
+ * When `false` (default), the validator emits `PSL_EXTENSION_UNKNOWN_PARAMETER`
223
+ * for keys absent from `parameters`.
224
+ */
225
+ readonly variadicParameters?: boolean;
189
226
  }
190
227
 
191
228
  export type AuthoringPslBlockDescriptorNamespace = {
@@ -399,7 +436,7 @@ export function mergeAuthoringNamespaces(
399
436
  }
400
437
  }
401
438
 
402
- function collectAuthoringLeafPaths(
439
+ function collectDescriptorPaths(
403
440
  namespace: Readonly<Record<string, unknown>>,
404
441
  isLeaf: (value: unknown) => boolean,
405
442
  path: readonly string[] = [],
@@ -413,29 +450,25 @@ function collectAuthoringLeafPaths(
413
450
  }
414
451
  if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
415
452
  paths.push(
416
- ...collectAuthoringLeafPaths(
417
- value as Readonly<Record<string, unknown>>,
418
- isLeaf,
419
- currentPath,
420
- ),
453
+ ...collectDescriptorPaths(value as Readonly<Record<string, unknown>>, isLeaf, currentPath),
421
454
  );
422
455
  }
423
456
  }
424
457
  return paths;
425
458
  }
426
459
 
427
- interface AuthoringLeafEntry {
460
+ interface DescriptorEntry {
428
461
  readonly path: string;
429
462
  readonly discriminator: string;
430
463
  }
431
464
 
432
- function collectAuthoringLeafDiscriminators(
465
+ function collectDescriptorEntries(
433
466
  namespace: Readonly<Record<string, unknown>>,
434
467
  isLeaf: (value: unknown) => boolean,
435
468
  label: string,
436
469
  path: readonly string[] = [],
437
- ): AuthoringLeafEntry[] {
438
- const entries: AuthoringLeafEntry[] = [];
470
+ ): DescriptorEntry[] {
471
+ const entries: DescriptorEntry[] = [];
439
472
  for (const [key, value] of Object.entries(namespace)) {
440
473
  const currentPath = [...path, key];
441
474
  if (isLeaf(value)) {
@@ -479,7 +512,7 @@ function collectAuthoringLeafDiscriminators(
479
512
  );
480
513
  }
481
514
  }
482
- entries.push(...collectAuthoringLeafDiscriminators(record, isLeaf, label, currentPath));
515
+ entries.push(...collectDescriptorEntries(record, isLeaf, label, currentPath));
483
516
  }
484
517
  }
485
518
  return entries;
@@ -491,7 +524,7 @@ function collectAuthoringLeafDiscriminators(
491
524
  * lowering factory lookup dispatches by discriminator, so one would silently
492
525
  * shadow the other. Catch duplicates before building any dispatch map.
493
526
  */
494
- function assertUniqueDiscriminators(entries: readonly AuthoringLeafEntry[], label: string): void {
527
+ function assertUniqueDiscriminators(entries: readonly DescriptorEntry[], label: string): void {
495
528
  const seen = new Map<string, string>();
496
529
  for (const { path, discriminator } of entries) {
497
530
  const existing = seen.get(discriminator);
@@ -504,23 +537,50 @@ function assertUniqueDiscriminators(entries: readonly AuthoringLeafEntry[], labe
504
537
  }
505
538
  }
506
539
 
540
+ function collectPslBlockDescriptorEntries(
541
+ namespace: Readonly<Record<string, unknown>>,
542
+ path: readonly string[] = [],
543
+ ): DescriptorEntry[] {
544
+ const entries: DescriptorEntry[] = [];
545
+ for (const [key, value] of Object.entries(namespace)) {
546
+ const currentPath = [...path, key];
547
+ if (isAuthoringPslBlockDescriptor(value)) {
548
+ entries.push({
549
+ path: currentPath.join('.'),
550
+ discriminator: value.discriminator,
551
+ });
552
+ continue;
553
+ }
554
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
555
+ const record = blindCast<
556
+ Readonly<Record<string, unknown>>,
557
+ 'walker descends into psl block namespace'
558
+ >(value);
559
+ const hasKind = record['kind'] === 'pslBlock';
560
+ const hasKeyword = typeof record['keyword'] === 'string';
561
+ const hasDiscriminator = typeof record['discriminator'] === 'string';
562
+ if (hasKind || (hasKeyword && hasDiscriminator)) {
563
+ throw new Error(
564
+ `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.`,
565
+ );
566
+ }
567
+ entries.push(...collectPslBlockDescriptorEntries(record, currentPath));
568
+ }
569
+ }
570
+ return entries;
571
+ }
572
+
507
573
  /**
508
- * Every `pslBlockDescriptors` entry needs a matching `entityTypes` factory
509
- * (same discriminator): the parser would otherwise produce an AST node
510
- * nothing can lower to an IR class instance. The link is one-directional
511
- * — an `entityTypes` factory may stand alone (e.g. `enum`, reachable from
512
- * the TypeScript builder without any PSL block).
574
+ * Every `pslBlockDescriptors` entry requires a matching `entityTypes` factory
575
+ * with the same discriminator. An `entityTypes` factory may stand alone (e.g.
576
+ * `enum`, reachable from the TypeScript builder without any PSL block).
513
577
  */
514
578
  function assertPslBlocksHaveFactories(
515
579
  entityTypeNamespace: AuthoringEntityTypeNamespace,
516
580
  pslBlockNamespace: AuthoringPslBlockDescriptorNamespace,
517
581
  ): void {
518
- const blockEntries = collectAuthoringLeafDiscriminators(
519
- pslBlockNamespace,
520
- isAuthoringPslBlockDescriptor,
521
- 'pslBlock',
522
- );
523
- const entityEntries = collectAuthoringLeafDiscriminators(
582
+ const blockEntries = collectPslBlockDescriptorEntries(pslBlockNamespace);
583
+ const entityEntries = collectDescriptorEntries(
524
584
  entityTypeNamespace,
525
585
  isAuthoringEntityTypeDescriptor,
526
586
  'entityType',
@@ -547,13 +607,13 @@ export function assertNoCrossRegistryCollisions(
547
607
  pslBlockNamespace: AuthoringPslBlockDescriptorNamespace = {},
548
608
  ): void {
549
609
  const typePaths = new Set(
550
- collectAuthoringLeafPaths(typeNamespace, isAuthoringTypeConstructorDescriptor),
610
+ collectDescriptorPaths(typeNamespace, isAuthoringTypeConstructorDescriptor),
551
611
  );
552
612
  const fieldPaths = new Set(
553
- collectAuthoringLeafPaths(fieldNamespace, isAuthoringFieldPresetDescriptor),
613
+ collectDescriptorPaths(fieldNamespace, isAuthoringFieldPresetDescriptor),
554
614
  );
555
615
  const entityPaths = new Set(
556
- collectAuthoringLeafPaths(entityTypeNamespace, isAuthoringEntityTypeDescriptor),
616
+ collectDescriptorPaths(entityTypeNamespace, isAuthoringEntityTypeDescriptor),
557
617
  );
558
618
  // Within-registry duplicate detection is handled upstream by the merge
559
619
  // walker (`mergeAuthoringNamespaces` in control-stack.ts and