@prisma-next/psl-parser 0.16.0-dev.30 → 0.16.0-dev.32
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/format.d.mts.map +1 -1
- package/dist/format.mjs +8 -2
- package/dist/format.mjs.map +1 -1
- package/dist/index.d.mts +9 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/attribute-spec/combinators/diagnostic.ts +7 -2
- package/src/attribute-spec/field-attribute.ts +2 -0
- package/src/attribute-spec/interpret.ts +1 -1
- package/src/attribute-spec/model-attribute.ts +2 -0
- package/src/attribute-spec/types.ts +11 -1
- package/src/format/error.ts +1 -1
- package/src/format/options.ts +8 -2
package/dist/format.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.mts","names":[],"sources":["../src/format/options.ts","../src/format/format.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"format.d.mts","names":[],"sources":["../src/format/options.ts","../src/format/format.ts"],"mappings":";UAEiB;WACN;WACA;;;;iBCCK,OAAO,gBAAgB,UAAU"}
|
package/dist/format.mjs
CHANGED
|
@@ -442,9 +442,15 @@ function pslError(code, message, options) {
|
|
|
442
442
|
//#region src/format/options.ts
|
|
443
443
|
function resolveFormatOptions(options) {
|
|
444
444
|
const indent = options?.indent ?? 2;
|
|
445
|
-
if (indent !== "tab" && (typeof indent !== "number" || !Number.isInteger(indent) || indent < 1)) throw
|
|
445
|
+
if (indent !== "tab" && (typeof indent !== "number" || !Number.isInteger(indent) || indent < 1)) throw pslError("PSL.FORMAT_OPTION_INVALID", `Invalid format options: indent must be a positive integer or 'tab', got ${String(indent)}`, { meta: {
|
|
446
|
+
option: "indent",
|
|
447
|
+
received: String(indent)
|
|
448
|
+
} });
|
|
446
449
|
const newline = options?.newline ?? "LF";
|
|
447
|
-
if (newline !== "LF" && newline !== "CRLF") throw
|
|
450
|
+
if (newline !== "LF" && newline !== "CRLF") throw pslError("PSL.FORMAT_OPTION_INVALID", `Invalid format options: newline must be 'LF' or 'CRLF', got ${String(newline)}`, { meta: {
|
|
451
|
+
option: "newline",
|
|
452
|
+
received: String(newline)
|
|
453
|
+
} });
|
|
448
454
|
return {
|
|
449
455
|
indentUnit: indent === "tab" ? " " : " ".repeat(indent),
|
|
450
456
|
newline: newline === "CRLF" ? "\r\n" : "\n"
|
package/dist/format.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.mjs","names":["#indentUnit","#newline","#out","#depth","#lastWasBlank","#lineOpen","#prevKind","#line","#hasContent"],"sources":["../src/format/emit.ts","../src/format/error.ts","../src/format/options.ts","../src/format/format.ts"],"sourcesContent":["import { ModelAttributeAst } from '../syntax/ast/attributes';\nimport {\n CompositeTypeDeclarationAst,\n type DocumentAst,\n FieldDeclarationAst,\n GenericBlockDeclarationAst,\n KeyValuePairAst,\n ModelDeclarationAst,\n NamedTypeDeclarationAst,\n NamespaceDeclarationAst,\n TypesBlockAst,\n} from '../syntax/ast/declarations';\nimport { type SyntaxElement, SyntaxNode, type SyntaxToken } from '../syntax/red';\nimport type { TokenKind } from '../tokenizer';\n\nexport function emitDocument(document: DocumentAst, indentUnit: string, newline: string): string {\n const writer = new LineWriter(indentUnit, newline);\n emitTopLevel(writer, document);\n return writer.finish();\n}\n\nclass LineWriter {\n readonly #indentUnit: string;\n readonly #newline: string;\n readonly #out: string[] = [];\n #depth = 0;\n #line = '';\n #lineOpen = false;\n #prevKind: TokenKind | undefined;\n #lastWasBlank = false;\n #hasContent = false;\n\n constructor(indentUnit: string, newline: string) {\n this.#indentUnit = indentUnit;\n this.#newline = newline;\n }\n\n indent(): void {\n this.#depth += 1;\n }\n\n unindent(): void {\n this.#depth = Math.max(0, this.#depth - 1);\n }\n\n lastIsBlank(): boolean {\n return this.#lastWasBlank;\n }\n\n lineOpen(): boolean {\n return this.#lineOpen;\n }\n\n prevKind(): TokenKind | undefined {\n return this.#prevKind;\n }\n\n newline(): void {\n if (!this.#lineOpen) return;\n this.#out.push(`${this.#indentUnit.repeat(this.#depth)}${this.#line}`);\n this.#line = '';\n this.#lineOpen = false;\n this.#prevKind = undefined;\n this.#lastWasBlank = false;\n this.#hasContent = true;\n }\n\n blank(): void {\n this.newline();\n if (!this.#hasContent || this.#lastWasBlank) return;\n this.#out.push('');\n this.#lastWasBlank = true;\n }\n\n write(token: SyntaxToken, space: boolean, padTo?: number): void {\n if (this.#lineOpen && padTo !== undefined) {\n this.#line = this.#line.padEnd(padTo);\n } else if (this.#lineOpen && space) {\n this.#line += ' ';\n }\n this.#line += token.text;\n this.#lineOpen = true;\n this.#prevKind = token.kind;\n }\n\n writeRaw(text: string): void {\n this.#line += text;\n this.#lineOpen = true;\n }\n\n comment(text: string): void {\n if (this.#lineOpen) this.#line += ` ${text}`;\n else this.#line = text;\n this.#lineOpen = true;\n this.newline();\n }\n\n finish(): string {\n this.newline();\n const body = this.#out.join(this.#newline);\n return body.length > 0 ? `${body}${this.#newline}` : '';\n }\n}\n\n// Qualified-name separators hug; argument/object colons keep the usual value space.\nfunction spaceBetween(\n prev: TokenKind | undefined,\n cur: TokenKind,\n inQualifiedName: boolean,\n): boolean {\n if (prev === undefined) return false;\n if (inQualifiedName) return false;\n\n switch (cur) {\n case 'LParen':\n case 'LBracket':\n case 'RParen':\n case 'RBracket':\n case 'Comma':\n case 'Question':\n case 'Dot':\n case 'Colon':\n return false;\n case 'RBrace':\n return prev !== 'LBrace';\n default:\n break;\n }\n switch (prev) {\n case 'LParen':\n case 'LBracket':\n case 'Dot':\n case 'At':\n case 'DoubleAt':\n return false;\n default:\n return true;\n }\n}\n\nfunction streamNode(writer: LineWriter, node: SyntaxNode, padTo?: number): number {\n let continuation = 0;\n let first = true;\n let prevQualified = false;\n\n const walk = (parent: SyntaxNode, qualified: boolean): void => {\n for (const child of parent.children()) {\n if (child instanceof SyntaxNode) {\n walk(child, qualified || child.kind === 'QualifiedName');\n continue;\n }\n if (child.kind === 'Whitespace' || child.kind === 'Newline') continue;\n if (child.kind === 'Comment') {\n writer.comment(child.text);\n writer.indent();\n continuation += 1;\n prevQualified = false;\n first = false;\n continue;\n }\n const pad = first ? padTo : undefined;\n const space = spaceBetween(writer.prevKind(), child.kind, qualified && prevQualified);\n writer.write(child, space, writer.lineOpen() ? pad : undefined);\n prevQualified = qualified;\n first = false;\n }\n };\n\n walk(node, false);\n return continuation;\n}\n\nfunction closeContinuation(writer: LineWriter, count: number): void {\n for (let i = 0; i < count; i++) writer.unindent();\n}\n\nfunction emitField(\n writer: LineWriter,\n field: FieldDeclarationAst,\n columns: AlignmentColumns | undefined,\n): number {\n return streamRow(writer, field.syntax, columns);\n}\n\nfunction emitNamedType(writer: LineWriter, decl: NamedTypeDeclarationAst): number {\n return streamRow(writer, decl.syntax, undefined);\n}\n\nfunction streamRow(\n writer: LineWriter,\n row: SyntaxNode,\n columns: AlignmentColumns | undefined,\n): number {\n let continuation = 0;\n let sawAttribute = false;\n\n for (const child of row.children()) {\n if (child instanceof SyntaxNode) {\n let padTo: number | undefined;\n if (child.kind === 'TypeAnnotation' && continuation === 0) {\n padTo = columns?.typeColumn;\n } else if (child.kind === 'FieldAttribute') {\n if (continuation > 0) writer.newline();\n else if (!sawAttribute) padTo = columns?.attributeColumn;\n sawAttribute = true;\n }\n continuation += streamNode(writer, child, padTo);\n continue;\n }\n if (child.kind === 'Whitespace' || child.kind === 'Newline') continue;\n if (child.kind === 'Comment') {\n writer.comment(child.text);\n writer.indent();\n continuation += 1;\n continue;\n }\n const space = spaceBetween(writer.prevKind(), child.kind, false);\n writer.write(child, space);\n }\n\n return continuation;\n}\n\nfunction emitBlockAttribute(writer: LineWriter, attribute: ModelAttributeAst): number {\n return streamNode(writer, attribute.syntax);\n}\n\nfunction emitKeyValue(writer: LineWriter, pair: KeyValuePairAst): number {\n return streamNode(writer, pair.syntax);\n}\n\ntype MemberCategory = 'regular' | 'blockAttribute' | 'nestedBlock';\n\ninterface BlockMember {\n readonly category: MemberCategory;\n emit(trailing: string | undefined): number;\n}\n\nfunction leafMember(\n writer: LineWriter,\n category: MemberCategory,\n print: () => number,\n): BlockMember {\n return {\n category,\n emit(trailing) {\n const continuation = print();\n if (trailing !== undefined) writer.comment(trailing);\n else writer.newline();\n return continuation;\n },\n };\n}\n\ntype MemberClassifier = (node: SyntaxNode) => BlockMember | undefined;\n\nfunction emitModel(\n writer: LineWriter,\n model: ModelDeclarationAst,\n trailing: string | undefined,\n): void {\n const columns = alignmentMap(model.syntax);\n emitBlockBody(writer, model.syntax, trailing, (node) => {\n const field = FieldDeclarationAst.cast(node);\n if (field) return leafMember(writer, 'regular', () => emitField(writer, field, columns));\n const attribute = ModelAttributeAst.cast(node);\n if (attribute)\n return leafMember(writer, 'blockAttribute', () => emitBlockAttribute(writer, attribute));\n return undefined;\n });\n}\n\nfunction emitCompositeType(\n writer: LineWriter,\n composite: CompositeTypeDeclarationAst,\n trailing: string | undefined,\n): void {\n const columns = alignmentMap(composite.syntax);\n emitBlockBody(writer, composite.syntax, trailing, (node) => {\n const field = FieldDeclarationAst.cast(node);\n if (field) return leafMember(writer, 'regular', () => emitField(writer, field, columns));\n const attribute = ModelAttributeAst.cast(node);\n if (attribute)\n return leafMember(writer, 'blockAttribute', () => emitBlockAttribute(writer, attribute));\n return undefined;\n });\n}\n\nfunction emitGenericBlock(\n writer: LineWriter,\n block: GenericBlockDeclarationAst,\n trailing: string | undefined,\n): void {\n emitBlockBody(writer, block.syntax, trailing, (node) => {\n const entry = KeyValuePairAst.cast(node);\n if (entry) return leafMember(writer, 'regular', () => emitKeyValue(writer, entry));\n const attribute = ModelAttributeAst.cast(node);\n if (attribute)\n return leafMember(writer, 'blockAttribute', () => emitBlockAttribute(writer, attribute));\n return undefined;\n });\n}\n\nfunction emitNamespace(\n writer: LineWriter,\n namespace: NamespaceDeclarationAst,\n trailing: string | undefined,\n): void {\n emitBlockBody(writer, namespace.syntax, trailing, (node) => {\n const declaration = castBlockDeclaration(node);\n if (declaration) return nestedBlockMember(writer, declaration);\n return undefined;\n });\n}\n\nfunction emitTypesBlock(\n writer: LineWriter,\n block: TypesBlockAst,\n trailing: string | undefined,\n): void {\n emitBlockBody(writer, block.syntax, trailing, (node) => {\n const named = NamedTypeDeclarationAst.cast(node);\n if (named) return leafMember(writer, 'regular', () => emitNamedType(writer, named));\n return undefined;\n });\n}\n\nfunction emitTopLevel(writer: LineWriter, document: DocumentAst): void {\n walkRegion(writer, Array.from(document.syntax.children()), undefined, (node) => {\n const declaration = castTopLevelDeclaration(node);\n if (declaration) return nestedBlockMember(writer, declaration);\n return undefined;\n });\n}\n\ntype BlockEmitter = (writer: LineWriter, trailing: string | undefined) => void;\n\nfunction nestedBlockMember(writer: LineWriter, block: BlockEmitter): BlockMember {\n return {\n category: 'nestedBlock',\n emit(trailing) {\n block(writer, trailing);\n return 0;\n },\n };\n}\n\nfunction castBlockDeclaration(node: SyntaxNode): BlockEmitter | undefined {\n const model = ModelDeclarationAst.cast(node);\n if (model) return (writer, trailing) => emitModel(writer, model, trailing);\n const composite = CompositeTypeDeclarationAst.cast(node);\n if (composite) return (writer, trailing) => emitCompositeType(writer, composite, trailing);\n const generic = GenericBlockDeclarationAst.cast(node);\n if (generic) return (writer, trailing) => emitGenericBlock(writer, generic, trailing);\n return undefined;\n}\n\nfunction castTopLevelDeclaration(node: SyntaxNode): BlockEmitter | undefined {\n const block = castBlockDeclaration(node);\n if (block) return block;\n const namespace = NamespaceDeclarationAst.cast(node);\n if (namespace) return (writer, trailing) => emitNamespace(writer, namespace, trailing);\n const types = TypesBlockAst.cast(node);\n if (types) return (writer, trailing) => emitTypesBlock(writer, types, trailing);\n return undefined;\n}\n\nfunction emitBlockBody(\n writer: LineWriter,\n node: SyntaxNode,\n closingTrailing: string | undefined,\n classify: MemberClassifier,\n): void {\n const children = Array.from(node.children());\n const openIndex = children.findIndex((el) => !(el instanceof SyntaxNode) && el.kind === 'LBrace');\n\n streamHeader(writer, node);\n const headerComment = sameLineCommentAfter(children, openIndex);\n if (headerComment !== undefined) writer.comment(headerComment);\n else writer.newline();\n\n writer.indent();\n walkRegion(writer, children, 'RBrace', classify);\n writer.unindent();\n\n writer.writeRaw('}');\n if (closingTrailing !== undefined) writer.comment(closingTrailing);\n else writer.newline();\n}\n\nfunction streamHeader(writer: LineWriter, node: SyntaxNode): void {\n let done = false;\n const walk = (parent: SyntaxNode): void => {\n for (const child of parent.children()) {\n if (done) return;\n if (child instanceof SyntaxNode) {\n walk(child);\n continue;\n }\n if (child.kind === 'Whitespace' || child.kind === 'Newline' || child.kind === 'Comment') {\n continue;\n }\n const space = spaceBetween(writer.prevKind(), child.kind, false);\n writer.write(child, space);\n if (child.kind === 'LBrace') {\n done = true;\n return;\n }\n }\n };\n walk(node);\n}\n\nfunction walkRegion(\n writer: LineWriter,\n elements: readonly SyntaxElement[],\n closeKind: 'RBrace' | undefined,\n classify: MemberClassifier,\n): void {\n let sawOpenBrace = closeKind === undefined;\n let sawContent = false;\n let lastWasRegular = false;\n let ledByComment = false;\n let newlines = 0;\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n if (element === undefined) continue;\n\n if (element instanceof SyntaxNode) {\n if (!sawOpenBrace) continue;\n const member = classify(element);\n if (member === undefined) continue;\n if (!ledByComment) {\n if (newlines >= 2 && sawContent && !writer.lastIsBlank()) writer.blank();\n else if (separationBlankWanted(writer, member.category, sawContent, lastWasRegular)) {\n writer.blank();\n }\n }\n\n const trailing = sameLineTrailingComment(elements, i);\n closeContinuation(writer, member.emit(trailing.text));\n if (trailing.index !== undefined) i = trailing.index;\n sawContent = true;\n lastWasRegular = member.category !== 'blockAttribute';\n ledByComment = false;\n newlines = 0;\n continue;\n }\n\n if (element.kind === 'LBrace' && closeKind === 'RBrace' && !sawOpenBrace) {\n sawOpenBrace = true;\n newlines = 0;\n continue;\n }\n if (!sawOpenBrace) continue;\n if (closeKind === 'RBrace' && element.kind === 'RBrace') break;\n if (element.kind === 'Whitespace') continue;\n if (element.kind === 'Newline') {\n newlines += 1;\n continue;\n }\n if (element.kind === 'Comment') {\n if (closeKind === 'RBrace' && newlines === 0 && !sawContent) {\n // Same-line comment trailing the opening `{`: owned by the block header.\n continue;\n }\n if (newlines >= 2 && sawContent && !writer.lastIsBlank()) writer.blank();\n else if (!ledByComment) {\n const led = leadingMemberAfter(elements, i, classify);\n if (led && separationBlankWanted(writer, led, sawContent, lastWasRegular)) writer.blank();\n }\n writer.writeRaw(element.text);\n writer.newline();\n sawContent = true;\n ledByComment = true;\n newlines = 0;\n }\n }\n}\n\nfunction separationBlankWanted(\n writer: LineWriter,\n category: MemberCategory,\n sawContent: boolean,\n lastWasRegular: boolean,\n): boolean {\n if (!sawContent || writer.lastIsBlank()) return false;\n if (category === 'nestedBlock') return true;\n return category === 'blockAttribute' && lastWasRegular;\n}\n\nfunction leadingMemberAfter(\n elements: readonly SyntaxElement[],\n commentIndex: number,\n classify: MemberClassifier,\n): MemberCategory | undefined {\n for (let i = commentIndex + 1; i < elements.length; i++) {\n const element = elements[i];\n if (element === undefined) continue;\n if (element instanceof SyntaxNode) return classify(element)?.category;\n if (element.kind === 'RBrace') return undefined;\n }\n return undefined;\n}\n\nfunction sameLineTrailingComment(\n elements: readonly SyntaxElement[],\n memberIndex: number,\n): { text: string | undefined; index: number | undefined } {\n for (let i = memberIndex + 1; i < elements.length; i++) {\n const element = elements[i];\n if (element === undefined) continue;\n if (element instanceof SyntaxNode) break;\n if (element.kind === 'Whitespace') continue;\n if (element.kind === 'Comment') return { text: element.text, index: i };\n break;\n }\n return { text: undefined, index: undefined };\n}\n\nfunction sameLineCommentAfter(\n children: readonly SyntaxElement[],\n openIndex: number,\n): string | undefined {\n for (let i = openIndex + 1; i < children.length; i++) {\n const child = children[i];\n if (child === undefined) continue;\n if (child instanceof SyntaxNode) return undefined;\n if (child.kind === 'Whitespace') continue;\n if (child.kind === 'Comment') return child.text;\n return undefined;\n }\n return undefined;\n}\n\ninterface AlignmentColumns {\n readonly typeColumn: number;\n readonly attributeColumn: number;\n}\n\nfunction alignmentMap(block: SyntaxNode): AlignmentColumns | undefined {\n const fields: SyntaxNode[] = [];\n for (const element of block.children()) {\n if (!(element instanceof SyntaxNode)) continue;\n if (FieldDeclarationAst.cast(element) === undefined) continue;\n // Interior comments split rows into continuation lines, so those rows opt out of alignment.\n if (hasInteriorComment(element)) continue;\n fields.push(element);\n }\n if (fields.length === 0) return undefined;\n return alignmentColumns(fields);\n}\n\nfunction alignmentColumns(rows: readonly SyntaxNode[]): AlignmentColumns {\n let nameWidth = 0;\n for (const row of rows) {\n const field = FieldDeclarationAst.cast(row);\n if (!field) continue;\n nameWidth = Math.max(nameWidth, renderTokens(field.name()?.syntax).length);\n }\n const typeColumn = nameWidth + 1;\n let cellEnd = 0;\n for (const row of rows) {\n const field = FieldDeclarationAst.cast(row);\n if (!field) continue;\n const name = renderTokens(field.name()?.syntax);\n const type = renderTokens(field.typeAnnotation()?.syntax);\n cellEnd = Math.max(cellEnd, type.length > 0 ? typeColumn + type.length : name.length);\n }\n return { typeColumn, attributeColumn: cellEnd + 1 };\n}\n\nfunction hasInteriorComment(node: SyntaxNode): boolean {\n for (const token of node.tokens()) {\n if (token.kind === 'Comment') return true;\n }\n return false;\n}\n\nfunction renderTokens(node: SyntaxNode | undefined): string {\n if (!node) return '';\n let out = '';\n let prev: TokenKind | undefined;\n let prevQualified = false;\n const walk = (parent: SyntaxNode, qualified: boolean): void => {\n for (const child of parent.children()) {\n if (child instanceof SyntaxNode) {\n walk(child, qualified || child.kind === 'QualifiedName');\n continue;\n }\n if (child.kind === 'Whitespace' || child.kind === 'Newline' || child.kind === 'Comment') {\n continue;\n }\n if (spaceBetween(prev, child.kind, qualified && prevQualified)) out += ' ';\n out += child.text;\n prev = child.kind;\n prevQualified = qualified;\n }\n };\n walk(node, false);\n return out;\n}\n","import type { StructuredError, StructuredErrorOptions } from '@prisma-next/utils/structured-error';\nimport { structuredError } from '@prisma-next/utils/structured-error';\n\nexport type PslCode = `PSL.${PslSubcode}`;\n\ntype PslSubcode = 'PARSE_FAILED';\n\nexport function pslError(\n code: PslCode,\n message: string,\n options?: StructuredErrorOptions,\n): StructuredError {\n return structuredError(code, message, options);\n}\n","export interface FormatOptions {\n readonly indent?: number | 'tab';\n readonly newline?: 'LF' | 'CRLF';\n}\n\nexport interface ResolvedFormatOptions {\n readonly indentUnit: string;\n readonly newline: string;\n}\n\nexport function resolveFormatOptions(options: FormatOptions | undefined): ResolvedFormatOptions {\n const indent = options?.indent ?? 2;\n if (indent !== 'tab' && (typeof indent !== 'number' || !Number.isInteger(indent) || indent < 1)) {\n throw new TypeError(\n `Invalid format options: indent must be a positive integer or 'tab', got ${String(indent)}`,\n );\n }\n const newline = options?.newline ?? 'LF';\n if (newline !== 'LF' && newline !== 'CRLF') {\n throw new TypeError(\n `Invalid format options: newline must be 'LF' or 'CRLF', got ${String(newline)}`,\n );\n }\n return {\n indentUnit: indent === 'tab' ? '\\t' : ' '.repeat(indent),\n newline: newline === 'CRLF' ? '\\r\\n' : '\\n',\n };\n}\n","import { parse } from '../parse';\nimport { emitDocument } from './emit';\nimport { pslError } from './error';\nimport { type FormatOptions, resolveFormatOptions } from './options';\n\nexport function format(source: string, options?: FormatOptions): string {\n const resolved = resolveFormatOptions(options);\n const { document, diagnostics } = parse(source);\n if (diagnostics.length > 0) {\n const summary = diagnostics[0]?.message ?? 'unknown parse error';\n const more = diagnostics.length > 1 ? ` (and ${diagnostics.length - 1} more)` : '';\n throw pslError('PSL.PARSE_FAILED', `Cannot format PSL with parse errors: ${summary}${more}`, {\n meta: { diagnostics },\n });\n }\n return emitDocument(document, resolved.indentUnit, resolved.newline);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"format.mjs","names":["#indentUnit","#newline","#out","#depth","#lastWasBlank","#lineOpen","#prevKind","#line","#hasContent"],"sources":["../src/format/emit.ts","../src/format/error.ts","../src/format/options.ts","../src/format/format.ts"],"sourcesContent":["import { ModelAttributeAst } from '../syntax/ast/attributes';\nimport {\n CompositeTypeDeclarationAst,\n type DocumentAst,\n FieldDeclarationAst,\n GenericBlockDeclarationAst,\n KeyValuePairAst,\n ModelDeclarationAst,\n NamedTypeDeclarationAst,\n NamespaceDeclarationAst,\n TypesBlockAst,\n} from '../syntax/ast/declarations';\nimport { type SyntaxElement, SyntaxNode, type SyntaxToken } from '../syntax/red';\nimport type { TokenKind } from '../tokenizer';\n\nexport function emitDocument(document: DocumentAst, indentUnit: string, newline: string): string {\n const writer = new LineWriter(indentUnit, newline);\n emitTopLevel(writer, document);\n return writer.finish();\n}\n\nclass LineWriter {\n readonly #indentUnit: string;\n readonly #newline: string;\n readonly #out: string[] = [];\n #depth = 0;\n #line = '';\n #lineOpen = false;\n #prevKind: TokenKind | undefined;\n #lastWasBlank = false;\n #hasContent = false;\n\n constructor(indentUnit: string, newline: string) {\n this.#indentUnit = indentUnit;\n this.#newline = newline;\n }\n\n indent(): void {\n this.#depth += 1;\n }\n\n unindent(): void {\n this.#depth = Math.max(0, this.#depth - 1);\n }\n\n lastIsBlank(): boolean {\n return this.#lastWasBlank;\n }\n\n lineOpen(): boolean {\n return this.#lineOpen;\n }\n\n prevKind(): TokenKind | undefined {\n return this.#prevKind;\n }\n\n newline(): void {\n if (!this.#lineOpen) return;\n this.#out.push(`${this.#indentUnit.repeat(this.#depth)}${this.#line}`);\n this.#line = '';\n this.#lineOpen = false;\n this.#prevKind = undefined;\n this.#lastWasBlank = false;\n this.#hasContent = true;\n }\n\n blank(): void {\n this.newline();\n if (!this.#hasContent || this.#lastWasBlank) return;\n this.#out.push('');\n this.#lastWasBlank = true;\n }\n\n write(token: SyntaxToken, space: boolean, padTo?: number): void {\n if (this.#lineOpen && padTo !== undefined) {\n this.#line = this.#line.padEnd(padTo);\n } else if (this.#lineOpen && space) {\n this.#line += ' ';\n }\n this.#line += token.text;\n this.#lineOpen = true;\n this.#prevKind = token.kind;\n }\n\n writeRaw(text: string): void {\n this.#line += text;\n this.#lineOpen = true;\n }\n\n comment(text: string): void {\n if (this.#lineOpen) this.#line += ` ${text}`;\n else this.#line = text;\n this.#lineOpen = true;\n this.newline();\n }\n\n finish(): string {\n this.newline();\n const body = this.#out.join(this.#newline);\n return body.length > 0 ? `${body}${this.#newline}` : '';\n }\n}\n\n// Qualified-name separators hug; argument/object colons keep the usual value space.\nfunction spaceBetween(\n prev: TokenKind | undefined,\n cur: TokenKind,\n inQualifiedName: boolean,\n): boolean {\n if (prev === undefined) return false;\n if (inQualifiedName) return false;\n\n switch (cur) {\n case 'LParen':\n case 'LBracket':\n case 'RParen':\n case 'RBracket':\n case 'Comma':\n case 'Question':\n case 'Dot':\n case 'Colon':\n return false;\n case 'RBrace':\n return prev !== 'LBrace';\n default:\n break;\n }\n switch (prev) {\n case 'LParen':\n case 'LBracket':\n case 'Dot':\n case 'At':\n case 'DoubleAt':\n return false;\n default:\n return true;\n }\n}\n\nfunction streamNode(writer: LineWriter, node: SyntaxNode, padTo?: number): number {\n let continuation = 0;\n let first = true;\n let prevQualified = false;\n\n const walk = (parent: SyntaxNode, qualified: boolean): void => {\n for (const child of parent.children()) {\n if (child instanceof SyntaxNode) {\n walk(child, qualified || child.kind === 'QualifiedName');\n continue;\n }\n if (child.kind === 'Whitespace' || child.kind === 'Newline') continue;\n if (child.kind === 'Comment') {\n writer.comment(child.text);\n writer.indent();\n continuation += 1;\n prevQualified = false;\n first = false;\n continue;\n }\n const pad = first ? padTo : undefined;\n const space = spaceBetween(writer.prevKind(), child.kind, qualified && prevQualified);\n writer.write(child, space, writer.lineOpen() ? pad : undefined);\n prevQualified = qualified;\n first = false;\n }\n };\n\n walk(node, false);\n return continuation;\n}\n\nfunction closeContinuation(writer: LineWriter, count: number): void {\n for (let i = 0; i < count; i++) writer.unindent();\n}\n\nfunction emitField(\n writer: LineWriter,\n field: FieldDeclarationAst,\n columns: AlignmentColumns | undefined,\n): number {\n return streamRow(writer, field.syntax, columns);\n}\n\nfunction emitNamedType(writer: LineWriter, decl: NamedTypeDeclarationAst): number {\n return streamRow(writer, decl.syntax, undefined);\n}\n\nfunction streamRow(\n writer: LineWriter,\n row: SyntaxNode,\n columns: AlignmentColumns | undefined,\n): number {\n let continuation = 0;\n let sawAttribute = false;\n\n for (const child of row.children()) {\n if (child instanceof SyntaxNode) {\n let padTo: number | undefined;\n if (child.kind === 'TypeAnnotation' && continuation === 0) {\n padTo = columns?.typeColumn;\n } else if (child.kind === 'FieldAttribute') {\n if (continuation > 0) writer.newline();\n else if (!sawAttribute) padTo = columns?.attributeColumn;\n sawAttribute = true;\n }\n continuation += streamNode(writer, child, padTo);\n continue;\n }\n if (child.kind === 'Whitespace' || child.kind === 'Newline') continue;\n if (child.kind === 'Comment') {\n writer.comment(child.text);\n writer.indent();\n continuation += 1;\n continue;\n }\n const space = spaceBetween(writer.prevKind(), child.kind, false);\n writer.write(child, space);\n }\n\n return continuation;\n}\n\nfunction emitBlockAttribute(writer: LineWriter, attribute: ModelAttributeAst): number {\n return streamNode(writer, attribute.syntax);\n}\n\nfunction emitKeyValue(writer: LineWriter, pair: KeyValuePairAst): number {\n return streamNode(writer, pair.syntax);\n}\n\ntype MemberCategory = 'regular' | 'blockAttribute' | 'nestedBlock';\n\ninterface BlockMember {\n readonly category: MemberCategory;\n emit(trailing: string | undefined): number;\n}\n\nfunction leafMember(\n writer: LineWriter,\n category: MemberCategory,\n print: () => number,\n): BlockMember {\n return {\n category,\n emit(trailing) {\n const continuation = print();\n if (trailing !== undefined) writer.comment(trailing);\n else writer.newline();\n return continuation;\n },\n };\n}\n\ntype MemberClassifier = (node: SyntaxNode) => BlockMember | undefined;\n\nfunction emitModel(\n writer: LineWriter,\n model: ModelDeclarationAst,\n trailing: string | undefined,\n): void {\n const columns = alignmentMap(model.syntax);\n emitBlockBody(writer, model.syntax, trailing, (node) => {\n const field = FieldDeclarationAst.cast(node);\n if (field) return leafMember(writer, 'regular', () => emitField(writer, field, columns));\n const attribute = ModelAttributeAst.cast(node);\n if (attribute)\n return leafMember(writer, 'blockAttribute', () => emitBlockAttribute(writer, attribute));\n return undefined;\n });\n}\n\nfunction emitCompositeType(\n writer: LineWriter,\n composite: CompositeTypeDeclarationAst,\n trailing: string | undefined,\n): void {\n const columns = alignmentMap(composite.syntax);\n emitBlockBody(writer, composite.syntax, trailing, (node) => {\n const field = FieldDeclarationAst.cast(node);\n if (field) return leafMember(writer, 'regular', () => emitField(writer, field, columns));\n const attribute = ModelAttributeAst.cast(node);\n if (attribute)\n return leafMember(writer, 'blockAttribute', () => emitBlockAttribute(writer, attribute));\n return undefined;\n });\n}\n\nfunction emitGenericBlock(\n writer: LineWriter,\n block: GenericBlockDeclarationAst,\n trailing: string | undefined,\n): void {\n emitBlockBody(writer, block.syntax, trailing, (node) => {\n const entry = KeyValuePairAst.cast(node);\n if (entry) return leafMember(writer, 'regular', () => emitKeyValue(writer, entry));\n const attribute = ModelAttributeAst.cast(node);\n if (attribute)\n return leafMember(writer, 'blockAttribute', () => emitBlockAttribute(writer, attribute));\n return undefined;\n });\n}\n\nfunction emitNamespace(\n writer: LineWriter,\n namespace: NamespaceDeclarationAst,\n trailing: string | undefined,\n): void {\n emitBlockBody(writer, namespace.syntax, trailing, (node) => {\n const declaration = castBlockDeclaration(node);\n if (declaration) return nestedBlockMember(writer, declaration);\n return undefined;\n });\n}\n\nfunction emitTypesBlock(\n writer: LineWriter,\n block: TypesBlockAst,\n trailing: string | undefined,\n): void {\n emitBlockBody(writer, block.syntax, trailing, (node) => {\n const named = NamedTypeDeclarationAst.cast(node);\n if (named) return leafMember(writer, 'regular', () => emitNamedType(writer, named));\n return undefined;\n });\n}\n\nfunction emitTopLevel(writer: LineWriter, document: DocumentAst): void {\n walkRegion(writer, Array.from(document.syntax.children()), undefined, (node) => {\n const declaration = castTopLevelDeclaration(node);\n if (declaration) return nestedBlockMember(writer, declaration);\n return undefined;\n });\n}\n\ntype BlockEmitter = (writer: LineWriter, trailing: string | undefined) => void;\n\nfunction nestedBlockMember(writer: LineWriter, block: BlockEmitter): BlockMember {\n return {\n category: 'nestedBlock',\n emit(trailing) {\n block(writer, trailing);\n return 0;\n },\n };\n}\n\nfunction castBlockDeclaration(node: SyntaxNode): BlockEmitter | undefined {\n const model = ModelDeclarationAst.cast(node);\n if (model) return (writer, trailing) => emitModel(writer, model, trailing);\n const composite = CompositeTypeDeclarationAst.cast(node);\n if (composite) return (writer, trailing) => emitCompositeType(writer, composite, trailing);\n const generic = GenericBlockDeclarationAst.cast(node);\n if (generic) return (writer, trailing) => emitGenericBlock(writer, generic, trailing);\n return undefined;\n}\n\nfunction castTopLevelDeclaration(node: SyntaxNode): BlockEmitter | undefined {\n const block = castBlockDeclaration(node);\n if (block) return block;\n const namespace = NamespaceDeclarationAst.cast(node);\n if (namespace) return (writer, trailing) => emitNamespace(writer, namespace, trailing);\n const types = TypesBlockAst.cast(node);\n if (types) return (writer, trailing) => emitTypesBlock(writer, types, trailing);\n return undefined;\n}\n\nfunction emitBlockBody(\n writer: LineWriter,\n node: SyntaxNode,\n closingTrailing: string | undefined,\n classify: MemberClassifier,\n): void {\n const children = Array.from(node.children());\n const openIndex = children.findIndex((el) => !(el instanceof SyntaxNode) && el.kind === 'LBrace');\n\n streamHeader(writer, node);\n const headerComment = sameLineCommentAfter(children, openIndex);\n if (headerComment !== undefined) writer.comment(headerComment);\n else writer.newline();\n\n writer.indent();\n walkRegion(writer, children, 'RBrace', classify);\n writer.unindent();\n\n writer.writeRaw('}');\n if (closingTrailing !== undefined) writer.comment(closingTrailing);\n else writer.newline();\n}\n\nfunction streamHeader(writer: LineWriter, node: SyntaxNode): void {\n let done = false;\n const walk = (parent: SyntaxNode): void => {\n for (const child of parent.children()) {\n if (done) return;\n if (child instanceof SyntaxNode) {\n walk(child);\n continue;\n }\n if (child.kind === 'Whitespace' || child.kind === 'Newline' || child.kind === 'Comment') {\n continue;\n }\n const space = spaceBetween(writer.prevKind(), child.kind, false);\n writer.write(child, space);\n if (child.kind === 'LBrace') {\n done = true;\n return;\n }\n }\n };\n walk(node);\n}\n\nfunction walkRegion(\n writer: LineWriter,\n elements: readonly SyntaxElement[],\n closeKind: 'RBrace' | undefined,\n classify: MemberClassifier,\n): void {\n let sawOpenBrace = closeKind === undefined;\n let sawContent = false;\n let lastWasRegular = false;\n let ledByComment = false;\n let newlines = 0;\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n if (element === undefined) continue;\n\n if (element instanceof SyntaxNode) {\n if (!sawOpenBrace) continue;\n const member = classify(element);\n if (member === undefined) continue;\n if (!ledByComment) {\n if (newlines >= 2 && sawContent && !writer.lastIsBlank()) writer.blank();\n else if (separationBlankWanted(writer, member.category, sawContent, lastWasRegular)) {\n writer.blank();\n }\n }\n\n const trailing = sameLineTrailingComment(elements, i);\n closeContinuation(writer, member.emit(trailing.text));\n if (trailing.index !== undefined) i = trailing.index;\n sawContent = true;\n lastWasRegular = member.category !== 'blockAttribute';\n ledByComment = false;\n newlines = 0;\n continue;\n }\n\n if (element.kind === 'LBrace' && closeKind === 'RBrace' && !sawOpenBrace) {\n sawOpenBrace = true;\n newlines = 0;\n continue;\n }\n if (!sawOpenBrace) continue;\n if (closeKind === 'RBrace' && element.kind === 'RBrace') break;\n if (element.kind === 'Whitespace') continue;\n if (element.kind === 'Newline') {\n newlines += 1;\n continue;\n }\n if (element.kind === 'Comment') {\n if (closeKind === 'RBrace' && newlines === 0 && !sawContent) {\n // Same-line comment trailing the opening `{`: owned by the block header.\n continue;\n }\n if (newlines >= 2 && sawContent && !writer.lastIsBlank()) writer.blank();\n else if (!ledByComment) {\n const led = leadingMemberAfter(elements, i, classify);\n if (led && separationBlankWanted(writer, led, sawContent, lastWasRegular)) writer.blank();\n }\n writer.writeRaw(element.text);\n writer.newline();\n sawContent = true;\n ledByComment = true;\n newlines = 0;\n }\n }\n}\n\nfunction separationBlankWanted(\n writer: LineWriter,\n category: MemberCategory,\n sawContent: boolean,\n lastWasRegular: boolean,\n): boolean {\n if (!sawContent || writer.lastIsBlank()) return false;\n if (category === 'nestedBlock') return true;\n return category === 'blockAttribute' && lastWasRegular;\n}\n\nfunction leadingMemberAfter(\n elements: readonly SyntaxElement[],\n commentIndex: number,\n classify: MemberClassifier,\n): MemberCategory | undefined {\n for (let i = commentIndex + 1; i < elements.length; i++) {\n const element = elements[i];\n if (element === undefined) continue;\n if (element instanceof SyntaxNode) return classify(element)?.category;\n if (element.kind === 'RBrace') return undefined;\n }\n return undefined;\n}\n\nfunction sameLineTrailingComment(\n elements: readonly SyntaxElement[],\n memberIndex: number,\n): { text: string | undefined; index: number | undefined } {\n for (let i = memberIndex + 1; i < elements.length; i++) {\n const element = elements[i];\n if (element === undefined) continue;\n if (element instanceof SyntaxNode) break;\n if (element.kind === 'Whitespace') continue;\n if (element.kind === 'Comment') return { text: element.text, index: i };\n break;\n }\n return { text: undefined, index: undefined };\n}\n\nfunction sameLineCommentAfter(\n children: readonly SyntaxElement[],\n openIndex: number,\n): string | undefined {\n for (let i = openIndex + 1; i < children.length; i++) {\n const child = children[i];\n if (child === undefined) continue;\n if (child instanceof SyntaxNode) return undefined;\n if (child.kind === 'Whitespace') continue;\n if (child.kind === 'Comment') return child.text;\n return undefined;\n }\n return undefined;\n}\n\ninterface AlignmentColumns {\n readonly typeColumn: number;\n readonly attributeColumn: number;\n}\n\nfunction alignmentMap(block: SyntaxNode): AlignmentColumns | undefined {\n const fields: SyntaxNode[] = [];\n for (const element of block.children()) {\n if (!(element instanceof SyntaxNode)) continue;\n if (FieldDeclarationAst.cast(element) === undefined) continue;\n // Interior comments split rows into continuation lines, so those rows opt out of alignment.\n if (hasInteriorComment(element)) continue;\n fields.push(element);\n }\n if (fields.length === 0) return undefined;\n return alignmentColumns(fields);\n}\n\nfunction alignmentColumns(rows: readonly SyntaxNode[]): AlignmentColumns {\n let nameWidth = 0;\n for (const row of rows) {\n const field = FieldDeclarationAst.cast(row);\n if (!field) continue;\n nameWidth = Math.max(nameWidth, renderTokens(field.name()?.syntax).length);\n }\n const typeColumn = nameWidth + 1;\n let cellEnd = 0;\n for (const row of rows) {\n const field = FieldDeclarationAst.cast(row);\n if (!field) continue;\n const name = renderTokens(field.name()?.syntax);\n const type = renderTokens(field.typeAnnotation()?.syntax);\n cellEnd = Math.max(cellEnd, type.length > 0 ? typeColumn + type.length : name.length);\n }\n return { typeColumn, attributeColumn: cellEnd + 1 };\n}\n\nfunction hasInteriorComment(node: SyntaxNode): boolean {\n for (const token of node.tokens()) {\n if (token.kind === 'Comment') return true;\n }\n return false;\n}\n\nfunction renderTokens(node: SyntaxNode | undefined): string {\n if (!node) return '';\n let out = '';\n let prev: TokenKind | undefined;\n let prevQualified = false;\n const walk = (parent: SyntaxNode, qualified: boolean): void => {\n for (const child of parent.children()) {\n if (child instanceof SyntaxNode) {\n walk(child, qualified || child.kind === 'QualifiedName');\n continue;\n }\n if (child.kind === 'Whitespace' || child.kind === 'Newline' || child.kind === 'Comment') {\n continue;\n }\n if (spaceBetween(prev, child.kind, qualified && prevQualified)) out += ' ';\n out += child.text;\n prev = child.kind;\n prevQualified = qualified;\n }\n };\n walk(node, false);\n return out;\n}\n","import type { StructuredError, StructuredErrorOptions } from '@prisma-next/utils/structured-error';\nimport { structuredError } from '@prisma-next/utils/structured-error';\n\nexport type PslCode = `PSL.${PslSubcode}`;\n\ntype PslSubcode = 'FORMAT_OPTION_INVALID' | 'PARSE_FAILED';\n\nexport function pslError(\n code: PslCode,\n message: string,\n options?: StructuredErrorOptions,\n): StructuredError {\n return structuredError(code, message, options);\n}\n","import { pslError } from './error';\n\nexport interface FormatOptions {\n readonly indent?: number | 'tab';\n readonly newline?: 'LF' | 'CRLF';\n}\n\nexport interface ResolvedFormatOptions {\n readonly indentUnit: string;\n readonly newline: string;\n}\n\nexport function resolveFormatOptions(options: FormatOptions | undefined): ResolvedFormatOptions {\n const indent = options?.indent ?? 2;\n if (indent !== 'tab' && (typeof indent !== 'number' || !Number.isInteger(indent) || indent < 1)) {\n throw pslError(\n 'PSL.FORMAT_OPTION_INVALID',\n `Invalid format options: indent must be a positive integer or 'tab', got ${String(indent)}`,\n { meta: { option: 'indent', received: String(indent) } },\n );\n }\n const newline = options?.newline ?? 'LF';\n if (newline !== 'LF' && newline !== 'CRLF') {\n throw pslError(\n 'PSL.FORMAT_OPTION_INVALID',\n `Invalid format options: newline must be 'LF' or 'CRLF', got ${String(newline)}`,\n { meta: { option: 'newline', received: String(newline) } },\n );\n }\n return {\n indentUnit: indent === 'tab' ? '\\t' : ' '.repeat(indent),\n newline: newline === 'CRLF' ? '\\r\\n' : '\\n',\n };\n}\n","import { parse } from '../parse';\nimport { emitDocument } from './emit';\nimport { pslError } from './error';\nimport { type FormatOptions, resolveFormatOptions } from './options';\n\nexport function format(source: string, options?: FormatOptions): string {\n const resolved = resolveFormatOptions(options);\n const { document, diagnostics } = parse(source);\n if (diagnostics.length > 0) {\n const summary = diagnostics[0]?.message ?? 'unknown parse error';\n const more = diagnostics.length > 1 ? ` (and ${diagnostics.length - 1} more)` : '';\n throw pslError('PSL.PARSE_FAILED', `Cannot format PSL with parse errors: ${summary}${more}`, {\n meta: { diagnostics },\n });\n }\n return emitDocument(document, resolved.indentUnit, resolved.newline);\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -40,7 +40,12 @@ interface AttributeSpec<Out> {
|
|
|
40
40
|
readonly name: string;
|
|
41
41
|
readonly positional: readonly PositionalParam[];
|
|
42
42
|
readonly named: Readonly<Record<string, Param<unknown>>>;
|
|
43
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Cross-argument validation after all arguments parse. `attributeNode` is
|
|
45
|
+
* the attribute's own AST node so refines can span-anchor their
|
|
46
|
+
* diagnostics at the attribute rather than the enclosing model.
|
|
47
|
+
*/
|
|
48
|
+
readonly refine?: (parsed: Out, ctx: InterpretCtx, attributeNode: AstNode) => readonly PslDiagnostic$1[];
|
|
44
49
|
}
|
|
45
50
|
type OutOf<P> = P extends ArgType<infer T> ? T : never;
|
|
46
51
|
type NamedOut<N extends Record<string, Param<unknown>>> = Simplify<{ [K in keyof N as N[K] extends OptionalArgType<unknown> ? never : K]: OutOf<N[K]>; } & { [K in keyof N as N[K] extends OptionalArgType<unknown> ? K : never]?: OutOf<N[K]>; }>;
|
|
@@ -53,7 +58,7 @@ type InferAttr<S> = S extends AttributeSpec<infer Out> ? Out : never;
|
|
|
53
58
|
declare function bool(): ArgType<boolean>;
|
|
54
59
|
//#endregion
|
|
55
60
|
//#region src/attribute-spec/combinators/diagnostic.d.ts
|
|
56
|
-
declare function leafDiagnostic(ctx: InterpretCtx, node: AstNode, message: string): PslDiagnostic$1;
|
|
61
|
+
declare function leafDiagnostic(ctx: InterpretCtx, node: AstNode, message: string, code?: PslDiagnostic$1['code']): PslDiagnostic$1;
|
|
57
62
|
//#endregion
|
|
58
63
|
//#region src/attribute-spec/combinators/entity-ref.d.ts
|
|
59
64
|
declare function entityRef(): ArgType<string>;
|
|
@@ -110,7 +115,7 @@ declare function str(): ArgType<string>;
|
|
|
110
115
|
interface FieldAttributeConfig<Pos extends readonly PositionalParam[], Named extends Record<string, Param<unknown>>> {
|
|
111
116
|
readonly positional?: Pos;
|
|
112
117
|
readonly named?: Named;
|
|
113
|
-
readonly refine?: (parsed: AttributeOut<Pos, Named>, ctx: InterpretCtx) => readonly PslDiagnostic$1[];
|
|
118
|
+
readonly refine?: (parsed: AttributeOut<Pos, Named>, ctx: InterpretCtx, attributeNode: AstNode) => readonly PslDiagnostic$1[];
|
|
114
119
|
}
|
|
115
120
|
declare function fieldAttribute<const Pos extends readonly PositionalParam[] = readonly [], const Named extends Record<string, Param<unknown>> = Record<never, never>>(name: string, config: FieldAttributeConfig<Pos, Named>): AttributeSpec<AttributeOut<Pos, Named>>;
|
|
116
121
|
//#endregion
|
|
@@ -127,7 +132,7 @@ declare function interpretAttribute<Out>(attrNode: FieldAttributeAst | ModelAttr
|
|
|
127
132
|
interface ModelAttributeConfig<Pos extends readonly PositionalParam[], Named extends Record<string, Param<unknown>>> {
|
|
128
133
|
readonly positional?: Pos;
|
|
129
134
|
readonly named?: Named;
|
|
130
|
-
readonly refine?: (parsed: AttributeOut<Pos, Named>, ctx: InterpretCtx) => readonly PslDiagnostic$1[];
|
|
135
|
+
readonly refine?: (parsed: AttributeOut<Pos, Named>, ctx: InterpretCtx, attributeNode: AstNode) => readonly PslDiagnostic$1[];
|
|
131
136
|
}
|
|
132
137
|
declare function modelAttribute<const Pos extends readonly PositionalParam[] = readonly [], const Named extends Record<string, Param<unknown>> = Record<never, never>>(name: string, config: ModelAttributeConfig<Pos, Named>): AttributeSpec<AttributeOut<Pos, Named>>;
|
|
133
138
|
//#endregion
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/attribute-helpers.ts","../src/attribute-spec/types.ts","../src/attribute-spec/combinators/bool.ts","../src/attribute-spec/combinators/diagnostic.ts","../src/attribute-spec/combinators/entity-ref.ts","../src/attribute-spec/combinators/field-ref.ts","../src/attribute-spec/combinators/func-call.ts","../src/attribute-spec/combinators/identifier.ts","../src/attribute-spec/combinators/int.ts","../src/attribute-spec/combinators/list.ts","../src/attribute-spec/combinators/num.ts","../src/attribute-spec/combinators/one-of.ts","../src/attribute-spec/combinators/record.ts","../src/attribute-spec/combinators/str.ts","../src/attribute-spec/field-attribute.ts","../src/attribute-spec/interpret.ts","../src/attribute-spec/model-attribute.ts","../src/attribute-spec/optional.ts","../src/extension-block.ts"],"mappings":";;;;;;;;iBAEgB,sBAAsB,WAAW,gBAAc;iBAK/C,yBAAyB;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/attribute-helpers.ts","../src/attribute-spec/types.ts","../src/attribute-spec/combinators/bool.ts","../src/attribute-spec/combinators/diagnostic.ts","../src/attribute-spec/combinators/entity-ref.ts","../src/attribute-spec/combinators/field-ref.ts","../src/attribute-spec/combinators/func-call.ts","../src/attribute-spec/combinators/identifier.ts","../src/attribute-spec/combinators/int.ts","../src/attribute-spec/combinators/list.ts","../src/attribute-spec/combinators/num.ts","../src/attribute-spec/combinators/one-of.ts","../src/attribute-spec/combinators/record.ts","../src/attribute-spec/combinators/str.ts","../src/attribute-spec/field-attribute.ts","../src/attribute-spec/interpret.ts","../src/attribute-spec/model-attribute.ts","../src/attribute-spec/optional.ts","../src/extension-block.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -90,9 +90,9 @@ function offsetToPslPosition(offset, sourceFile) {
|
|
|
90
90
|
//#endregion
|
|
91
91
|
//#region src/attribute-spec/combinators/diagnostic.ts
|
|
92
92
|
const ATTRIBUTE_DIAGNOSTIC_CODE = "PSL_INVALID_ATTRIBUTE_SYNTAX";
|
|
93
|
-
function leafDiagnostic(ctx, node, message) {
|
|
93
|
+
function leafDiagnostic(ctx, node, message, code = ATTRIBUTE_DIAGNOSTIC_CODE) {
|
|
94
94
|
return {
|
|
95
|
-
code
|
|
95
|
+
code,
|
|
96
96
|
message,
|
|
97
97
|
sourceId: ctx.sourceId,
|
|
98
98
|
span: nodePslSpan(node.syntax, ctx.sourceFile)
|
|
@@ -211,7 +211,7 @@ function interpretAttribute(attrNode, spec, ctx) {
|
|
|
211
211
|
if (!bound.ok) return notOk(bound.failure);
|
|
212
212
|
const value = blindCast(bound.value);
|
|
213
213
|
if (spec.refine !== void 0) {
|
|
214
|
-
const refineDiagnostics = spec.refine(value, ctx);
|
|
214
|
+
const refineDiagnostics = spec.refine(value, ctx, attrNode);
|
|
215
215
|
if (refineDiagnostics.length > 0) return notOk(refineDiagnostics);
|
|
216
216
|
}
|
|
217
217
|
return ok(value);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/attribute-helpers.ts","../src/resolve.ts","../src/attribute-spec/combinators/diagnostic.ts","../src/attribute-spec/combinators/bool.ts","../src/attribute-spec/combinators/entity-ref.ts","../src/attribute-spec/combinators/field-ref.ts","../src/attribute-spec/interpret.ts","../src/attribute-spec/combinators/func-call.ts","../src/attribute-spec/combinators/identifier.ts","../src/attribute-spec/combinators/int.ts","../src/attribute-spec/combinators/list.ts","../src/attribute-spec/combinators/num.ts","../src/attribute-spec/combinators/one-of.ts","../src/attribute-spec/combinators/record.ts","../src/attribute-spec/combinators/str.ts","../src/attribute-spec/field-attribute.ts","../src/attribute-spec/model-attribute.ts","../src/attribute-spec/optional.ts","../src/extension-block.ts","../src/block-reconstruction.ts","../src/symbol-table.ts"],"sourcesContent":["import type { PslAttribute } from '@prisma-next/framework-components/psl-ast';\n\nexport function getPositionalArgument(attribute: PslAttribute, index = 0): string | undefined {\n const entries = attribute.args.filter((arg) => arg.kind === 'positional');\n return entries[index]?.value;\n}\n\nexport function parseQuotedStringLiteral(value: string): string | undefined {\n const trimmed = value.trim();\n const match = trimmed.match(/^(['\"])(.*)\\1$/);\n if (!match) return undefined;\n return match[2] ?? '';\n}\n","import type { PslSpan } from '@prisma-next/framework-components/psl-ast';\nimport type { Position, Range, SourceFile } from './source-file';\nimport type {\n AttributeArgListAst,\n FieldAttributeAst,\n ModelAttributeAst,\n} from './syntax/ast/attributes';\nimport type { ExpressionAst } from './syntax/ast/expressions';\nimport type { QualifiedNameAst } from './syntax/ast/qualified-name';\nimport type { TypeAnnotationAst } from './syntax/ast/type-annotation';\nimport { printSyntax } from './syntax/ast-helpers';\nimport type { SyntaxNode } from './syntax/red';\n\nexport interface ResolvedAttributeArg {\n readonly kind: 'positional' | 'named';\n readonly name?: string;\n readonly value: string;\n readonly expression?: ExpressionAst;\n readonly span: PslSpan;\n}\n\nexport interface ResolvedAttribute {\n readonly name: string;\n readonly args: readonly ResolvedAttributeArg[];\n readonly span: PslSpan;\n}\n\nexport interface ResolvedTypeConstructorCall {\n readonly path: readonly string[];\n readonly args: readonly ResolvedAttributeArg[];\n readonly span: PslSpan;\n}\n\nexport function readResolvedAttribute(\n attribute: FieldAttributeAst | ModelAttributeAst,\n sourceFile: SourceFile,\n): ResolvedAttribute {\n return {\n name: attributeName(attribute.name()),\n args: readResolvedArgList(attribute.argList(), sourceFile),\n span: nodePslSpan(attribute.syntax, sourceFile),\n };\n}\n\nexport function readResolvedAttributes(\n attributes: Iterable<FieldAttributeAst | ModelAttributeAst>,\n sourceFile: SourceFile,\n): readonly ResolvedAttribute[] {\n return Array.from(attributes, (attribute) => readResolvedAttribute(attribute, sourceFile));\n}\n\nexport function readResolvedConstructorCall(\n annotation: TypeAnnotationAst | undefined,\n sourceFile: SourceFile,\n): ResolvedTypeConstructorCall | undefined {\n const argList = annotation?.argList();\n if (annotation === undefined || argList === undefined) return undefined;\n return {\n path: annotation.name()?.path() ?? [],\n args: readResolvedArgList(argList, sourceFile),\n span: nodePslSpan(annotation.syntax, sourceFile),\n };\n}\n\nfunction readResolvedArgList(\n argList: AttributeArgListAst | undefined,\n sourceFile: SourceFile,\n): readonly ResolvedAttributeArg[] {\n if (argList === undefined) return [];\n const args: ResolvedAttributeArg[] = [];\n for (const arg of argList.args()) {\n const name = arg.name()?.name();\n const expression = arg.value();\n args.push({\n kind: name !== undefined ? 'named' : 'positional',\n ...(name !== undefined ? { name } : {}),\n value: renderExpression(expression),\n ...(expression !== undefined ? { expression } : {}),\n span: nodePslSpan(arg.syntax, sourceFile),\n });\n }\n return args;\n}\n\nfunction attributeName(name: QualifiedNameAst | undefined): string {\n return name?.path().join('.') ?? '';\n}\n\nfunction renderExpression(expression: ExpressionAst | undefined): string {\n if (expression === undefined) return '';\n return printSyntax(expression.syntax).trim();\n}\n\nexport function nodePslSpan(node: SyntaxNode, sourceFile: SourceFile): PslSpan {\n const start = node.offset;\n const end = start + node.green.textLength;\n return {\n start: offsetToPslPosition(start, sourceFile),\n end: offsetToPslPosition(end, sourceFile),\n };\n}\n\n/** Unsupported-top-level-block diagnostics are anchored to the keyword token. */\nexport function keywordPslSpan(node: SyntaxNode, keyword: string, sourceFile: SourceFile): PslSpan {\n const start = node.offset;\n const end = start + keyword.length;\n return {\n start: offsetToPslPosition(start, sourceFile),\n end: offsetToPslPosition(end, sourceFile),\n };\n}\n\nexport function rangeToPslSpan(range: Range, sourceFile: SourceFile): PslSpan {\n return {\n start: offsetToPslPosition(sourceFile.offsetAt(range.start), sourceFile),\n end: offsetToPslPosition(sourceFile.offsetAt(range.end), sourceFile),\n };\n}\n\nfunction offsetToPslPosition(offset: number, sourceFile: SourceFile): PslSpan['start'] {\n const position: Position = sourceFile.positionAt(offset);\n return { offset, line: position.line + 1, column: position.character + 1 };\n}\n","import type { PslDiagnostic, PslDiagnosticCode } from '@prisma-next/framework-components/psl-ast';\nimport { nodePslSpan } from '../../resolve';\nimport type { AstNode } from '../../syntax/ast-helpers';\nimport type { InterpretCtx } from '../types';\n\nexport const ATTRIBUTE_DIAGNOSTIC_CODE: PslDiagnosticCode = 'PSL_INVALID_ATTRIBUTE_SYNTAX';\n\nexport function leafDiagnostic(ctx: InterpretCtx, node: AstNode, message: string): PslDiagnostic {\n return {\n code: ATTRIBUTE_DIAGNOSTIC_CODE,\n message,\n sourceId: ctx.sourceId,\n span: nodePslSpan(node.syntax, ctx.sourceFile),\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { BooleanLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function bool(): ArgType<boolean> {\n return {\n kind: 'bool',\n label: 'boolean',\n parse: (arg, ctx): Result<boolean, readonly PslDiagnostic[]> => {\n if (arg instanceof BooleanLiteralExprAst) {\n const value = arg.value();\n if (value !== undefined) return ok(value);\n }\n return notOk([leafDiagnostic(ctx, arg, 'Expected a boolean literal')]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { IdentifierAst } from '../../syntax/ast/identifier';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\n// A bare model-name reference. Existence of a model with this name is resolved\n// downstream (e.g. `resolvePolymorphism`), not here.\nexport function entityRef(): ArgType<string> {\n return {\n kind: 'entityRef',\n label: 'model name',\n parse: (arg, ctx): Result<string, readonly PslDiagnostic[]> => {\n if (!(arg instanceof IdentifierAst)) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a model name')]);\n }\n const name = arg.name();\n if (name === undefined) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a model name')]);\n }\n return ok(name);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { IdentifierAst } from '../../syntax/ast/identifier';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport type FieldRefScope = 'self' | 'referenced';\n\nexport interface FieldRefArgType extends ArgType<string> {\n readonly scope: FieldRefScope;\n}\n\nexport function fieldRef(scope: FieldRefScope): FieldRefArgType {\n return {\n kind: 'fieldRef',\n label: 'field name',\n scope,\n parse: (arg, ctx): Result<string, readonly PslDiagnostic[]> => {\n if (!(arg instanceof IdentifierAst)) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a field name')]);\n }\n const name = arg.name();\n if (name === undefined) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a field name')]);\n }\n const model = scope === 'self' ? ctx.selfModel : ctx.resolveReferencedModel();\n // A referenced model in another space can't be resolved here (resolveReferencedModel returns undefined); skip the existence check — it runs where that model is known.\n if (model !== undefined && !Object.hasOwn(model.fields, name)) {\n return notOk([\n leafDiagnostic(ctx, arg, `Field \"${name}\" does not exist on model \"${model.name}\"`),\n ]);\n }\n return ok(name);\n },\n };\n}\n","import type { PslDiagnostic, PslSpan } from '@prisma-next/framework-components/psl-ast';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { nodePslSpan } from '../resolve';\nimport type { FieldAttributeAst, ModelAttributeAst } from '../syntax/ast/attributes';\nimport type { AttributeArgAst } from '../syntax/ast/expressions';\nimport { ATTRIBUTE_DIAGNOSTIC_CODE } from './combinators/diagnostic';\nimport type {\n ArgType,\n AttributeSpec,\n InterpretCtx,\n OptionalArgType,\n Param,\n PositionalParam,\n} from './types';\n\n// The positional/named argument-binding for an attribute or a function call. `name` labels the\n// callee in binding diagnostics (`Attribute \"<name>\" …`); `span` anchors the arity diagnostics\n// (too-many / missing) that have no per-argument node to point at.\nexport interface ArgBindingSpec {\n readonly name: string;\n readonly positional: readonly PositionalParam<unknown>[];\n readonly named: Readonly<Record<string, Param<unknown>>>;\n}\n\nexport function interpretArgs(\n args: Iterable<AttributeArgAst>,\n spec: ArgBindingSpec,\n ctx: InterpretCtx,\n span: PslSpan,\n): Result<Record<string, unknown>, readonly PslDiagnostic[]> {\n const diagnostics: PslDiagnostic[] = [];\n\n const output: Record<string, unknown> = {};\n const seen = new Set<string>();\n let positionalSlot = 0;\n let reportedExcess = false;\n\n for (const arg of args) {\n const name = arg.name()?.name();\n\n let key: string;\n let param: Param<unknown>;\n if (name === undefined) {\n const posParam = spec.positional[positionalSlot];\n if (posParam === undefined) {\n if (!reportedExcess) {\n diagnostics.push(\n diagnostic(\n `Attribute \"${spec.name}\" received too many positional arguments`,\n ctx,\n span,\n ),\n );\n reportedExcess = true;\n }\n continue;\n }\n positionalSlot += 1;\n key = posParam.key;\n param = posParam.type;\n } else {\n const namedParam = Object.hasOwn(spec.named, name) ? spec.named[name] : undefined;\n if (namedParam === undefined) {\n diagnostics.push(\n diagnostic(\n `Attribute \"${spec.name}\" received unknown argument \"${name}\"`,\n ctx,\n nodePslSpan(arg.syntax, ctx.sourceFile),\n ),\n );\n continue;\n }\n key = name;\n param = namedParam;\n }\n\n if (seen.has(key)) {\n diagnostics.push(\n diagnostic(\n `Attribute \"${spec.name}\" received duplicate argument \"${key}\"`,\n ctx,\n nodePslSpan(arg.syntax, ctx.sourceFile),\n ),\n );\n continue;\n }\n seen.add(key);\n const result = parseArgValue(arg, param, ctx, diagnostics);\n if (result.ok) output[key] = result.value;\n }\n\n const finalized = new Set<string>();\n const finalizeAbsentKey = (\n key: string,\n positionalParam: Param<unknown> | undefined,\n namedParam: Param<unknown> | undefined,\n ): void => {\n if (finalized.has(key) || seen.has(key)) return;\n finalized.add(key);\n const effective = namedParam ?? positionalParam;\n if (effective === undefined) return;\n if (isOptionalArgType(effective)) {\n if (effective.hasDefault) output[key] = effective.defaultValue;\n return;\n }\n diagnostics.push(\n diagnostic(`Attribute \"${spec.name}\" is missing required argument \"${key}\"`, ctx, span),\n );\n };\n\n for (const param of spec.positional) {\n const namedParam = Object.hasOwn(spec.named, param.key) ? spec.named[param.key] : undefined;\n finalizeAbsentKey(param.key, param.type, namedParam);\n }\n for (const key of Object.keys(spec.named)) {\n finalizeAbsentKey(key, undefined, spec.named[key]);\n }\n\n if (diagnostics.length > 0) {\n return notOk<readonly PslDiagnostic[]>(diagnostics);\n }\n return ok(output);\n}\n\nexport function interpretAttribute<Out>(\n attrNode: FieldAttributeAst | ModelAttributeAst,\n spec: AttributeSpec<Out>,\n ctx: InterpretCtx,\n): Result<Out, readonly PslDiagnostic[]> {\n const attributeSpan = nodePslSpan(attrNode.syntax, ctx.sourceFile);\n const bound = interpretArgs(attrNode.argList()?.args() ?? [], spec, ctx, attributeSpan);\n if (!bound.ok) return notOk<readonly PslDiagnostic[]>(bound.failure);\n\n const value = blindCast<\n Out,\n 'The engine builds the output object structurally from the spec; TypeScript cannot relate the dynamically-keyed record to the spec-inferred output type.'\n >(bound.value);\n if (spec.refine !== undefined) {\n const refineDiagnostics = spec.refine(value, ctx);\n if (refineDiagnostics.length > 0) {\n return notOk<readonly PslDiagnostic[]>(refineDiagnostics);\n }\n }\n return ok(value);\n}\n\nfunction parseArgValue(\n arg: AttributeArgAst,\n argType: ArgType<unknown>,\n ctx: InterpretCtx,\n diagnostics: PslDiagnostic[],\n): Result<unknown, readonly PslDiagnostic[]> {\n const value = arg.value();\n if (value === undefined) {\n const missing = diagnostic(\n 'Attribute argument is missing a value',\n ctx,\n nodePslSpan(arg.syntax, ctx.sourceFile),\n );\n diagnostics.push(missing);\n return notOk<readonly PslDiagnostic[]>([missing]);\n }\n const result = argType.parse(value, ctx);\n if (!result.ok) {\n for (const failure of result.failure) diagnostics.push(failure);\n }\n return result;\n}\n\nfunction isOptionalArgType(param: Param<unknown>): param is OptionalArgType<unknown> {\n return 'optional' in param && param.optional === true;\n}\n\nfunction diagnostic(message: string, ctx: InterpretCtx, span: PslSpan): PslDiagnostic {\n return { code: ATTRIBUTE_DIAGNOSTIC_CODE, message, sourceId: ctx.sourceId, span };\n}\n","import type { PslDiagnostic, PslSpan } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { nodePslSpan } from '../../resolve';\nimport type { ExpressionAst } from '../../syntax/ast/expressions';\nimport { FunctionCallAst } from '../../syntax/ast/expressions';\nimport { interpretArgs } from '../interpret';\nimport type { ArgType, InterpretCtx, Param, PositionalParam } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\n// The argument signature of a pinned function call — the same positional/named shape an attribute\n// spec uses. Omitted groups default to empty, so a nullary call needs neither key.\nexport interface FuncCallSig {\n readonly positional?: readonly PositionalParam<unknown>[];\n readonly named?: Readonly<Record<string, Param<unknown>>>;\n}\n\nexport interface TypedFuncCall {\n readonly fn: string;\n readonly span: PslSpan;\n readonly args: Readonly<Record<string, unknown>>;\n}\n\n// A name-pinned function-call argument — `funcCall('now', {})` matches `now()`, parsing the call's\n// arguments through `sig`.\nexport function funcCall(name: string, sig: FuncCallSig): ArgType<TypedFuncCall> {\n return {\n kind: 'funcCall',\n label: 'function call',\n parse: (arg, ctx): Result<TypedFuncCall, readonly PslDiagnostic[]> => {\n const guard = matchCallee(arg, name, ctx);\n if (!guard.ok) return guard;\n const span = nodePslSpan(guard.value.syntax, ctx.sourceFile);\n const bound = interpretArgs(\n guard.value.args(),\n { name, positional: sig.positional ?? [], named: sig.named ?? {} },\n ctx,\n span,\n );\n if (!bound.ok) return notOk<readonly PslDiagnostic[]>(bound.failure);\n return ok({ fn: name, span, args: bound.value });\n },\n };\n}\n\nfunction matchCallee(\n arg: ExpressionAst,\n name: string,\n ctx: InterpretCtx,\n): Result<FunctionCallAst, readonly PslDiagnostic[]> {\n if (!(arg instanceof FunctionCallAst)) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a function call')]);\n }\n const qname = arg.name();\n if (qname === undefined || qname.dot() !== undefined || qname.colon() !== undefined) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a function call')]);\n }\n const calleeName = qname.identifier()?.token()?.text;\n if (calleeName === undefined) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a function call')]);\n }\n if (calleeName !== name) {\n return notOk([leafDiagnostic(ctx, arg, `Expected ${name}()`)]);\n }\n return ok(arg);\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { IdentifierAst } from '../../syntax/ast/identifier';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function identifier<const N extends string>(name: N): ArgType<N> {\n return {\n kind: 'identifier',\n label: name,\n parse: (arg, ctx): Result<N, readonly PslDiagnostic[]> => {\n if (arg instanceof IdentifierAst && arg.name() === name) return ok(name);\n return notOk([leafDiagnostic(ctx, arg, `Expected ${name}`)]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { NumberLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\n// An integer literal reduced to its numeric value. Passing `min`/`max` additionally rejects\n// out-of-range integers with a distinct range message, leaving the integer-only check intact.\nexport function int(opts?: { min?: number; max?: number }): ArgType<number> {\n const min = opts?.min;\n const max = opts?.max;\n return {\n kind: 'int',\n label: 'integer',\n parse: (arg, ctx): Result<number, readonly PslDiagnostic[]> => {\n if (arg instanceof NumberLiteralExprAst) {\n const value = arg.value();\n if (value !== undefined && Number.isInteger(value)) {\n if ((min === undefined || value >= min) && (max === undefined || value <= max)) {\n return ok(value);\n }\n return notOk([leafDiagnostic(ctx, arg, rangeMessage(min, max))]);\n }\n }\n return notOk([leafDiagnostic(ctx, arg, 'Expected an integer literal')]);\n },\n };\n}\n\nfunction rangeMessage(min: number | undefined, max: number | undefined): string {\n if (min !== undefined && max !== undefined)\n return `Expected an integer between ${min} and ${max}`;\n if (min !== undefined) return `Expected an integer greater than or equal to ${min}`;\n return `Expected an integer less than or equal to ${max}`;\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { ArrayLiteralAst, type ExpressionAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport interface ListOptions {\n readonly nonEmpty?: boolean;\n readonly unique?: boolean;\n}\n\nexport function list<T>(of: ArgType<T>, opts?: ListOptions): ArgType<T[]> {\n return {\n kind: 'list',\n label: `${of.label}[]`,\n parse: (arg, ctx): Result<T[], readonly PslDiagnostic[]> => {\n if (!(arg instanceof ArrayLiteralAst)) {\n return notOk([leafDiagnostic(ctx, arg, `Expected a list of ${of.label}`)]);\n }\n const diagnostics: PslDiagnostic[] = [];\n const parsed: { node: ExpressionAst; value: T }[] = [];\n let count = 0;\n for (const element of arg.elements()) {\n count += 1;\n const result = of.parse(element, ctx);\n if (result.ok) parsed.push({ node: element, value: result.value });\n else diagnostics.push(...result.failure);\n }\n if (opts?.nonEmpty === true && count === 0) {\n diagnostics.push(leafDiagnostic(ctx, arg, 'Expected a non-empty list'));\n }\n if (opts?.unique === true) {\n const seen = new Set<T>();\n for (const { node, value } of parsed) {\n if (seen.has(value)) diagnostics.push(leafDiagnostic(ctx, node, 'Duplicate list entry'));\n else seen.add(value);\n }\n }\n if (diagnostics.length > 0) return notOk(diagnostics);\n return ok(parsed.map((entry) => entry.value));\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { NumberLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\n// A general number literal — any number, including floats — reduced to its numeric value.\n// Passing `value` pins the combinator to that single literal (`num(4)` matches only `4`),\n// mirroring how `identifier(name)` pins a bare identifier. Use `int()` when only integer\n// literals are allowed.\nexport function num(): ArgType<number>;\nexport function num(value: number): ArgType<number>;\nexport function num(value?: number): ArgType<number> {\n return {\n kind: 'num',\n label: value === undefined ? 'number' : String(value),\n parse: (arg, ctx): Result<number, readonly PslDiagnostic[]> => {\n if (arg instanceof NumberLiteralExprAst) {\n const parsed = arg.value();\n if (parsed !== undefined && (value === undefined || parsed === value)) return ok(parsed);\n }\n const message = value === undefined ? 'Expected a number literal' : `Expected ${value}`;\n return notOk([leafDiagnostic(ctx, arg, message)]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport type { ArgType, OutOf } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function oneOf<Alts extends readonly [ArgType<unknown>, ...ArgType<unknown>[]]>(\n ...alts: Alts\n): ArgType<OutOf<Alts[number]>> {\n const label = alts.map((alt) => alt.label).join(' | ');\n return {\n kind: 'oneOf',\n label,\n parse: (arg, ctx): Result<OutOf<Alts[number]>, readonly PslDiagnostic[]> => {\n for (const alt of alts) {\n const result = alt.parse(arg, ctx);\n if (result.ok) {\n return ok(\n blindCast<\n OutOf<Alts[number]>,\n 'The matched value comes from an alternative whose output type is a member of the union, but iterating the tuple widens each element to ArgType<unknown>, erasing that relationship.'\n >(result.value),\n );\n }\n }\n return notOk([leafDiagnostic(ctx, arg, `Expected one of: ${label}`)]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { ObjectLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function record<T>(of: ArgType<T>): ArgType<Record<string, T>> {\n return {\n kind: 'record',\n label: `{ [key]: ${of.label} }`,\n parse: (arg, ctx): Result<Record<string, T>, readonly PslDiagnostic[]> => {\n if (!(arg instanceof ObjectLiteralExprAst)) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected an object literal')]);\n }\n const diagnostics: PslDiagnostic[] = [];\n const result: Record<string, T> = {};\n for (const field of arg.fields()) {\n const key = field.keyName();\n if (key === undefined) {\n diagnostics.push(leafDiagnostic(ctx, field, 'Expected a key'));\n continue;\n }\n const value = field.value();\n if (value === undefined) {\n diagnostics.push(leafDiagnostic(ctx, field, `Expected a value for key \"${key}\"`));\n continue;\n }\n const parsed = of.parse(value, ctx);\n if (!parsed.ok) {\n diagnostics.push(...parsed.failure);\n continue;\n }\n if (Object.hasOwn(result, key)) {\n diagnostics.push(leafDiagnostic(ctx, field, `Duplicate key \"${key}\"`));\n continue;\n }\n result[key] = parsed.value;\n }\n if (diagnostics.length > 0) return notOk(diagnostics);\n return ok(result);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { StringLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function str(): ArgType<string> {\n return {\n kind: 'str',\n label: 'string',\n parse: (arg, ctx): Result<string, readonly PslDiagnostic[]> => {\n if (arg instanceof StringLiteralExprAst) {\n const value = arg.value();\n if (value !== undefined) return ok(value);\n }\n return notOk([leafDiagnostic(ctx, arg, 'Expected a string literal')]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport type { AttributeOut, AttributeSpec, InterpretCtx, Param, PositionalParam } from './types';\n\ninterface FieldAttributeConfig<\n Pos extends readonly PositionalParam[],\n Named extends Record<string, Param<unknown>>,\n> {\n readonly positional?: Pos;\n readonly named?: Named;\n readonly refine?: (\n parsed: AttributeOut<Pos, Named>,\n ctx: InterpretCtx,\n ) => readonly PslDiagnostic[];\n}\n\nexport function fieldAttribute<\n const Pos extends readonly PositionalParam[] = readonly [],\n const Named extends Record<string, Param<unknown>> = Record<never, never>,\n>(name: string, config: FieldAttributeConfig<Pos, Named>): AttributeSpec<AttributeOut<Pos, Named>> {\n return {\n level: 'field',\n name,\n positional: config.positional ?? [],\n named: config.named ?? {},\n ...(config.refine !== undefined ? { refine: config.refine } : {}),\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport type { AttributeOut, AttributeSpec, InterpretCtx, Param, PositionalParam } from './types';\n\ninterface ModelAttributeConfig<\n Pos extends readonly PositionalParam[],\n Named extends Record<string, Param<unknown>>,\n> {\n readonly positional?: Pos;\n readonly named?: Named;\n readonly refine?: (\n parsed: AttributeOut<Pos, Named>,\n ctx: InterpretCtx,\n ) => readonly PslDiagnostic[];\n}\n\nexport function modelAttribute<\n const Pos extends readonly PositionalParam[] = readonly [],\n const Named extends Record<string, Param<unknown>> = Record<never, never>,\n>(name: string, config: ModelAttributeConfig<Pos, Named>): AttributeSpec<AttributeOut<Pos, Named>> {\n return {\n level: 'model',\n name,\n positional: config.positional ?? [],\n named: config.named ?? {},\n ...(config.refine !== undefined ? { refine: config.refine } : {}),\n };\n}\n","import type { ArgType, OptionalArgType } from './types';\n\nexport function optional<T>(type: ArgType<T>, ...rest: [defaultValue: T] | []): OptionalArgType<T> {\n if (rest.length === 0) {\n return { ...type, optional: true, hasDefault: false };\n }\n return { ...type, optional: true, hasDefault: true, defaultValue: rest[0] };\n}\n","import {\n type AuthoringPslBlockDescriptor,\n type AuthoringPslBlockDescriptorNamespace,\n isAuthoringPslBlockDescriptor,\n} from '@prisma-next/framework-components/authoring';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport {\n makePslNamespace,\n makePslNamespaceEntries,\n type PslDiagnostic,\n type PslModel,\n type PslSpan,\n UNSPECIFIED_PSL_NAMESPACE_ID,\n validateExtensionBlock,\n} from '@prisma-next/framework-components/psl-ast';\nimport type { SourceFile } from './source-file';\nimport type { BlockSymbol, ModelSymbol, SymbolTable } from './symbol-table';\n\nexport function findBlockDescriptor(\n descriptors: AuthoringPslBlockDescriptorNamespace | undefined,\n keyword: string,\n): AuthoringPslBlockDescriptor | undefined {\n if (descriptors === undefined) return undefined;\n for (const value of Object.values(descriptors)) {\n if (value === undefined) continue;\n if (isAuthoringPslBlockDescriptor(value)) {\n if (value.keyword === keyword) return value;\n continue;\n }\n const nested = findBlockDescriptor(value, keyword);\n if (nested !== undefined) return nested;\n }\n return undefined;\n}\n\nexport function validateExtensionBlockFromSymbol(input: {\n readonly block: BlockSymbol;\n readonly descriptor: AuthoringPslBlockDescriptor;\n readonly symbolTable: SymbolTable;\n readonly sourceFile: SourceFile;\n readonly sourceId: string;\n readonly codecLookup: CodecLookup;\n}): readonly PslDiagnostic[] {\n const refCtx = buildRefResolutionContext(input.symbolTable, input.block);\n return validateExtensionBlock(\n input.block.block,\n input.descriptor,\n input.sourceId,\n input.codecLookup,\n refCtx,\n );\n}\n\nconst ZERO_SPAN: PslSpan = {\n start: { offset: 0, line: 1, column: 1 },\n end: { offset: 0, line: 1, column: 1 },\n};\n\nfunction buildRefResolutionContext(\n symbolTable: SymbolTable,\n block: BlockSymbol,\n): {\n ownerNamespace: ReturnType<typeof makePslNamespace>;\n allNamespaces: readonly ReturnType<typeof makePslNamespace>[];\n} {\n const unspecifiedNamespace = makeNamespace(\n UNSPECIFIED_PSL_NAMESPACE_ID,\n Object.values(symbolTable.topLevel.models),\n );\n const namedNamespaces = Object.values(symbolTable.topLevel.namespaces).map((namespace) =>\n makeNamespace(namespace.name, Object.values(namespace.models)),\n );\n const allNamespaces = [unspecifiedNamespace, ...namedNamespaces];\n const ownerNamespaceName = findOwnerNamespaceName(symbolTable, block);\n const ownerNamespace =\n allNamespaces.find((namespace) => namespace.name === ownerNamespaceName) ??\n unspecifiedNamespace;\n return { ownerNamespace, allNamespaces };\n}\n\nfunction makeNamespace(\n name: string,\n models: readonly ModelSymbol[],\n): ReturnType<typeof makePslNamespace> {\n const modelStubs: PslModel[] = models.map((model) => ({\n kind: 'model',\n name: model.name,\n fields: [],\n attributes: [],\n span: ZERO_SPAN,\n }));\n return makePslNamespace({\n kind: 'namespace',\n name,\n entries: makePslNamespaceEntries(modelStubs, [], []),\n span: ZERO_SPAN,\n });\n}\n\nfunction findOwnerNamespaceName(symbolTable: SymbolTable, block: BlockSymbol): string {\n for (const namespace of Object.values(symbolTable.topLevel.namespaces)) {\n if (Object.values(namespace.blocks).some((candidate) => candidate === block)) {\n return namespace.name;\n }\n }\n return UNSPECIFIED_PSL_NAMESPACE_ID;\n}\n","import type { AuthoringPslBlockDescriptor } from '@prisma-next/framework-components/authoring';\nimport type {\n PslBlockParam,\n PslExtensionBlock,\n PslExtensionBlockAttribute,\n PslExtensionBlockParamValue,\n PslSpan,\n} from '@prisma-next/framework-components/psl-ast';\nimport type { ParseDiagnostic } from './parse';\nimport { nodePslSpan } from './resolve';\nimport type { SourceFile } from './source-file';\nimport type { GenericBlockDeclarationAst, KeyValuePairAst } from './syntax/ast/declarations';\nimport { ArrayLiteralAst, type ExpressionAst } from './syntax/ast/expressions';\nimport { printSyntax } from './syntax/ast-helpers';\n\n/**\n * Descriptor-free and unknown parameters become `value` stubs so validation can\n * report them via key-set comparison. Duplicate member names are first-wins.\n */\nexport function reconstructExtensionBlock(\n node: GenericBlockDeclarationAst,\n descriptor: AuthoringPslBlockDescriptor | undefined,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): PslExtensionBlock {\n const keyword = node.keyword()?.text ?? '';\n const blockName = node.name()?.name() ?? '';\n\n const blockAttributes: PslExtensionBlockAttribute[] = [];\n for (const attribute of node.attributes()) {\n const name = attribute.name()?.path().join('.') ?? '';\n const args = Array.from(attribute.argList()?.args() ?? [], (arg) => {\n const value = arg.value();\n return {\n kind: 'positional' as const,\n value: value === undefined ? '' : printSyntax(value.syntax).trim(),\n span: nodePslSpan(arg.syntax, sourceFile),\n };\n });\n blockAttributes.push({\n name,\n args,\n span: nodePslSpan(attribute.syntax, sourceFile),\n });\n }\n\n const parameters: Record<string, PslExtensionBlockParamValue> = {};\n for (const entry of node.entries()) {\n const key = entry.key()?.name();\n if (key === undefined) continue;\n const span = nodePslSpan(entry.syntax, sourceFile);\n if (Object.hasOwn(parameters, key)) {\n diagnostics.push({\n code: 'PSL_EXTENSION_DUPLICATE_PARAMETER',\n message: `Duplicate parameter \"${key}\" in \"${keyword}\" block \"${blockName}\"; first occurrence wins`,\n range: {\n start: sourceFile.positionAt(entry.syntax.offset),\n end: sourceFile.positionAt(entry.syntax.offset + entry.syntax.green.textLength),\n },\n });\n continue;\n }\n parameters[key] = reconstructParamValue(\n entry,\n descriptor?.parameters[key],\n span,\n sourceFile,\n diagnostics,\n );\n }\n\n return {\n kind: descriptor?.discriminator ?? keyword,\n keyword,\n name: blockName,\n parameters,\n blockAttributes,\n span: nodePslSpan(node.syntax, sourceFile),\n };\n}\n\nfunction reconstructParamValue(\n entry: KeyValuePairAst,\n param: PslBlockParam | undefined,\n span: PslSpan,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): PslExtensionBlockParamValue {\n const value = entry.value();\n if (value === undefined) {\n return { kind: 'bare', span };\n }\n return reconstructFromExpression(value, param, span, sourceFile, diagnostics);\n}\n\nfunction reconstructFromExpression(\n value: ExpressionAst,\n param: PslBlockParam | undefined,\n span: PslSpan,\n sourceFile: SourceFile,\n diagnostics?: ParseDiagnostic[],\n): PslExtensionBlockParamValue {\n const raw = printSyntax(value.syntax).trim();\n if (param?.kind === 'list') {\n const array = ArrayLiteralAst.cast(value.syntax);\n if (!array) {\n diagnostics?.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `List parameter expects an array literal, got ${raw}`,\n range: {\n start: sourceFile.positionAt(value.syntax.offset),\n end: sourceFile.positionAt(value.syntax.offset + value.syntax.green.textLength),\n },\n });\n return { kind: 'value', raw, span };\n }\n\n const items: PslExtensionBlockParamValue[] = [];\n for (const element of array.elements()) {\n items.push(\n reconstructFromExpression(\n element,\n param.of,\n nodePslSpan(element.syntax, sourceFile),\n sourceFile,\n diagnostics,\n ),\n );\n }\n return { kind: 'list', items, span };\n }\n switch (param?.kind) {\n case 'ref':\n return { kind: 'ref', identifier: raw, span };\n case 'option':\n return { kind: 'option', token: raw, span };\n default:\n return { kind: 'value', raw, span };\n }\n}\n","import type { AuthoringPslBlockDescriptorNamespace } from '@prisma-next/framework-components/authoring';\nimport type { PslExtensionBlock, PslSpan } from '@prisma-next/framework-components/psl-ast';\nimport { reconstructExtensionBlock } from './block-reconstruction';\nimport { findBlockDescriptor } from './extension-block';\nimport type { ParseDiagnostic } from './parse';\nimport {\n nodePslSpan,\n type ResolvedAttribute,\n type ResolvedTypeConstructorCall,\n readResolvedAttributes,\n readResolvedConstructorCall,\n} from './resolve';\nimport type { Range, SourceFile } from './source-file';\nimport {\n CompositeTypeDeclarationAst,\n type DocumentAst,\n type FieldDeclarationAst,\n GenericBlockDeclarationAst,\n ModelDeclarationAst,\n type NamedTypeDeclarationAst,\n NamespaceDeclarationAst,\n TypesBlockAst,\n} from './syntax/ast/declarations';\nimport type { IdentifierAst } from './syntax/ast/identifier';\nimport type { SyntaxNode } from './syntax/red';\n\nexport type {\n ResolvedAttribute,\n ResolvedAttributeArg,\n ResolvedTypeConstructorCall,\n} from './resolve';\n\nexport interface SymbolTable {\n readonly topLevel: TopLevelScope;\n}\n\nexport interface TopLevelScope {\n readonly namespaces: Record<string, NamespaceSymbol>;\n readonly namedTypes: Record<string, NamedTypeSymbol>;\n readonly blocks: Record<string, BlockSymbol>;\n readonly models: Record<string, ModelSymbol>;\n readonly compositeTypes: Record<string, CompositeTypeSymbol>;\n}\n\nexport interface NamespaceSymbol {\n readonly kind: 'namespace';\n readonly name: string;\n readonly node: NamespaceDeclarationAst;\n readonly span: PslSpan;\n readonly models: Record<string, ModelSymbol>;\n readonly compositeTypes: Record<string, CompositeTypeSymbol>;\n readonly blocks: Record<string, BlockSymbol>;\n}\n\nexport interface ModelSymbol {\n readonly kind: 'model';\n readonly name: string;\n readonly node: ModelDeclarationAst;\n readonly span: PslSpan;\n readonly fields: Record<string, FieldSymbol>;\n readonly attributes: readonly ResolvedAttribute[];\n}\n\nexport interface CompositeTypeSymbol {\n readonly kind: 'compositeType';\n readonly name: string;\n readonly node: CompositeTypeDeclarationAst;\n readonly span: PslSpan;\n readonly fields: Record<string, FieldSymbol>;\n readonly attributes: readonly ResolvedAttribute[];\n}\n\nexport interface BlockSymbol {\n readonly kind: 'block';\n readonly name: string;\n readonly keyword: string;\n readonly node: GenericBlockDeclarationAst;\n readonly span: PslSpan;\n /** Resolved once so consumers do not independently classify block parameters. */\n readonly block: PslExtensionBlock;\n}\n\nexport interface ResolvedNamedTypeBinding {\n readonly baseType?: string;\n readonly typeConstructor?: ResolvedTypeConstructorCall;\n readonly isConstructor: boolean;\n readonly attributes: readonly ResolvedAttribute[];\n}\n\n/**\n * A `types {}` binding, collected without classification: whether the binding\n * refines a target scalar is pronounced by the interpreter\n * (`resolveNamedTypeDeclarations`), not by the family-blind symbol table.\n */\nexport interface NamedTypeSymbol extends ResolvedNamedTypeBinding {\n readonly kind: 'namedType';\n readonly name: string;\n readonly node: NamedTypeDeclarationAst;\n readonly span: PslSpan;\n}\n\nexport interface FieldSymbol {\n readonly kind: 'field';\n readonly name: string;\n readonly node: FieldDeclarationAst;\n readonly span: PslSpan;\n readonly typeName: string;\n readonly typeNamespaceId?: string;\n readonly typeContractSpaceId?: string;\n readonly optional: boolean;\n readonly list: boolean;\n readonly typeConstructor?: ResolvedTypeConstructorCall;\n readonly attributes: readonly ResolvedAttribute[];\n /** Prevents cascading unsupported-type diagnostics after invalid qualification. */\n readonly malformedType?: boolean;\n}\n\nexport interface BuildSymbolTableOptions {\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n readonly pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace;\n}\n\nexport interface SymbolTableResult {\n readonly table: SymbolTable;\n readonly diagnostics: readonly ParseDiagnostic[];\n}\n\n/**\n * Owns duplicate-declaration detection for all PSL scopes; downstream consumers\n * should consume first-wins symbols rather than re-emitting duplicate diagnostics.\n */\nexport function buildSymbolTable(options: BuildSymbolTableOptions): SymbolTableResult {\n const { document, sourceFile, pslBlockDescriptors } = options;\n const diagnostics: ParseDiagnostic[] = [];\n\n const namespaces: Record<string, NamespaceSymbol> = {};\n const namedTypes: Record<string, NamedTypeSymbol> = {};\n const blocks: Record<string, BlockSymbol> = {};\n const models: Record<string, ModelSymbol> = {};\n const compositeTypes: Record<string, CompositeTypeSymbol> = {};\n const topLevelNames = new Set<string>();\n\n const claim = (taken: Set<string>, name: IdentifierAst | undefined): string | undefined => {\n const text = name?.name();\n if (text === undefined) return undefined;\n if (taken.has(text)) {\n const range = nameRange(name, sourceFile);\n if (range) {\n diagnostics.push({\n code: 'PSL_DUPLICATE_DECLARATION',\n message: `Duplicate declaration of \"${text}\"`,\n range,\n });\n }\n return undefined;\n }\n taken.add(text);\n return text;\n };\n\n for (const declaration of document.declarations()) {\n if (declaration instanceof ModelDeclarationAst) {\n const name = claim(topLevelNames, declaration.name());\n if (name !== undefined) models[name] = buildModel(name, declaration, sourceFile, diagnostics);\n } else if (declaration instanceof CompositeTypeDeclarationAst) {\n const name = claim(topLevelNames, declaration.name());\n if (name !== undefined) {\n compositeTypes[name] = buildCompositeType(name, declaration, sourceFile, diagnostics);\n }\n } else if (declaration instanceof GenericBlockDeclarationAst) {\n const name = claim(topLevelNames, declaration.name());\n if (name !== undefined) {\n blocks[name] = buildBlock(name, declaration, sourceFile, pslBlockDescriptors, diagnostics);\n }\n } else if (declaration instanceof NamespaceDeclarationAst) {\n const name = claim(topLevelNames, declaration.name());\n if (name !== undefined) {\n namespaces[name] = buildNamespace(\n name,\n declaration,\n diagnostics,\n sourceFile,\n pslBlockDescriptors,\n );\n }\n } else if (declaration instanceof TypesBlockAst) {\n for (const binding of declaration.declarations()) {\n const name = claim(topLevelNames, binding.name());\n if (name === undefined) continue;\n const resolved = resolveNamedTypeBinding(binding, sourceFile);\n const span = nodePslSpan(binding.syntax, sourceFile);\n namedTypes[name] = { kind: 'namedType', name, node: binding, span, ...resolved };\n }\n }\n }\n\n const table: SymbolTable = {\n topLevel: { namespaces, namedTypes, blocks, models, compositeTypes },\n };\n return { table, diagnostics };\n}\n\nfunction buildModel(\n name: string,\n node: ModelDeclarationAst,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): ModelSymbol {\n return {\n kind: 'model',\n name,\n node,\n span: nodePslSpan(node.syntax, sourceFile),\n fields: buildFields(name, node.fields(), sourceFile, diagnostics),\n attributes: readResolvedAttributes(node.attributes(), sourceFile),\n };\n}\n\nfunction buildCompositeType(\n name: string,\n node: CompositeTypeDeclarationAst,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): CompositeTypeSymbol {\n return {\n kind: 'compositeType',\n name,\n node,\n span: nodePslSpan(node.syntax, sourceFile),\n fields: buildFields(name, node.fields(), sourceFile, diagnostics),\n attributes: readResolvedAttributes(node.attributes(), sourceFile),\n };\n}\n\nfunction buildBlock(\n name: string,\n node: GenericBlockDeclarationAst,\n sourceFile: SourceFile,\n pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace,\n diagnostics: ParseDiagnostic[],\n): BlockSymbol {\n const keyword = node.keyword()?.text ?? '';\n const descriptor = findBlockDescriptor(pslBlockDescriptors, keyword);\n return {\n kind: 'block',\n name,\n keyword,\n node,\n span: nodePslSpan(node.syntax, sourceFile),\n block: reconstructExtensionBlock(node, descriptor, sourceFile, diagnostics),\n };\n}\n\nfunction buildNamespace(\n name: string,\n node: NamespaceDeclarationAst,\n diagnostics: ParseDiagnostic[],\n sourceFile: SourceFile,\n pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace,\n): NamespaceSymbol {\n const models: Record<string, ModelSymbol> = {};\n const compositeTypes: Record<string, CompositeTypeSymbol> = {};\n const blocks: Record<string, BlockSymbol> = {};\n const taken = new Set<string>();\n\n for (const member of node.declarations()) {\n const memberName = member.name()?.name();\n if (memberName === undefined) continue;\n if (taken.has(memberName)) {\n const range = nameRange(member.name(), sourceFile);\n if (range) {\n diagnostics.push({\n code: 'PSL_DUPLICATE_DECLARATION',\n message: `Duplicate declaration of \"${memberName}\"`,\n range,\n });\n }\n continue;\n }\n taken.add(memberName);\n if (member instanceof ModelDeclarationAst) {\n models[memberName] = buildModel(memberName, member, sourceFile, diagnostics);\n } else if (member instanceof CompositeTypeDeclarationAst) {\n compositeTypes[memberName] = buildCompositeType(memberName, member, sourceFile, diagnostics);\n } else if (member instanceof GenericBlockDeclarationAst) {\n blocks[memberName] = buildBlock(\n memberName,\n member,\n sourceFile,\n pslBlockDescriptors,\n diagnostics,\n );\n }\n }\n\n return {\n kind: 'namespace',\n name,\n node,\n span: nodePslSpan(node.syntax, sourceFile),\n models,\n compositeTypes,\n blocks,\n };\n}\n\nfunction buildFields(\n ownerName: string,\n fields: Iterable<FieldDeclarationAst>,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): Record<string, FieldSymbol> {\n const result: Record<string, FieldSymbol> = {};\n for (const field of fields) {\n const nameNode = field.name();\n const name = nameNode?.name();\n if (name === undefined) continue;\n if (Object.hasOwn(result, name)) {\n const range = nameRange(nameNode, sourceFile);\n if (range) {\n diagnostics.push({\n code: 'PSL_DUPLICATE_DECLARATION',\n message: `Duplicate declaration of \"${name}\"`,\n range,\n });\n }\n continue;\n }\n result[name] = buildField(ownerName, name, field, sourceFile, diagnostics);\n }\n return result;\n}\n\nfunction buildField(\n ownerName: string,\n name: string,\n node: FieldDeclarationAst,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): FieldSymbol {\n const attributes = readResolvedAttributes(node.attributes(), sourceFile);\n const span = nodePslSpan(node.syntax, sourceFile);\n const annotation = node.typeAnnotation();\n const typeName = annotation?.name();\n\n if (typeName?.isOverQualified()) {\n const path = typeName.path();\n diagnostics.push({\n code: 'PSL_INVALID_QUALIFIED_TYPE',\n message: `Field \"${ownerName}.${name}\" has an invalid qualified type \"${path.join('.')}\"; use at most one namespace qualifier (e.g. \"ns.TypeName\")`,\n range: nodeRange(typeName.syntax, sourceFile),\n });\n return {\n kind: 'field',\n name,\n node,\n span,\n typeName: path[path.length - 1] ?? '',\n optional: false,\n list: false,\n malformedType: true,\n attributes,\n };\n }\n\n const typeConstructor = annotation?.isConstructor()\n ? readResolvedConstructorCall(annotation, sourceFile)\n : undefined;\n const typeNamespaceId = typeName?.namespace()?.name();\n const typeContractSpaceId = typeName?.space()?.name();\n\n return {\n kind: 'field',\n name,\n node,\n span,\n typeName: typeName?.identifier()?.name() ?? '',\n ...(typeNamespaceId !== undefined ? { typeNamespaceId } : {}),\n ...(typeContractSpaceId !== undefined ? { typeContractSpaceId } : {}),\n optional: annotation?.isOptional() ?? false,\n list: annotation?.isList() ?? false,\n ...(typeConstructor !== undefined ? { typeConstructor } : {}),\n attributes,\n };\n}\n\nfunction resolveNamedTypeBinding(\n node: NamedTypeDeclarationAst,\n sourceFile: SourceFile,\n): {\n baseType?: string;\n typeConstructor?: ResolvedTypeConstructorCall;\n isConstructor: boolean;\n attributes: readonly ResolvedAttribute[];\n} {\n const annotation = node.typeAnnotation();\n const isConstructor = annotation?.isConstructor() ?? false;\n const baseType = annotation?.name()?.identifier()?.name();\n const typeConstructor = readResolvedConstructorCall(annotation, sourceFile);\n return {\n isConstructor,\n ...(!isConstructor && baseType !== undefined ? { baseType } : {}),\n ...(typeConstructor !== undefined ? { typeConstructor } : {}),\n attributes: readResolvedAttributes(node.attributes(), sourceFile),\n };\n}\n\nfunction nameRange(name: IdentifierAst | undefined, sourceFile: SourceFile): Range | undefined {\n if (name === undefined) return undefined;\n for (const token of name.syntax.tokens()) {\n if (token.kind === 'Ident') {\n return {\n start: sourceFile.positionAt(token.offset),\n end: sourceFile.positionAt(token.offset + token.text.length),\n };\n }\n }\n return undefined;\n}\n\nfunction nodeRange(node: SyntaxNode, sourceFile: SourceFile): Range {\n const start = node.offset;\n const end = start + node.green.textLength;\n return {\n start: sourceFile.positionAt(start),\n end: sourceFile.positionAt(end),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/attribute-helpers.ts","../src/resolve.ts","../src/attribute-spec/combinators/diagnostic.ts","../src/attribute-spec/combinators/bool.ts","../src/attribute-spec/combinators/entity-ref.ts","../src/attribute-spec/combinators/field-ref.ts","../src/attribute-spec/interpret.ts","../src/attribute-spec/combinators/func-call.ts","../src/attribute-spec/combinators/identifier.ts","../src/attribute-spec/combinators/int.ts","../src/attribute-spec/combinators/list.ts","../src/attribute-spec/combinators/num.ts","../src/attribute-spec/combinators/one-of.ts","../src/attribute-spec/combinators/record.ts","../src/attribute-spec/combinators/str.ts","../src/attribute-spec/field-attribute.ts","../src/attribute-spec/model-attribute.ts","../src/attribute-spec/optional.ts","../src/extension-block.ts","../src/block-reconstruction.ts","../src/symbol-table.ts"],"sourcesContent":["import type { PslAttribute } from '@prisma-next/framework-components/psl-ast';\n\nexport function getPositionalArgument(attribute: PslAttribute, index = 0): string | undefined {\n const entries = attribute.args.filter((arg) => arg.kind === 'positional');\n return entries[index]?.value;\n}\n\nexport function parseQuotedStringLiteral(value: string): string | undefined {\n const trimmed = value.trim();\n const match = trimmed.match(/^(['\"])(.*)\\1$/);\n if (!match) return undefined;\n return match[2] ?? '';\n}\n","import type { PslSpan } from '@prisma-next/framework-components/psl-ast';\nimport type { Position, Range, SourceFile } from './source-file';\nimport type {\n AttributeArgListAst,\n FieldAttributeAst,\n ModelAttributeAst,\n} from './syntax/ast/attributes';\nimport type { ExpressionAst } from './syntax/ast/expressions';\nimport type { QualifiedNameAst } from './syntax/ast/qualified-name';\nimport type { TypeAnnotationAst } from './syntax/ast/type-annotation';\nimport { printSyntax } from './syntax/ast-helpers';\nimport type { SyntaxNode } from './syntax/red';\n\nexport interface ResolvedAttributeArg {\n readonly kind: 'positional' | 'named';\n readonly name?: string;\n readonly value: string;\n readonly expression?: ExpressionAst;\n readonly span: PslSpan;\n}\n\nexport interface ResolvedAttribute {\n readonly name: string;\n readonly args: readonly ResolvedAttributeArg[];\n readonly span: PslSpan;\n}\n\nexport interface ResolvedTypeConstructorCall {\n readonly path: readonly string[];\n readonly args: readonly ResolvedAttributeArg[];\n readonly span: PslSpan;\n}\n\nexport function readResolvedAttribute(\n attribute: FieldAttributeAst | ModelAttributeAst,\n sourceFile: SourceFile,\n): ResolvedAttribute {\n return {\n name: attributeName(attribute.name()),\n args: readResolvedArgList(attribute.argList(), sourceFile),\n span: nodePslSpan(attribute.syntax, sourceFile),\n };\n}\n\nexport function readResolvedAttributes(\n attributes: Iterable<FieldAttributeAst | ModelAttributeAst>,\n sourceFile: SourceFile,\n): readonly ResolvedAttribute[] {\n return Array.from(attributes, (attribute) => readResolvedAttribute(attribute, sourceFile));\n}\n\nexport function readResolvedConstructorCall(\n annotation: TypeAnnotationAst | undefined,\n sourceFile: SourceFile,\n): ResolvedTypeConstructorCall | undefined {\n const argList = annotation?.argList();\n if (annotation === undefined || argList === undefined) return undefined;\n return {\n path: annotation.name()?.path() ?? [],\n args: readResolvedArgList(argList, sourceFile),\n span: nodePslSpan(annotation.syntax, sourceFile),\n };\n}\n\nfunction readResolvedArgList(\n argList: AttributeArgListAst | undefined,\n sourceFile: SourceFile,\n): readonly ResolvedAttributeArg[] {\n if (argList === undefined) return [];\n const args: ResolvedAttributeArg[] = [];\n for (const arg of argList.args()) {\n const name = arg.name()?.name();\n const expression = arg.value();\n args.push({\n kind: name !== undefined ? 'named' : 'positional',\n ...(name !== undefined ? { name } : {}),\n value: renderExpression(expression),\n ...(expression !== undefined ? { expression } : {}),\n span: nodePslSpan(arg.syntax, sourceFile),\n });\n }\n return args;\n}\n\nfunction attributeName(name: QualifiedNameAst | undefined): string {\n return name?.path().join('.') ?? '';\n}\n\nfunction renderExpression(expression: ExpressionAst | undefined): string {\n if (expression === undefined) return '';\n return printSyntax(expression.syntax).trim();\n}\n\nexport function nodePslSpan(node: SyntaxNode, sourceFile: SourceFile): PslSpan {\n const start = node.offset;\n const end = start + node.green.textLength;\n return {\n start: offsetToPslPosition(start, sourceFile),\n end: offsetToPslPosition(end, sourceFile),\n };\n}\n\n/** Unsupported-top-level-block diagnostics are anchored to the keyword token. */\nexport function keywordPslSpan(node: SyntaxNode, keyword: string, sourceFile: SourceFile): PslSpan {\n const start = node.offset;\n const end = start + keyword.length;\n return {\n start: offsetToPslPosition(start, sourceFile),\n end: offsetToPslPosition(end, sourceFile),\n };\n}\n\nexport function rangeToPslSpan(range: Range, sourceFile: SourceFile): PslSpan {\n return {\n start: offsetToPslPosition(sourceFile.offsetAt(range.start), sourceFile),\n end: offsetToPslPosition(sourceFile.offsetAt(range.end), sourceFile),\n };\n}\n\nfunction offsetToPslPosition(offset: number, sourceFile: SourceFile): PslSpan['start'] {\n const position: Position = sourceFile.positionAt(offset);\n return { offset, line: position.line + 1, column: position.character + 1 };\n}\n","import type { PslDiagnostic, PslDiagnosticCode } from '@prisma-next/framework-components/psl-ast';\nimport { nodePslSpan } from '../../resolve';\nimport type { AstNode } from '../../syntax/ast-helpers';\nimport type { InterpretCtx } from '../types';\n\nexport const ATTRIBUTE_DIAGNOSTIC_CODE: PslDiagnosticCode = 'PSL_INVALID_ATTRIBUTE_SYNTAX';\n\nexport function leafDiagnostic(\n ctx: InterpretCtx,\n node: AstNode,\n message: string,\n code: PslDiagnostic['code'] = ATTRIBUTE_DIAGNOSTIC_CODE,\n): PslDiagnostic {\n return {\n code,\n message,\n sourceId: ctx.sourceId,\n span: nodePslSpan(node.syntax, ctx.sourceFile),\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { BooleanLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function bool(): ArgType<boolean> {\n return {\n kind: 'bool',\n label: 'boolean',\n parse: (arg, ctx): Result<boolean, readonly PslDiagnostic[]> => {\n if (arg instanceof BooleanLiteralExprAst) {\n const value = arg.value();\n if (value !== undefined) return ok(value);\n }\n return notOk([leafDiagnostic(ctx, arg, 'Expected a boolean literal')]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { IdentifierAst } from '../../syntax/ast/identifier';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\n// A bare model-name reference. Existence of a model with this name is resolved\n// downstream (e.g. `resolvePolymorphism`), not here.\nexport function entityRef(): ArgType<string> {\n return {\n kind: 'entityRef',\n label: 'model name',\n parse: (arg, ctx): Result<string, readonly PslDiagnostic[]> => {\n if (!(arg instanceof IdentifierAst)) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a model name')]);\n }\n const name = arg.name();\n if (name === undefined) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a model name')]);\n }\n return ok(name);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { IdentifierAst } from '../../syntax/ast/identifier';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport type FieldRefScope = 'self' | 'referenced';\n\nexport interface FieldRefArgType extends ArgType<string> {\n readonly scope: FieldRefScope;\n}\n\nexport function fieldRef(scope: FieldRefScope): FieldRefArgType {\n return {\n kind: 'fieldRef',\n label: 'field name',\n scope,\n parse: (arg, ctx): Result<string, readonly PslDiagnostic[]> => {\n if (!(arg instanceof IdentifierAst)) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a field name')]);\n }\n const name = arg.name();\n if (name === undefined) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a field name')]);\n }\n const model = scope === 'self' ? ctx.selfModel : ctx.resolveReferencedModel();\n // A referenced model in another space can't be resolved here (resolveReferencedModel returns undefined); skip the existence check — it runs where that model is known.\n if (model !== undefined && !Object.hasOwn(model.fields, name)) {\n return notOk([\n leafDiagnostic(ctx, arg, `Field \"${name}\" does not exist on model \"${model.name}\"`),\n ]);\n }\n return ok(name);\n },\n };\n}\n","import type { PslDiagnostic, PslSpan } from '@prisma-next/framework-components/psl-ast';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { nodePslSpan } from '../resolve';\nimport type { FieldAttributeAst, ModelAttributeAst } from '../syntax/ast/attributes';\nimport type { AttributeArgAst } from '../syntax/ast/expressions';\nimport { ATTRIBUTE_DIAGNOSTIC_CODE } from './combinators/diagnostic';\nimport type {\n ArgType,\n AttributeSpec,\n InterpretCtx,\n OptionalArgType,\n Param,\n PositionalParam,\n} from './types';\n\n// The positional/named argument-binding for an attribute or a function call. `name` labels the\n// callee in binding diagnostics (`Attribute \"<name>\" …`); `span` anchors the arity diagnostics\n// (too-many / missing) that have no per-argument node to point at.\nexport interface ArgBindingSpec {\n readonly name: string;\n readonly positional: readonly PositionalParam<unknown>[];\n readonly named: Readonly<Record<string, Param<unknown>>>;\n}\n\nexport function interpretArgs(\n args: Iterable<AttributeArgAst>,\n spec: ArgBindingSpec,\n ctx: InterpretCtx,\n span: PslSpan,\n): Result<Record<string, unknown>, readonly PslDiagnostic[]> {\n const diagnostics: PslDiagnostic[] = [];\n\n const output: Record<string, unknown> = {};\n const seen = new Set<string>();\n let positionalSlot = 0;\n let reportedExcess = false;\n\n for (const arg of args) {\n const name = arg.name()?.name();\n\n let key: string;\n let param: Param<unknown>;\n if (name === undefined) {\n const posParam = spec.positional[positionalSlot];\n if (posParam === undefined) {\n if (!reportedExcess) {\n diagnostics.push(\n diagnostic(\n `Attribute \"${spec.name}\" received too many positional arguments`,\n ctx,\n span,\n ),\n );\n reportedExcess = true;\n }\n continue;\n }\n positionalSlot += 1;\n key = posParam.key;\n param = posParam.type;\n } else {\n const namedParam = Object.hasOwn(spec.named, name) ? spec.named[name] : undefined;\n if (namedParam === undefined) {\n diagnostics.push(\n diagnostic(\n `Attribute \"${spec.name}\" received unknown argument \"${name}\"`,\n ctx,\n nodePslSpan(arg.syntax, ctx.sourceFile),\n ),\n );\n continue;\n }\n key = name;\n param = namedParam;\n }\n\n if (seen.has(key)) {\n diagnostics.push(\n diagnostic(\n `Attribute \"${spec.name}\" received duplicate argument \"${key}\"`,\n ctx,\n nodePslSpan(arg.syntax, ctx.sourceFile),\n ),\n );\n continue;\n }\n seen.add(key);\n const result = parseArgValue(arg, param, ctx, diagnostics);\n if (result.ok) output[key] = result.value;\n }\n\n const finalized = new Set<string>();\n const finalizeAbsentKey = (\n key: string,\n positionalParam: Param<unknown> | undefined,\n namedParam: Param<unknown> | undefined,\n ): void => {\n if (finalized.has(key) || seen.has(key)) return;\n finalized.add(key);\n const effective = namedParam ?? positionalParam;\n if (effective === undefined) return;\n if (isOptionalArgType(effective)) {\n if (effective.hasDefault) output[key] = effective.defaultValue;\n return;\n }\n diagnostics.push(\n diagnostic(`Attribute \"${spec.name}\" is missing required argument \"${key}\"`, ctx, span),\n );\n };\n\n for (const param of spec.positional) {\n const namedParam = Object.hasOwn(spec.named, param.key) ? spec.named[param.key] : undefined;\n finalizeAbsentKey(param.key, param.type, namedParam);\n }\n for (const key of Object.keys(spec.named)) {\n finalizeAbsentKey(key, undefined, spec.named[key]);\n }\n\n if (diagnostics.length > 0) {\n return notOk<readonly PslDiagnostic[]>(diagnostics);\n }\n return ok(output);\n}\n\nexport function interpretAttribute<Out>(\n attrNode: FieldAttributeAst | ModelAttributeAst,\n spec: AttributeSpec<Out>,\n ctx: InterpretCtx,\n): Result<Out, readonly PslDiagnostic[]> {\n const attributeSpan = nodePslSpan(attrNode.syntax, ctx.sourceFile);\n const bound = interpretArgs(attrNode.argList()?.args() ?? [], spec, ctx, attributeSpan);\n if (!bound.ok) return notOk<readonly PslDiagnostic[]>(bound.failure);\n\n const value = blindCast<\n Out,\n 'The engine builds the output object structurally from the spec; TypeScript cannot relate the dynamically-keyed record to the spec-inferred output type.'\n >(bound.value);\n if (spec.refine !== undefined) {\n const refineDiagnostics = spec.refine(value, ctx, attrNode);\n if (refineDiagnostics.length > 0) {\n return notOk<readonly PslDiagnostic[]>(refineDiagnostics);\n }\n }\n return ok(value);\n}\n\nfunction parseArgValue(\n arg: AttributeArgAst,\n argType: ArgType<unknown>,\n ctx: InterpretCtx,\n diagnostics: PslDiagnostic[],\n): Result<unknown, readonly PslDiagnostic[]> {\n const value = arg.value();\n if (value === undefined) {\n const missing = diagnostic(\n 'Attribute argument is missing a value',\n ctx,\n nodePslSpan(arg.syntax, ctx.sourceFile),\n );\n diagnostics.push(missing);\n return notOk<readonly PslDiagnostic[]>([missing]);\n }\n const result = argType.parse(value, ctx);\n if (!result.ok) {\n for (const failure of result.failure) diagnostics.push(failure);\n }\n return result;\n}\n\nfunction isOptionalArgType(param: Param<unknown>): param is OptionalArgType<unknown> {\n return 'optional' in param && param.optional === true;\n}\n\nfunction diagnostic(message: string, ctx: InterpretCtx, span: PslSpan): PslDiagnostic {\n return { code: ATTRIBUTE_DIAGNOSTIC_CODE, message, sourceId: ctx.sourceId, span };\n}\n","import type { PslDiagnostic, PslSpan } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { nodePslSpan } from '../../resolve';\nimport type { ExpressionAst } from '../../syntax/ast/expressions';\nimport { FunctionCallAst } from '../../syntax/ast/expressions';\nimport { interpretArgs } from '../interpret';\nimport type { ArgType, InterpretCtx, Param, PositionalParam } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\n// The argument signature of a pinned function call — the same positional/named shape an attribute\n// spec uses. Omitted groups default to empty, so a nullary call needs neither key.\nexport interface FuncCallSig {\n readonly positional?: readonly PositionalParam<unknown>[];\n readonly named?: Readonly<Record<string, Param<unknown>>>;\n}\n\nexport interface TypedFuncCall {\n readonly fn: string;\n readonly span: PslSpan;\n readonly args: Readonly<Record<string, unknown>>;\n}\n\n// A name-pinned function-call argument — `funcCall('now', {})` matches `now()`, parsing the call's\n// arguments through `sig`.\nexport function funcCall(name: string, sig: FuncCallSig): ArgType<TypedFuncCall> {\n return {\n kind: 'funcCall',\n label: 'function call',\n parse: (arg, ctx): Result<TypedFuncCall, readonly PslDiagnostic[]> => {\n const guard = matchCallee(arg, name, ctx);\n if (!guard.ok) return guard;\n const span = nodePslSpan(guard.value.syntax, ctx.sourceFile);\n const bound = interpretArgs(\n guard.value.args(),\n { name, positional: sig.positional ?? [], named: sig.named ?? {} },\n ctx,\n span,\n );\n if (!bound.ok) return notOk<readonly PslDiagnostic[]>(bound.failure);\n return ok({ fn: name, span, args: bound.value });\n },\n };\n}\n\nfunction matchCallee(\n arg: ExpressionAst,\n name: string,\n ctx: InterpretCtx,\n): Result<FunctionCallAst, readonly PslDiagnostic[]> {\n if (!(arg instanceof FunctionCallAst)) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a function call')]);\n }\n const qname = arg.name();\n if (qname === undefined || qname.dot() !== undefined || qname.colon() !== undefined) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a function call')]);\n }\n const calleeName = qname.identifier()?.token()?.text;\n if (calleeName === undefined) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected a function call')]);\n }\n if (calleeName !== name) {\n return notOk([leafDiagnostic(ctx, arg, `Expected ${name}()`)]);\n }\n return ok(arg);\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { IdentifierAst } from '../../syntax/ast/identifier';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function identifier<const N extends string>(name: N): ArgType<N> {\n return {\n kind: 'identifier',\n label: name,\n parse: (arg, ctx): Result<N, readonly PslDiagnostic[]> => {\n if (arg instanceof IdentifierAst && arg.name() === name) return ok(name);\n return notOk([leafDiagnostic(ctx, arg, `Expected ${name}`)]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { NumberLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\n// An integer literal reduced to its numeric value. Passing `min`/`max` additionally rejects\n// out-of-range integers with a distinct range message, leaving the integer-only check intact.\nexport function int(opts?: { min?: number; max?: number }): ArgType<number> {\n const min = opts?.min;\n const max = opts?.max;\n return {\n kind: 'int',\n label: 'integer',\n parse: (arg, ctx): Result<number, readonly PslDiagnostic[]> => {\n if (arg instanceof NumberLiteralExprAst) {\n const value = arg.value();\n if (value !== undefined && Number.isInteger(value)) {\n if ((min === undefined || value >= min) && (max === undefined || value <= max)) {\n return ok(value);\n }\n return notOk([leafDiagnostic(ctx, arg, rangeMessage(min, max))]);\n }\n }\n return notOk([leafDiagnostic(ctx, arg, 'Expected an integer literal')]);\n },\n };\n}\n\nfunction rangeMessage(min: number | undefined, max: number | undefined): string {\n if (min !== undefined && max !== undefined)\n return `Expected an integer between ${min} and ${max}`;\n if (min !== undefined) return `Expected an integer greater than or equal to ${min}`;\n return `Expected an integer less than or equal to ${max}`;\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { ArrayLiteralAst, type ExpressionAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport interface ListOptions {\n readonly nonEmpty?: boolean;\n readonly unique?: boolean;\n}\n\nexport function list<T>(of: ArgType<T>, opts?: ListOptions): ArgType<T[]> {\n return {\n kind: 'list',\n label: `${of.label}[]`,\n parse: (arg, ctx): Result<T[], readonly PslDiagnostic[]> => {\n if (!(arg instanceof ArrayLiteralAst)) {\n return notOk([leafDiagnostic(ctx, arg, `Expected a list of ${of.label}`)]);\n }\n const diagnostics: PslDiagnostic[] = [];\n const parsed: { node: ExpressionAst; value: T }[] = [];\n let count = 0;\n for (const element of arg.elements()) {\n count += 1;\n const result = of.parse(element, ctx);\n if (result.ok) parsed.push({ node: element, value: result.value });\n else diagnostics.push(...result.failure);\n }\n if (opts?.nonEmpty === true && count === 0) {\n diagnostics.push(leafDiagnostic(ctx, arg, 'Expected a non-empty list'));\n }\n if (opts?.unique === true) {\n const seen = new Set<T>();\n for (const { node, value } of parsed) {\n if (seen.has(value)) diagnostics.push(leafDiagnostic(ctx, node, 'Duplicate list entry'));\n else seen.add(value);\n }\n }\n if (diagnostics.length > 0) return notOk(diagnostics);\n return ok(parsed.map((entry) => entry.value));\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { NumberLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\n// A general number literal — any number, including floats — reduced to its numeric value.\n// Passing `value` pins the combinator to that single literal (`num(4)` matches only `4`),\n// mirroring how `identifier(name)` pins a bare identifier. Use `int()` when only integer\n// literals are allowed.\nexport function num(): ArgType<number>;\nexport function num(value: number): ArgType<number>;\nexport function num(value?: number): ArgType<number> {\n return {\n kind: 'num',\n label: value === undefined ? 'number' : String(value),\n parse: (arg, ctx): Result<number, readonly PslDiagnostic[]> => {\n if (arg instanceof NumberLiteralExprAst) {\n const parsed = arg.value();\n if (parsed !== undefined && (value === undefined || parsed === value)) return ok(parsed);\n }\n const message = value === undefined ? 'Expected a number literal' : `Expected ${value}`;\n return notOk([leafDiagnostic(ctx, arg, message)]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport type { ArgType, OutOf } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function oneOf<Alts extends readonly [ArgType<unknown>, ...ArgType<unknown>[]]>(\n ...alts: Alts\n): ArgType<OutOf<Alts[number]>> {\n const label = alts.map((alt) => alt.label).join(' | ');\n return {\n kind: 'oneOf',\n label,\n parse: (arg, ctx): Result<OutOf<Alts[number]>, readonly PslDiagnostic[]> => {\n for (const alt of alts) {\n const result = alt.parse(arg, ctx);\n if (result.ok) {\n return ok(\n blindCast<\n OutOf<Alts[number]>,\n 'The matched value comes from an alternative whose output type is a member of the union, but iterating the tuple widens each element to ArgType<unknown>, erasing that relationship.'\n >(result.value),\n );\n }\n }\n return notOk([leafDiagnostic(ctx, arg, `Expected one of: ${label}`)]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { ObjectLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function record<T>(of: ArgType<T>): ArgType<Record<string, T>> {\n return {\n kind: 'record',\n label: `{ [key]: ${of.label} }`,\n parse: (arg, ctx): Result<Record<string, T>, readonly PslDiagnostic[]> => {\n if (!(arg instanceof ObjectLiteralExprAst)) {\n return notOk([leafDiagnostic(ctx, arg, 'Expected an object literal')]);\n }\n const diagnostics: PslDiagnostic[] = [];\n const result: Record<string, T> = {};\n for (const field of arg.fields()) {\n const key = field.keyName();\n if (key === undefined) {\n diagnostics.push(leafDiagnostic(ctx, field, 'Expected a key'));\n continue;\n }\n const value = field.value();\n if (value === undefined) {\n diagnostics.push(leafDiagnostic(ctx, field, `Expected a value for key \"${key}\"`));\n continue;\n }\n const parsed = of.parse(value, ctx);\n if (!parsed.ok) {\n diagnostics.push(...parsed.failure);\n continue;\n }\n if (Object.hasOwn(result, key)) {\n diagnostics.push(leafDiagnostic(ctx, field, `Duplicate key \"${key}\"`));\n continue;\n }\n result[key] = parsed.value;\n }\n if (diagnostics.length > 0) return notOk(diagnostics);\n return ok(result);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { StringLiteralExprAst } from '../../syntax/ast/expressions';\nimport type { ArgType } from '../types';\nimport { leafDiagnostic } from './diagnostic';\n\nexport function str(): ArgType<string> {\n return {\n kind: 'str',\n label: 'string',\n parse: (arg, ctx): Result<string, readonly PslDiagnostic[]> => {\n if (arg instanceof StringLiteralExprAst) {\n const value = arg.value();\n if (value !== undefined) return ok(value);\n }\n return notOk([leafDiagnostic(ctx, arg, 'Expected a string literal')]);\n },\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport type { AstNode } from '../syntax/ast-helpers';\nimport type { AttributeOut, AttributeSpec, InterpretCtx, Param, PositionalParam } from './types';\n\ninterface FieldAttributeConfig<\n Pos extends readonly PositionalParam[],\n Named extends Record<string, Param<unknown>>,\n> {\n readonly positional?: Pos;\n readonly named?: Named;\n readonly refine?: (\n parsed: AttributeOut<Pos, Named>,\n ctx: InterpretCtx,\n attributeNode: AstNode,\n ) => readonly PslDiagnostic[];\n}\n\nexport function fieldAttribute<\n const Pos extends readonly PositionalParam[] = readonly [],\n const Named extends Record<string, Param<unknown>> = Record<never, never>,\n>(name: string, config: FieldAttributeConfig<Pos, Named>): AttributeSpec<AttributeOut<Pos, Named>> {\n return {\n level: 'field',\n name,\n positional: config.positional ?? [],\n named: config.named ?? {},\n ...(config.refine !== undefined ? { refine: config.refine } : {}),\n };\n}\n","import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';\nimport type { AstNode } from '../syntax/ast-helpers';\nimport type { AttributeOut, AttributeSpec, InterpretCtx, Param, PositionalParam } from './types';\n\ninterface ModelAttributeConfig<\n Pos extends readonly PositionalParam[],\n Named extends Record<string, Param<unknown>>,\n> {\n readonly positional?: Pos;\n readonly named?: Named;\n readonly refine?: (\n parsed: AttributeOut<Pos, Named>,\n ctx: InterpretCtx,\n attributeNode: AstNode,\n ) => readonly PslDiagnostic[];\n}\n\nexport function modelAttribute<\n const Pos extends readonly PositionalParam[] = readonly [],\n const Named extends Record<string, Param<unknown>> = Record<never, never>,\n>(name: string, config: ModelAttributeConfig<Pos, Named>): AttributeSpec<AttributeOut<Pos, Named>> {\n return {\n level: 'model',\n name,\n positional: config.positional ?? [],\n named: config.named ?? {},\n ...(config.refine !== undefined ? { refine: config.refine } : {}),\n };\n}\n","import type { ArgType, OptionalArgType } from './types';\n\nexport function optional<T>(type: ArgType<T>, ...rest: [defaultValue: T] | []): OptionalArgType<T> {\n if (rest.length === 0) {\n return { ...type, optional: true, hasDefault: false };\n }\n return { ...type, optional: true, hasDefault: true, defaultValue: rest[0] };\n}\n","import {\n type AuthoringPslBlockDescriptor,\n type AuthoringPslBlockDescriptorNamespace,\n isAuthoringPslBlockDescriptor,\n} from '@prisma-next/framework-components/authoring';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport {\n makePslNamespace,\n makePslNamespaceEntries,\n type PslDiagnostic,\n type PslModel,\n type PslSpan,\n UNSPECIFIED_PSL_NAMESPACE_ID,\n validateExtensionBlock,\n} from '@prisma-next/framework-components/psl-ast';\nimport type { SourceFile } from './source-file';\nimport type { BlockSymbol, ModelSymbol, SymbolTable } from './symbol-table';\n\nexport function findBlockDescriptor(\n descriptors: AuthoringPslBlockDescriptorNamespace | undefined,\n keyword: string,\n): AuthoringPslBlockDescriptor | undefined {\n if (descriptors === undefined) return undefined;\n for (const value of Object.values(descriptors)) {\n if (value === undefined) continue;\n if (isAuthoringPslBlockDescriptor(value)) {\n if (value.keyword === keyword) return value;\n continue;\n }\n const nested = findBlockDescriptor(value, keyword);\n if (nested !== undefined) return nested;\n }\n return undefined;\n}\n\nexport function validateExtensionBlockFromSymbol(input: {\n readonly block: BlockSymbol;\n readonly descriptor: AuthoringPslBlockDescriptor;\n readonly symbolTable: SymbolTable;\n readonly sourceFile: SourceFile;\n readonly sourceId: string;\n readonly codecLookup: CodecLookup;\n}): readonly PslDiagnostic[] {\n const refCtx = buildRefResolutionContext(input.symbolTable, input.block);\n return validateExtensionBlock(\n input.block.block,\n input.descriptor,\n input.sourceId,\n input.codecLookup,\n refCtx,\n );\n}\n\nconst ZERO_SPAN: PslSpan = {\n start: { offset: 0, line: 1, column: 1 },\n end: { offset: 0, line: 1, column: 1 },\n};\n\nfunction buildRefResolutionContext(\n symbolTable: SymbolTable,\n block: BlockSymbol,\n): {\n ownerNamespace: ReturnType<typeof makePslNamespace>;\n allNamespaces: readonly ReturnType<typeof makePslNamespace>[];\n} {\n const unspecifiedNamespace = makeNamespace(\n UNSPECIFIED_PSL_NAMESPACE_ID,\n Object.values(symbolTable.topLevel.models),\n );\n const namedNamespaces = Object.values(symbolTable.topLevel.namespaces).map((namespace) =>\n makeNamespace(namespace.name, Object.values(namespace.models)),\n );\n const allNamespaces = [unspecifiedNamespace, ...namedNamespaces];\n const ownerNamespaceName = findOwnerNamespaceName(symbolTable, block);\n const ownerNamespace =\n allNamespaces.find((namespace) => namespace.name === ownerNamespaceName) ??\n unspecifiedNamespace;\n return { ownerNamespace, allNamespaces };\n}\n\nfunction makeNamespace(\n name: string,\n models: readonly ModelSymbol[],\n): ReturnType<typeof makePslNamespace> {\n const modelStubs: PslModel[] = models.map((model) => ({\n kind: 'model',\n name: model.name,\n fields: [],\n attributes: [],\n span: ZERO_SPAN,\n }));\n return makePslNamespace({\n kind: 'namespace',\n name,\n entries: makePslNamespaceEntries(modelStubs, [], []),\n span: ZERO_SPAN,\n });\n}\n\nfunction findOwnerNamespaceName(symbolTable: SymbolTable, block: BlockSymbol): string {\n for (const namespace of Object.values(symbolTable.topLevel.namespaces)) {\n if (Object.values(namespace.blocks).some((candidate) => candidate === block)) {\n return namespace.name;\n }\n }\n return UNSPECIFIED_PSL_NAMESPACE_ID;\n}\n","import type { AuthoringPslBlockDescriptor } from '@prisma-next/framework-components/authoring';\nimport type {\n PslBlockParam,\n PslExtensionBlock,\n PslExtensionBlockAttribute,\n PslExtensionBlockParamValue,\n PslSpan,\n} from '@prisma-next/framework-components/psl-ast';\nimport type { ParseDiagnostic } from './parse';\nimport { nodePslSpan } from './resolve';\nimport type { SourceFile } from './source-file';\nimport type { GenericBlockDeclarationAst, KeyValuePairAst } from './syntax/ast/declarations';\nimport { ArrayLiteralAst, type ExpressionAst } from './syntax/ast/expressions';\nimport { printSyntax } from './syntax/ast-helpers';\n\n/**\n * Descriptor-free and unknown parameters become `value` stubs so validation can\n * report them via key-set comparison. Duplicate member names are first-wins.\n */\nexport function reconstructExtensionBlock(\n node: GenericBlockDeclarationAst,\n descriptor: AuthoringPslBlockDescriptor | undefined,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): PslExtensionBlock {\n const keyword = node.keyword()?.text ?? '';\n const blockName = node.name()?.name() ?? '';\n\n const blockAttributes: PslExtensionBlockAttribute[] = [];\n for (const attribute of node.attributes()) {\n const name = attribute.name()?.path().join('.') ?? '';\n const args = Array.from(attribute.argList()?.args() ?? [], (arg) => {\n const value = arg.value();\n return {\n kind: 'positional' as const,\n value: value === undefined ? '' : printSyntax(value.syntax).trim(),\n span: nodePslSpan(arg.syntax, sourceFile),\n };\n });\n blockAttributes.push({\n name,\n args,\n span: nodePslSpan(attribute.syntax, sourceFile),\n });\n }\n\n const parameters: Record<string, PslExtensionBlockParamValue> = {};\n for (const entry of node.entries()) {\n const key = entry.key()?.name();\n if (key === undefined) continue;\n const span = nodePslSpan(entry.syntax, sourceFile);\n if (Object.hasOwn(parameters, key)) {\n diagnostics.push({\n code: 'PSL_EXTENSION_DUPLICATE_PARAMETER',\n message: `Duplicate parameter \"${key}\" in \"${keyword}\" block \"${blockName}\"; first occurrence wins`,\n range: {\n start: sourceFile.positionAt(entry.syntax.offset),\n end: sourceFile.positionAt(entry.syntax.offset + entry.syntax.green.textLength),\n },\n });\n continue;\n }\n parameters[key] = reconstructParamValue(\n entry,\n descriptor?.parameters[key],\n span,\n sourceFile,\n diagnostics,\n );\n }\n\n return {\n kind: descriptor?.discriminator ?? keyword,\n keyword,\n name: blockName,\n parameters,\n blockAttributes,\n span: nodePslSpan(node.syntax, sourceFile),\n };\n}\n\nfunction reconstructParamValue(\n entry: KeyValuePairAst,\n param: PslBlockParam | undefined,\n span: PslSpan,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): PslExtensionBlockParamValue {\n const value = entry.value();\n if (value === undefined) {\n return { kind: 'bare', span };\n }\n return reconstructFromExpression(value, param, span, sourceFile, diagnostics);\n}\n\nfunction reconstructFromExpression(\n value: ExpressionAst,\n param: PslBlockParam | undefined,\n span: PslSpan,\n sourceFile: SourceFile,\n diagnostics?: ParseDiagnostic[],\n): PslExtensionBlockParamValue {\n const raw = printSyntax(value.syntax).trim();\n if (param?.kind === 'list') {\n const array = ArrayLiteralAst.cast(value.syntax);\n if (!array) {\n diagnostics?.push({\n code: 'PSL_EXTENSION_INVALID_VALUE',\n message: `List parameter expects an array literal, got ${raw}`,\n range: {\n start: sourceFile.positionAt(value.syntax.offset),\n end: sourceFile.positionAt(value.syntax.offset + value.syntax.green.textLength),\n },\n });\n return { kind: 'value', raw, span };\n }\n\n const items: PslExtensionBlockParamValue[] = [];\n for (const element of array.elements()) {\n items.push(\n reconstructFromExpression(\n element,\n param.of,\n nodePslSpan(element.syntax, sourceFile),\n sourceFile,\n diagnostics,\n ),\n );\n }\n return { kind: 'list', items, span };\n }\n switch (param?.kind) {\n case 'ref':\n return { kind: 'ref', identifier: raw, span };\n case 'option':\n return { kind: 'option', token: raw, span };\n default:\n return { kind: 'value', raw, span };\n }\n}\n","import type { AuthoringPslBlockDescriptorNamespace } from '@prisma-next/framework-components/authoring';\nimport type { PslExtensionBlock, PslSpan } from '@prisma-next/framework-components/psl-ast';\nimport { reconstructExtensionBlock } from './block-reconstruction';\nimport { findBlockDescriptor } from './extension-block';\nimport type { ParseDiagnostic } from './parse';\nimport {\n nodePslSpan,\n type ResolvedAttribute,\n type ResolvedTypeConstructorCall,\n readResolvedAttributes,\n readResolvedConstructorCall,\n} from './resolve';\nimport type { Range, SourceFile } from './source-file';\nimport {\n CompositeTypeDeclarationAst,\n type DocumentAst,\n type FieldDeclarationAst,\n GenericBlockDeclarationAst,\n ModelDeclarationAst,\n type NamedTypeDeclarationAst,\n NamespaceDeclarationAst,\n TypesBlockAst,\n} from './syntax/ast/declarations';\nimport type { IdentifierAst } from './syntax/ast/identifier';\nimport type { SyntaxNode } from './syntax/red';\n\nexport type {\n ResolvedAttribute,\n ResolvedAttributeArg,\n ResolvedTypeConstructorCall,\n} from './resolve';\n\nexport interface SymbolTable {\n readonly topLevel: TopLevelScope;\n}\n\nexport interface TopLevelScope {\n readonly namespaces: Record<string, NamespaceSymbol>;\n readonly namedTypes: Record<string, NamedTypeSymbol>;\n readonly blocks: Record<string, BlockSymbol>;\n readonly models: Record<string, ModelSymbol>;\n readonly compositeTypes: Record<string, CompositeTypeSymbol>;\n}\n\nexport interface NamespaceSymbol {\n readonly kind: 'namespace';\n readonly name: string;\n readonly node: NamespaceDeclarationAst;\n readonly span: PslSpan;\n readonly models: Record<string, ModelSymbol>;\n readonly compositeTypes: Record<string, CompositeTypeSymbol>;\n readonly blocks: Record<string, BlockSymbol>;\n}\n\nexport interface ModelSymbol {\n readonly kind: 'model';\n readonly name: string;\n readonly node: ModelDeclarationAst;\n readonly span: PslSpan;\n readonly fields: Record<string, FieldSymbol>;\n readonly attributes: readonly ResolvedAttribute[];\n}\n\nexport interface CompositeTypeSymbol {\n readonly kind: 'compositeType';\n readonly name: string;\n readonly node: CompositeTypeDeclarationAst;\n readonly span: PslSpan;\n readonly fields: Record<string, FieldSymbol>;\n readonly attributes: readonly ResolvedAttribute[];\n}\n\nexport interface BlockSymbol {\n readonly kind: 'block';\n readonly name: string;\n readonly keyword: string;\n readonly node: GenericBlockDeclarationAst;\n readonly span: PslSpan;\n /** Resolved once so consumers do not independently classify block parameters. */\n readonly block: PslExtensionBlock;\n}\n\nexport interface ResolvedNamedTypeBinding {\n readonly baseType?: string;\n readonly typeConstructor?: ResolvedTypeConstructorCall;\n readonly isConstructor: boolean;\n readonly attributes: readonly ResolvedAttribute[];\n}\n\n/**\n * A `types {}` binding, collected without classification: whether the binding\n * refines a target scalar is pronounced by the interpreter\n * (`resolveNamedTypeDeclarations`), not by the family-blind symbol table.\n */\nexport interface NamedTypeSymbol extends ResolvedNamedTypeBinding {\n readonly kind: 'namedType';\n readonly name: string;\n readonly node: NamedTypeDeclarationAst;\n readonly span: PslSpan;\n}\n\nexport interface FieldSymbol {\n readonly kind: 'field';\n readonly name: string;\n readonly node: FieldDeclarationAst;\n readonly span: PslSpan;\n readonly typeName: string;\n readonly typeNamespaceId?: string;\n readonly typeContractSpaceId?: string;\n readonly optional: boolean;\n readonly list: boolean;\n readonly typeConstructor?: ResolvedTypeConstructorCall;\n readonly attributes: readonly ResolvedAttribute[];\n /** Prevents cascading unsupported-type diagnostics after invalid qualification. */\n readonly malformedType?: boolean;\n}\n\nexport interface BuildSymbolTableOptions {\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n readonly pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace;\n}\n\nexport interface SymbolTableResult {\n readonly table: SymbolTable;\n readonly diagnostics: readonly ParseDiagnostic[];\n}\n\n/**\n * Owns duplicate-declaration detection for all PSL scopes; downstream consumers\n * should consume first-wins symbols rather than re-emitting duplicate diagnostics.\n */\nexport function buildSymbolTable(options: BuildSymbolTableOptions): SymbolTableResult {\n const { document, sourceFile, pslBlockDescriptors } = options;\n const diagnostics: ParseDiagnostic[] = [];\n\n const namespaces: Record<string, NamespaceSymbol> = {};\n const namedTypes: Record<string, NamedTypeSymbol> = {};\n const blocks: Record<string, BlockSymbol> = {};\n const models: Record<string, ModelSymbol> = {};\n const compositeTypes: Record<string, CompositeTypeSymbol> = {};\n const topLevelNames = new Set<string>();\n\n const claim = (taken: Set<string>, name: IdentifierAst | undefined): string | undefined => {\n const text = name?.name();\n if (text === undefined) return undefined;\n if (taken.has(text)) {\n const range = nameRange(name, sourceFile);\n if (range) {\n diagnostics.push({\n code: 'PSL_DUPLICATE_DECLARATION',\n message: `Duplicate declaration of \"${text}\"`,\n range,\n });\n }\n return undefined;\n }\n taken.add(text);\n return text;\n };\n\n for (const declaration of document.declarations()) {\n if (declaration instanceof ModelDeclarationAst) {\n const name = claim(topLevelNames, declaration.name());\n if (name !== undefined) models[name] = buildModel(name, declaration, sourceFile, diagnostics);\n } else if (declaration instanceof CompositeTypeDeclarationAst) {\n const name = claim(topLevelNames, declaration.name());\n if (name !== undefined) {\n compositeTypes[name] = buildCompositeType(name, declaration, sourceFile, diagnostics);\n }\n } else if (declaration instanceof GenericBlockDeclarationAst) {\n const name = claim(topLevelNames, declaration.name());\n if (name !== undefined) {\n blocks[name] = buildBlock(name, declaration, sourceFile, pslBlockDescriptors, diagnostics);\n }\n } else if (declaration instanceof NamespaceDeclarationAst) {\n const name = claim(topLevelNames, declaration.name());\n if (name !== undefined) {\n namespaces[name] = buildNamespace(\n name,\n declaration,\n diagnostics,\n sourceFile,\n pslBlockDescriptors,\n );\n }\n } else if (declaration instanceof TypesBlockAst) {\n for (const binding of declaration.declarations()) {\n const name = claim(topLevelNames, binding.name());\n if (name === undefined) continue;\n const resolved = resolveNamedTypeBinding(binding, sourceFile);\n const span = nodePslSpan(binding.syntax, sourceFile);\n namedTypes[name] = { kind: 'namedType', name, node: binding, span, ...resolved };\n }\n }\n }\n\n const table: SymbolTable = {\n topLevel: { namespaces, namedTypes, blocks, models, compositeTypes },\n };\n return { table, diagnostics };\n}\n\nfunction buildModel(\n name: string,\n node: ModelDeclarationAst,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): ModelSymbol {\n return {\n kind: 'model',\n name,\n node,\n span: nodePslSpan(node.syntax, sourceFile),\n fields: buildFields(name, node.fields(), sourceFile, diagnostics),\n attributes: readResolvedAttributes(node.attributes(), sourceFile),\n };\n}\n\nfunction buildCompositeType(\n name: string,\n node: CompositeTypeDeclarationAst,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): CompositeTypeSymbol {\n return {\n kind: 'compositeType',\n name,\n node,\n span: nodePslSpan(node.syntax, sourceFile),\n fields: buildFields(name, node.fields(), sourceFile, diagnostics),\n attributes: readResolvedAttributes(node.attributes(), sourceFile),\n };\n}\n\nfunction buildBlock(\n name: string,\n node: GenericBlockDeclarationAst,\n sourceFile: SourceFile,\n pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace,\n diagnostics: ParseDiagnostic[],\n): BlockSymbol {\n const keyword = node.keyword()?.text ?? '';\n const descriptor = findBlockDescriptor(pslBlockDescriptors, keyword);\n return {\n kind: 'block',\n name,\n keyword,\n node,\n span: nodePslSpan(node.syntax, sourceFile),\n block: reconstructExtensionBlock(node, descriptor, sourceFile, diagnostics),\n };\n}\n\nfunction buildNamespace(\n name: string,\n node: NamespaceDeclarationAst,\n diagnostics: ParseDiagnostic[],\n sourceFile: SourceFile,\n pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace,\n): NamespaceSymbol {\n const models: Record<string, ModelSymbol> = {};\n const compositeTypes: Record<string, CompositeTypeSymbol> = {};\n const blocks: Record<string, BlockSymbol> = {};\n const taken = new Set<string>();\n\n for (const member of node.declarations()) {\n const memberName = member.name()?.name();\n if (memberName === undefined) continue;\n if (taken.has(memberName)) {\n const range = nameRange(member.name(), sourceFile);\n if (range) {\n diagnostics.push({\n code: 'PSL_DUPLICATE_DECLARATION',\n message: `Duplicate declaration of \"${memberName}\"`,\n range,\n });\n }\n continue;\n }\n taken.add(memberName);\n if (member instanceof ModelDeclarationAst) {\n models[memberName] = buildModel(memberName, member, sourceFile, diagnostics);\n } else if (member instanceof CompositeTypeDeclarationAst) {\n compositeTypes[memberName] = buildCompositeType(memberName, member, sourceFile, diagnostics);\n } else if (member instanceof GenericBlockDeclarationAst) {\n blocks[memberName] = buildBlock(\n memberName,\n member,\n sourceFile,\n pslBlockDescriptors,\n diagnostics,\n );\n }\n }\n\n return {\n kind: 'namespace',\n name,\n node,\n span: nodePslSpan(node.syntax, sourceFile),\n models,\n compositeTypes,\n blocks,\n };\n}\n\nfunction buildFields(\n ownerName: string,\n fields: Iterable<FieldDeclarationAst>,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): Record<string, FieldSymbol> {\n const result: Record<string, FieldSymbol> = {};\n for (const field of fields) {\n const nameNode = field.name();\n const name = nameNode?.name();\n if (name === undefined) continue;\n if (Object.hasOwn(result, name)) {\n const range = nameRange(nameNode, sourceFile);\n if (range) {\n diagnostics.push({\n code: 'PSL_DUPLICATE_DECLARATION',\n message: `Duplicate declaration of \"${name}\"`,\n range,\n });\n }\n continue;\n }\n result[name] = buildField(ownerName, name, field, sourceFile, diagnostics);\n }\n return result;\n}\n\nfunction buildField(\n ownerName: string,\n name: string,\n node: FieldDeclarationAst,\n sourceFile: SourceFile,\n diagnostics: ParseDiagnostic[],\n): FieldSymbol {\n const attributes = readResolvedAttributes(node.attributes(), sourceFile);\n const span = nodePslSpan(node.syntax, sourceFile);\n const annotation = node.typeAnnotation();\n const typeName = annotation?.name();\n\n if (typeName?.isOverQualified()) {\n const path = typeName.path();\n diagnostics.push({\n code: 'PSL_INVALID_QUALIFIED_TYPE',\n message: `Field \"${ownerName}.${name}\" has an invalid qualified type \"${path.join('.')}\"; use at most one namespace qualifier (e.g. \"ns.TypeName\")`,\n range: nodeRange(typeName.syntax, sourceFile),\n });\n return {\n kind: 'field',\n name,\n node,\n span,\n typeName: path[path.length - 1] ?? '',\n optional: false,\n list: false,\n malformedType: true,\n attributes,\n };\n }\n\n const typeConstructor = annotation?.isConstructor()\n ? readResolvedConstructorCall(annotation, sourceFile)\n : undefined;\n const typeNamespaceId = typeName?.namespace()?.name();\n const typeContractSpaceId = typeName?.space()?.name();\n\n return {\n kind: 'field',\n name,\n node,\n span,\n typeName: typeName?.identifier()?.name() ?? '',\n ...(typeNamespaceId !== undefined ? { typeNamespaceId } : {}),\n ...(typeContractSpaceId !== undefined ? { typeContractSpaceId } : {}),\n optional: annotation?.isOptional() ?? false,\n list: annotation?.isList() ?? false,\n ...(typeConstructor !== undefined ? { typeConstructor } : {}),\n attributes,\n };\n}\n\nfunction resolveNamedTypeBinding(\n node: NamedTypeDeclarationAst,\n sourceFile: SourceFile,\n): {\n baseType?: string;\n typeConstructor?: ResolvedTypeConstructorCall;\n isConstructor: boolean;\n attributes: readonly ResolvedAttribute[];\n} {\n const annotation = node.typeAnnotation();\n const isConstructor = annotation?.isConstructor() ?? false;\n const baseType = annotation?.name()?.identifier()?.name();\n const typeConstructor = readResolvedConstructorCall(annotation, sourceFile);\n return {\n isConstructor,\n ...(!isConstructor && baseType !== undefined ? { baseType } : {}),\n ...(typeConstructor !== undefined ? { typeConstructor } : {}),\n attributes: readResolvedAttributes(node.attributes(), sourceFile),\n };\n}\n\nfunction nameRange(name: IdentifierAst | undefined, sourceFile: SourceFile): Range | undefined {\n if (name === undefined) return undefined;\n for (const token of name.syntax.tokens()) {\n if (token.kind === 'Ident') {\n return {\n start: sourceFile.positionAt(token.offset),\n end: sourceFile.positionAt(token.offset + token.text.length),\n };\n }\n }\n return undefined;\n}\n\nfunction nodeRange(node: SyntaxNode, sourceFile: SourceFile): Range {\n const start = node.offset;\n const end = start + node.green.textLength;\n return {\n start: sourceFile.positionAt(start),\n end: sourceFile.positionAt(end),\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/psl-parser",
|
|
3
|
-
"version": "0.16.0-dev.
|
|
3
|
+
"version": "0.16.0-dev.32",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "Reusable parser for Prisma Schema Language (PSL)",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/config": "0.16.0-dev.
|
|
10
|
-
"@prisma-next/contract": "0.16.0-dev.
|
|
11
|
-
"@prisma-next/framework-components": "0.16.0-dev.
|
|
12
|
-
"@prisma-next/utils": "0.16.0-dev.
|
|
9
|
+
"@prisma-next/config": "0.16.0-dev.32",
|
|
10
|
+
"@prisma-next/contract": "0.16.0-dev.32",
|
|
11
|
+
"@prisma-next/framework-components": "0.16.0-dev.32",
|
|
12
|
+
"@prisma-next/utils": "0.16.0-dev.32"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@prisma-next/tsconfig": "0.16.0-dev.
|
|
16
|
-
"@prisma-next/tsdown": "0.16.0-dev.
|
|
15
|
+
"@prisma-next/tsconfig": "0.16.0-dev.32",
|
|
16
|
+
"@prisma-next/tsdown": "0.16.0-dev.32",
|
|
17
17
|
"tsdown": "0.22.8",
|
|
18
18
|
"typescript": "5.9.3",
|
|
19
19
|
"vitest": "4.1.10"
|
|
@@ -5,9 +5,14 @@ import type { InterpretCtx } from '../types';
|
|
|
5
5
|
|
|
6
6
|
export const ATTRIBUTE_DIAGNOSTIC_CODE: PslDiagnosticCode = 'PSL_INVALID_ATTRIBUTE_SYNTAX';
|
|
7
7
|
|
|
8
|
-
export function leafDiagnostic(
|
|
8
|
+
export function leafDiagnostic(
|
|
9
|
+
ctx: InterpretCtx,
|
|
10
|
+
node: AstNode,
|
|
11
|
+
message: string,
|
|
12
|
+
code: PslDiagnostic['code'] = ATTRIBUTE_DIAGNOSTIC_CODE,
|
|
13
|
+
): PslDiagnostic {
|
|
9
14
|
return {
|
|
10
|
-
code
|
|
15
|
+
code,
|
|
11
16
|
message,
|
|
12
17
|
sourceId: ctx.sourceId,
|
|
13
18
|
span: nodePslSpan(node.syntax, ctx.sourceFile),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';
|
|
2
|
+
import type { AstNode } from '../syntax/ast-helpers';
|
|
2
3
|
import type { AttributeOut, AttributeSpec, InterpretCtx, Param, PositionalParam } from './types';
|
|
3
4
|
|
|
4
5
|
interface FieldAttributeConfig<
|
|
@@ -10,6 +11,7 @@ interface FieldAttributeConfig<
|
|
|
10
11
|
readonly refine?: (
|
|
11
12
|
parsed: AttributeOut<Pos, Named>,
|
|
12
13
|
ctx: InterpretCtx,
|
|
14
|
+
attributeNode: AstNode,
|
|
13
15
|
) => readonly PslDiagnostic[];
|
|
14
16
|
}
|
|
15
17
|
|
|
@@ -137,7 +137,7 @@ export function interpretAttribute<Out>(
|
|
|
137
137
|
'The engine builds the output object structurally from the spec; TypeScript cannot relate the dynamically-keyed record to the spec-inferred output type.'
|
|
138
138
|
>(bound.value);
|
|
139
139
|
if (spec.refine !== undefined) {
|
|
140
|
-
const refineDiagnostics = spec.refine(value, ctx);
|
|
140
|
+
const refineDiagnostics = spec.refine(value, ctx, attrNode);
|
|
141
141
|
if (refineDiagnostics.length > 0) {
|
|
142
142
|
return notOk<readonly PslDiagnostic[]>(refineDiagnostics);
|
|
143
143
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PslDiagnostic } from '@prisma-next/framework-components/psl-ast';
|
|
2
|
+
import type { AstNode } from '../syntax/ast-helpers';
|
|
2
3
|
import type { AttributeOut, AttributeSpec, InterpretCtx, Param, PositionalParam } from './types';
|
|
3
4
|
|
|
4
5
|
interface ModelAttributeConfig<
|
|
@@ -10,6 +11,7 @@ interface ModelAttributeConfig<
|
|
|
10
11
|
readonly refine?: (
|
|
11
12
|
parsed: AttributeOut<Pos, Named>,
|
|
12
13
|
ctx: InterpretCtx,
|
|
14
|
+
attributeNode: AstNode,
|
|
13
15
|
) => readonly PslDiagnostic[];
|
|
14
16
|
}
|
|
15
17
|
|
|
@@ -4,6 +4,7 @@ import type { Simplify, UnionToIntersection } from '@prisma-next/utils/types';
|
|
|
4
4
|
import type { SourceFile } from '../source-file';
|
|
5
5
|
import type { FieldSymbol, ModelSymbol } from '../symbol-table';
|
|
6
6
|
import type { ExpressionAst } from '../syntax/ast/expressions';
|
|
7
|
+
import type { AstNode } from '../syntax/ast-helpers';
|
|
7
8
|
|
|
8
9
|
export type AttributeLevel = 'field' | 'model' | 'block';
|
|
9
10
|
|
|
@@ -43,7 +44,16 @@ export interface AttributeSpec<Out> {
|
|
|
43
44
|
readonly name: string;
|
|
44
45
|
readonly positional: readonly PositionalParam[];
|
|
45
46
|
readonly named: Readonly<Record<string, Param<unknown>>>;
|
|
46
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Cross-argument validation after all arguments parse. `attributeNode` is
|
|
49
|
+
* the attribute's own AST node so refines can span-anchor their
|
|
50
|
+
* diagnostics at the attribute rather than the enclosing model.
|
|
51
|
+
*/
|
|
52
|
+
readonly refine?: (
|
|
53
|
+
parsed: Out,
|
|
54
|
+
ctx: InterpretCtx,
|
|
55
|
+
attributeNode: AstNode,
|
|
56
|
+
) => readonly PslDiagnostic[];
|
|
47
57
|
}
|
|
48
58
|
|
|
49
59
|
export type OutOf<P> = P extends ArgType<infer T> ? T : never;
|
package/src/format/error.ts
CHANGED
package/src/format/options.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { pslError } from './error';
|
|
2
|
+
|
|
1
3
|
export interface FormatOptions {
|
|
2
4
|
readonly indent?: number | 'tab';
|
|
3
5
|
readonly newline?: 'LF' | 'CRLF';
|
|
@@ -11,14 +13,18 @@ export interface ResolvedFormatOptions {
|
|
|
11
13
|
export function resolveFormatOptions(options: FormatOptions | undefined): ResolvedFormatOptions {
|
|
12
14
|
const indent = options?.indent ?? 2;
|
|
13
15
|
if (indent !== 'tab' && (typeof indent !== 'number' || !Number.isInteger(indent) || indent < 1)) {
|
|
14
|
-
throw
|
|
16
|
+
throw pslError(
|
|
17
|
+
'PSL.FORMAT_OPTION_INVALID',
|
|
15
18
|
`Invalid format options: indent must be a positive integer or 'tab', got ${String(indent)}`,
|
|
19
|
+
{ meta: { option: 'indent', received: String(indent) } },
|
|
16
20
|
);
|
|
17
21
|
}
|
|
18
22
|
const newline = options?.newline ?? 'LF';
|
|
19
23
|
if (newline !== 'LF' && newline !== 'CRLF') {
|
|
20
|
-
throw
|
|
24
|
+
throw pslError(
|
|
25
|
+
'PSL.FORMAT_OPTION_INVALID',
|
|
21
26
|
`Invalid format options: newline must be 'LF' or 'CRLF', got ${String(newline)}`,
|
|
27
|
+
{ meta: { option: 'newline', received: String(newline) } },
|
|
22
28
|
);
|
|
23
29
|
}
|
|
24
30
|
return {
|