@prisma-next/language-server 0.14.0-dev.21 → 0.14.0-dev.23

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/diagnostic-mapping.ts","../../src/schema-inputs.ts","../../src/config-resolution.ts","../../src/folding-ranges.ts","../../src/pipeline.ts","../../src/document-diagnostics.ts","../../src/project-artifacts.ts","../../src/server.ts","../../src/start-server.ts"],"sourcesContent":["import type { ParseDiagnostic, Range } from '@prisma-next/psl-parser/syntax';\n\nexport const ParseDiagnosticSeverity = {\n Error: 1,\n Warning: 2,\n Information: 3,\n Hint: 4,\n} as const;\n\nexport interface LspDiagnostic {\n readonly range: Range;\n readonly message: string;\n readonly code: string;\n readonly severity: number;\n}\n\nexport function mapParseDiagnostics(\n diagnostics: readonly ParseDiagnostic[],\n): readonly LspDiagnostic[] {\n return diagnostics.map((diagnostic) => ({\n range: diagnostic.range,\n message: diagnostic.message,\n code: diagnostic.code,\n severity: ParseDiagnosticSeverity.Error,\n }));\n}\n","import { pathToFileURL } from 'node:url';\n\nexport interface SchemaInputConfig {\n readonly contract?: {\n readonly source: {\n readonly sourceFormat?: string;\n readonly inputs?: readonly string[];\n };\n };\n}\n\nexport interface SchemaInputSet {\n includes(uri: string): boolean;\n}\n\nexport function hasPslInputs(config: SchemaInputConfig): boolean {\n const source = config.contract?.source;\n return source?.sourceFormat === 'psl' && source.inputs !== undefined;\n}\n\nexport function resolveSchemaInputs(config: SchemaInputConfig): SchemaInputSet {\n const inputs = hasPslInputs(config) ? config.contract?.source.inputs : undefined;\n const uris = new Set(inputs?.map((input) => pathToFileURL(input).toString()));\n\n return {\n includes: (uri) => uris.has(uri),\n };\n}\n\nexport const emptySchemaInputSet: SchemaInputSet = {\n includes: () => false,\n};\n","import { loadConfig, type PrismaNextConfig } from '@prisma-next/config-loader';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport type { FormatOptions } from '@prisma-next/psl-parser/format';\nimport type { PipelineInputs } from './pipeline';\nimport { hasPslInputs, resolveSchemaInputs, type SchemaInputSet } from './schema-inputs';\n\nexport const CONFIG_FILENAME = 'prisma-next.config.ts';\n\nexport interface ConfigResolution {\n readonly inputs: SchemaInputSet;\n readonly formatter?: FormatOptions;\n readonly controlStack: PipelineInputs;\n}\n\nconst emptyPipelineInputs: PipelineInputs = {\n scalarTypes: [],\n pslBlockDescriptors: {},\n};\n\nexport async function resolveConfigInputs(configPath: string): Promise<ConfigResolution> {\n const config = await loadConfig(configPath);\n const inputs = resolveSchemaInputs(config);\n const controlStack = resolveControlStackInputs(config) ?? emptyPipelineInputs;\n return config.formatter === undefined\n ? { inputs, controlStack }\n : { inputs, formatter: config.formatter, controlStack };\n}\n\nexport function resolveControlStackInputs(config: PrismaNextConfig): PipelineInputs | undefined {\n if (!hasPslInputs(config)) {\n return undefined;\n }\n const stack = createControlStack(config);\n return {\n scalarTypes: [...stack.scalarTypeDescriptors.keys()],\n pslBlockDescriptors: stack.authoringContributions.pslBlockDescriptors,\n };\n}\n","import {\n type DocumentAst,\n NamespaceDeclarationAst,\n type NamespaceMemberAst,\n type SourceFile,\n type TypesBlockAst,\n} from '@prisma-next/psl-parser/syntax';\nimport { type FoldingRange, FoldingRangeKind } from 'vscode-languageserver';\n\ntype Declaration = NamespaceMemberAst | TypesBlockAst | NamespaceDeclarationAst;\n\n/**\n * Computes folding ranges for block declarations in a PSL document.\n *\n * Block types that produce folding ranges:\n * - model (e.g., `model User { ... }`)\n * - composite type (e.g., `type Address { ... }`)\n * - namespace (e.g., `namespace billing { ... }`)\n * - generic blocks (generator, datasource, extension blocks)\n * - types block (e.g., `types { ... }`)\n *\n * The range spans from the line containing `{` to the line containing `}`.\n */\nexport function computeFoldingRanges(\n document: DocumentAst,\n sourceFile: SourceFile,\n): FoldingRange[] {\n const ranges: FoldingRange[] = [];\n collectFoldingRanges(document, sourceFile, ranges);\n return ranges;\n}\n\nfunction collectFoldingRanges(\n document: DocumentAst,\n sourceFile: SourceFile,\n ranges: FoldingRange[],\n): void {\n for (const declaration of document.declarations()) {\n addFoldingRange(declaration, sourceFile, ranges);\n\n const namespace = NamespaceDeclarationAst.cast(declaration.syntax);\n if (namespace !== undefined) {\n for (const nested of namespace.declarations()) {\n addFoldingRange(nested, sourceFile, ranges);\n }\n }\n }\n}\n\nfunction addFoldingRange(\n declaration: Declaration,\n sourceFile: SourceFile,\n ranges: FoldingRange[],\n): void {\n const lbrace = declaration.lbrace();\n const rbrace = declaration.rbrace();\n\n if (lbrace === undefined || rbrace === undefined) {\n return;\n }\n\n const startLine = sourceFile.positionAt(lbrace.offset).line;\n const endLine = sourceFile.positionAt(rbrace.offset).line;\n\n ranges.push({\n startLine,\n endLine,\n kind: FoldingRangeKind.Region,\n });\n}\n","import type { AuthoringPslBlockDescriptorNamespace } from '@prisma-next/framework-components/authoring';\nimport { buildSymbolTable, type SymbolTable } from '@prisma-next/psl-parser';\nimport { type DocumentAst, parse, type SourceFile } from '@prisma-next/psl-parser/syntax';\nimport { type LspDiagnostic, mapParseDiagnostics } from './diagnostic-mapping';\n\n/**\n * `pslBlockDescriptors` is kept complete on the live path so extension-block\n * validation matches the build; the structural diagnostics (duplicate\n * declaration, invalid qualified type) hold even without descriptors.\n */\nexport interface PipelineInputs {\n readonly scalarTypes: readonly string[];\n readonly pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace;\n}\n\nexport interface PipelineResult {\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n readonly symbolTable: SymbolTable;\n readonly diagnostics: readonly LspDiagnostic[];\n}\n\n/**\n * Composes the stages exactly as the contract-psl provider does, so the editor\n * and the build agree: `parse` then `buildSymbolTable`, parse diagnostics ahead\n * of symbol-table diagnostics. Never throws on malformed input — `parse`\n * recovers and `buildSymbolTable` is documented not to throw.\n */\nexport function runPipeline(text: string, inputs: PipelineInputs): PipelineResult {\n const { document, sourceFile, diagnostics: parseDiagnostics } = parse(text);\n const { table: symbolTable, diagnostics: symbolTableDiagnostics } = buildSymbolTable({\n document,\n sourceFile,\n scalarTypes: inputs.scalarTypes,\n pslBlockDescriptors: inputs.pslBlockDescriptors,\n });\n\n return {\n document,\n sourceFile,\n symbolTable,\n diagnostics: mapParseDiagnostics([...parseDiagnostics, ...symbolTableDiagnostics]),\n };\n}\n","import type { SymbolTable } from '@prisma-next/psl-parser';\nimport type { DocumentAst, SourceFile } from '@prisma-next/psl-parser/syntax';\nimport type { LspDiagnostic } from './diagnostic-mapping';\nimport { type PipelineInputs, runPipeline } from './pipeline';\nimport type { SchemaInputSet } from './schema-inputs';\n\nexport interface DocumentDiagnostics {\n readonly diagnostics: readonly LspDiagnostic[];\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n readonly symbolTable: SymbolTable;\n}\n\n/**\n * `null` (not a configured input) is distinct from a `DocumentDiagnostics` whose\n * `diagnostics` are `[]` (an input that parsed clean): the caller treats both as\n * \"publish no diagnostics\", but only the latter is a document we own and keep\n * diagnosing.\n */\nexport function computeDocumentDiagnostics(\n uri: string,\n text: string,\n inputs: SchemaInputSet,\n controlStack: PipelineInputs,\n): DocumentDiagnostics | null {\n if (!inputs.includes(uri)) {\n return null;\n }\n const { document, sourceFile, symbolTable, diagnostics } = runPipeline(text, controlStack);\n return { diagnostics, document, sourceFile, symbolTable };\n}\n","import type { SymbolTable } from '@prisma-next/psl-parser';\nimport type { DocumentAst, SourceFile } from '@prisma-next/psl-parser/syntax';\nimport type { LspDiagnostic } from './diagnostic-mapping';\nimport { computeDocumentDiagnostics } from './document-diagnostics';\nimport type { PipelineInputs } from './pipeline';\nimport type { SchemaInputSet } from './schema-inputs';\n\nexport interface CachedDocument {\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n}\n\nexport interface ProjectArtifacts {\n getDocument(uri: string): CachedDocument | undefined;\n getSymbolTable(): SymbolTable | undefined;\n update(\n uri: string,\n text: string,\n inputs: SchemaInputSet,\n controlStack: PipelineInputs,\n ): readonly LspDiagnostic[] | null;\n remove(uri: string): void;\n}\n\nexport function createProjectArtifacts(): ProjectArtifacts {\n const documents = new Map<string, CachedDocument>();\n let symbolTable: SymbolTable | undefined;\n\n return {\n getDocument: (uri) => documents.get(uri),\n getSymbolTable: () => symbolTable,\n update: (uri, text, inputs, controlStack) => {\n const computed = computeDocumentDiagnostics(uri, text, inputs, controlStack);\n if (computed === null) {\n if (documents.delete(uri)) {\n symbolTable = undefined;\n }\n return null;\n }\n documents.set(uri, {\n document: computed.document,\n sourceFile: computed.sourceFile,\n });\n // One symbol table per project. Single-input reality: it is (re)built from\n // the one open configured input on every edit. Merging several open inputs\n // into one project table — and reading unopened `inputs` from disk — is the\n // deferred cross-file work; `buildSymbolTable`'s single-document signature\n // is left untouched for it.\n symbolTable = computed.symbolTable;\n return computed.diagnostics;\n },\n remove: (uri) => {\n if (documents.delete(uri)) {\n symbolTable = undefined;\n }\n },\n };\n}\n","import { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { findNearestConfigPathForFile } from '@prisma-next/config-loader';\nimport type { SymbolTable } from '@prisma-next/psl-parser';\nimport { type FormatOptions, format } from '@prisma-next/psl-parser/format';\nimport {\n type Connection,\n type Diagnostic,\n DiagnosticSeverity,\n DidChangeWatchedFilesNotification,\n type FoldingRange,\n type InitializeParams,\n type InitializeResult,\n RegistrationRequest,\n TextDocumentSyncKind,\n TextDocuments,\n type TextEdit,\n} from 'vscode-languageserver';\nimport { TextDocument } from 'vscode-languageserver-textdocument';\nimport { CONFIG_FILENAME, resolveConfigInputs } from './config-resolution';\nimport { ParseDiagnosticSeverity } from './diagnostic-mapping';\nimport { computeFoldingRanges } from './folding-ranges';\nimport type { PipelineInputs } from './pipeline';\nimport {\n type CachedDocument,\n createProjectArtifacts,\n type ProjectArtifacts,\n} from './project-artifacts';\nimport type { SchemaInputSet } from './schema-inputs';\n\nexport interface LanguageServer {\n dispose(): void;\n /**\n * Exposed for future features (completion, semantic tokens); nothing consumes\n * them yet.\n */\n getDocumentAst(uri: string): CachedDocument | undefined;\n getProjectSymbolTable(uri: string): SymbolTable | undefined;\n}\n\ninterface ProjectState {\n readonly configPath: string;\n readonly inputs: SchemaInputSet;\n readonly formatter?: FormatOptions;\n /**\n * Resolved once per config and refreshed by the config-watch path — never\n * rebuilt per document.\n */\n readonly controlStack: PipelineInputs;\n readonly artifacts: ProjectArtifacts;\n}\n\nexport function createServer(connection: Connection): LanguageServer {\n const documents = new TextDocuments(TextDocument);\n const projects = new Map<string, ProjectState>();\n const projectLoads = new Map<string, Promise<ProjectState>>();\n const documentConfigPaths = new Map<string, string>();\n let rootPath = process.cwd();\n let watchedConfigGlob = join(rootPath, '**', CONFIG_FILENAME);\n let supportsWatchedFilesRegistration = false;\n\n async function publish(uri: string, text: string): Promise<void> {\n const project = await resolveProjectForDocument(uri);\n if (project === undefined) {\n return;\n }\n const currentDocument = documents.get(uri);\n if (currentDocument === undefined) {\n documentConfigPaths.delete(uri);\n return;\n }\n if (currentDocument.getText() !== text) {\n return;\n }\n const computed = project.artifacts.update(uri, text, project.inputs, project.controlStack);\n if (computed === null) {\n void connection.sendDiagnostics({ uri, diagnostics: [] });\n return;\n }\n const diagnostics: Diagnostic[] = computed.map((diagnostic) => ({\n range: diagnostic.range,\n message: diagnostic.message,\n code: diagnostic.code,\n severity: toLspSeverity(diagnostic.severity),\n source: 'prisma-next',\n }));\n void connection.sendDiagnostics({ uri, diagnostics });\n }\n\n async function resolveProjectForDocument(uri: string): Promise<ProjectState | undefined> {\n const knownConfigPath = documentConfigPaths.get(uri);\n if (knownConfigPath !== undefined) {\n return resolveProject(knownConfigPath);\n }\n\n const filePath = filePathFromUri(uri);\n if (filePath === undefined) {\n return undefined;\n }\n\n const configPath = await findNearestConfigPathForFile(filePath);\n if (configPath === undefined) {\n return undefined;\n }\n\n documentConfigPaths.set(uri, configPath);\n const project = await resolveProjectIfLoadable(configPath);\n if (project === undefined) {\n documentConfigPaths.delete(uri);\n }\n return project;\n }\n\n async function resolveProjectIfLoadable(configPath: string): Promise<ProjectState | undefined> {\n try {\n return await resolveProject(configPath);\n } catch {\n stopManagingProject(configPath);\n return undefined;\n }\n }\n\n async function resolveProject(configPath: string): Promise<ProjectState> {\n const existing = projects.get(configPath);\n if (existing !== undefined) {\n return existing;\n }\n const existingLoad = projectLoads.get(configPath);\n if (existingLoad !== undefined) {\n return existingLoad;\n }\n return queueProjectLoad(configPath);\n }\n\n function refreshProject(configPath: string): Promise<ProjectState> {\n return queueProjectLoad(configPath);\n }\n\n function queueProjectLoad(configPath: string): Promise<ProjectState> {\n const previousLoad = projectLoads.get(configPath) ?? Promise.resolve();\n const load = previousLoad\n .catch(() => undefined)\n .then(() => loadProject(configPath))\n .finally(() => {\n if (projectLoads.get(configPath) === load) {\n projectLoads.delete(configPath);\n }\n });\n projectLoads.set(configPath, load);\n return load;\n }\n\n async function loadProject(configPath: string): Promise<ProjectState> {\n const resolution = await resolveConfigInputs(configPath);\n // Preserve open-document ASTs across config reloads; the project symbol table\n // refreshes on the next publish against the new stack.\n const artifacts = projects.get(configPath)?.artifacts ?? createProjectArtifacts();\n const project: ProjectState =\n resolution.formatter === undefined\n ? {\n configPath,\n inputs: resolution.inputs,\n controlStack: resolution.controlStack,\n artifacts,\n }\n : {\n configPath,\n inputs: resolution.inputs,\n formatter: resolution.formatter,\n controlStack: resolution.controlStack,\n artifacts,\n };\n projects.set(configPath, project);\n return project;\n }\n\n function stopManagingProject(configPath: string): void {\n const hadProject = projects.delete(configPath);\n for (const document of documents.all()) {\n if (documentConfigPaths.get(document.uri) === configPath) {\n documentConfigPaths.delete(document.uri);\n if (hadProject) {\n void connection.sendDiagnostics({ uri: document.uri, diagnostics: [] });\n }\n }\n }\n }\n\n async function republishOpenDocumentsForConfig(configPath: string): Promise<void> {\n for (const document of documents.all()) {\n const knownConfigPath = documentConfigPaths.get(document.uri);\n if (knownConfigPath === configPath) {\n await publish(document.uri, document.getText());\n continue;\n }\n\n const filePath = filePathFromUri(document.uri);\n if (filePath === undefined) {\n continue;\n }\n const nearestConfigPath = await findNearestConfigPathForFile(filePath);\n if (nearestConfigPath === configPath) {\n documentConfigPaths.set(document.uri, configPath);\n await publish(document.uri, document.getText());\n }\n }\n }\n\n function publishSafely(uri: string, text: string): void {\n void publish(uri, text).catch((error: unknown) => {\n connection.console.error(error instanceof Error ? error.message : String(error));\n });\n }\n\n async function formatDocument(uri: string): Promise<TextEdit[]> {\n const document = documents.get(uri);\n if (document === undefined) {\n return [];\n }\n\n let project: ProjectState | undefined;\n try {\n project = await resolveProjectForDocument(uri);\n } catch {\n return [];\n }\n if (project === undefined || !project.inputs.includes(uri)) {\n return [];\n }\n\n const source = document.getText();\n let formatted: string;\n try {\n formatted = format(source, project.formatter);\n } catch {\n return [];\n }\n\n if (formatted === source) {\n return [];\n }\n\n return [\n {\n range: { start: { line: 0, character: 0 }, end: document.positionAt(source.length) },\n newText: formatted,\n },\n ];\n }\n\n connection.onInitialize(async (params): Promise<InitializeResult> => {\n rootPath = resolveRootPath(params.rootUri, params.rootPath);\n watchedConfigGlob = join(rootPath, '**', CONFIG_FILENAME);\n supportsWatchedFilesRegistration = clientSupportsWatchedFilesRegistration(params);\n\n return {\n capabilities: {\n textDocumentSync: TextDocumentSyncKind.Incremental,\n documentFormattingProvider: true,\n foldingRangeProvider: true,\n },\n };\n });\n\n connection.onInitialized(() => {\n if (supportsWatchedFilesRegistration) {\n void connection\n .sendRequest(RegistrationRequest.type, {\n registrations: [\n {\n id: 'prisma-next-config-watcher',\n method: DidChangeWatchedFilesNotification.type.method,\n registerOptions: { watchers: [{ globPattern: watchedConfigGlob }] },\n },\n ],\n })\n .catch(() => undefined);\n } else {\n connection.console.warn(\n 'Client does not support dynamic file-watcher registration; Prisma Next config changes will not be picked up without a restart.',\n );\n }\n });\n\n connection.onDidChangeWatchedFiles(async (params) => {\n const changedConfigPaths = configPathsFromWatchedChanges(\n params.changes.map((change) => filePathFromUri(change.uri)),\n );\n for (const configPath of changedConfigPaths) {\n try {\n await refreshProject(configPath);\n } catch {\n stopManagingProject(configPath);\n continue;\n }\n await republishOpenDocumentsForConfig(configPath);\n }\n });\n\n connection.onDocumentFormatting((params) => formatDocument(params.textDocument.uri));\n\n connection.onFoldingRanges(async (params): Promise<FoldingRange[]> => {\n let project: ProjectState | undefined;\n try {\n project = await resolveProjectForDocument(params.textDocument.uri);\n } catch {\n return [];\n }\n if (project === undefined) {\n return [];\n }\n const cached = project.artifacts.getDocument(params.textDocument.uri);\n if (cached === undefined) {\n return [];\n }\n return computeFoldingRanges(cached.document, cached.sourceFile);\n });\n\n documents.onDidOpen((event) => {\n publishSafely(event.document.uri, event.document.getText());\n });\n documents.onDidChangeContent((event) => {\n publishSafely(event.document.uri, event.document.getText());\n });\n documents.onDidClose((event) => {\n const uri = event.document.uri;\n const configPath = documentConfigPaths.get(uri);\n if (configPath !== undefined) {\n projects.get(configPath)?.artifacts.remove(uri);\n }\n documentConfigPaths.delete(uri);\n void connection.sendDiagnostics({ uri, diagnostics: [] });\n });\n\n documents.listen(connection);\n connection.listen();\n\n function artifactsForDocument(uri: string): ProjectArtifacts | undefined {\n const configPath = documentConfigPaths.get(uri);\n return configPath === undefined ? undefined : projects.get(configPath)?.artifacts;\n }\n\n return {\n dispose: () => {\n connection.dispose();\n },\n getDocumentAst: (uri) => artifactsForDocument(uri)?.getDocument(uri),\n getProjectSymbolTable: (uri) => artifactsForDocument(uri)?.getSymbolTable(),\n };\n}\n\nfunction toLspSeverity(severity: number): DiagnosticSeverity {\n switch (severity) {\n case ParseDiagnosticSeverity.Warning:\n return DiagnosticSeverity.Warning;\n case ParseDiagnosticSeverity.Information:\n return DiagnosticSeverity.Information;\n case ParseDiagnosticSeverity.Hint:\n return DiagnosticSeverity.Hint;\n default:\n return DiagnosticSeverity.Error;\n }\n}\n\nfunction clientSupportsWatchedFilesRegistration(params: InitializeParams): boolean {\n return params.capabilities.workspace?.didChangeWatchedFiles?.dynamicRegistration === true;\n}\n\nfunction resolveRootPath(\n rootUri: string | null | undefined,\n rootPath: string | null | undefined,\n): string {\n if (rootUri) {\n return fileURLToPath(rootUri);\n }\n if (rootPath) {\n return rootPath;\n }\n return process.cwd();\n}\n\nfunction filePathFromUri(uri: string): string | undefined {\n try {\n return fileURLToPath(uri);\n } catch {\n return undefined;\n }\n}\n\nfunction configPathsFromWatchedChanges(paths: readonly (string | undefined)[]): Set<string> {\n const configPaths = new Set<string>();\n for (const path of paths) {\n if (path?.endsWith(CONFIG_FILENAME)) {\n configPaths.add(path);\n }\n }\n return configPaths;\n}\n","import { createConnection, ProposedFeatures } from 'vscode-languageserver/node';\nimport { createServer, type LanguageServer } from './server';\n\nexport function startServer(): LanguageServer {\n const connection = createConnection(ProposedFeatures.all);\n return createServer(connection);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["#data","#sourceFile","#rangeOffsets","#intersectsRange","#addMultilineSplitToken","#encode","#first","#previousLine","#previousCharacter"],"sources":["../../src/diagnostic-mapping.ts","../../src/schema-inputs.ts","../../src/config-resolution.ts","../../src/folding-ranges.ts","../../src/pipeline.ts","../../src/document-diagnostics.ts","../../src/project-artifacts.ts","../../src/semantic-tokens.ts","../../src/server.ts","../../src/start-server.ts"],"sourcesContent":["import type { ParseDiagnostic, Range } from '@prisma-next/psl-parser/syntax';\n\nexport const ParseDiagnosticSeverity = {\n Error: 1,\n Warning: 2,\n Information: 3,\n Hint: 4,\n} as const;\n\nexport interface LspDiagnostic {\n readonly range: Range;\n readonly message: string;\n readonly code: string;\n readonly severity: number;\n}\n\nexport function mapParseDiagnostics(\n diagnostics: readonly ParseDiagnostic[],\n): readonly LspDiagnostic[] {\n return diagnostics.map((diagnostic) => ({\n range: diagnostic.range,\n message: diagnostic.message,\n code: diagnostic.code,\n severity: ParseDiagnosticSeverity.Error,\n }));\n}\n","import { pathToFileURL } from 'node:url';\n\nexport interface SchemaInputConfig {\n readonly contract?: {\n readonly source: {\n readonly sourceFormat?: string;\n readonly inputs?: readonly string[];\n };\n };\n}\n\nexport interface SchemaInputSet {\n includes(uri: string): boolean;\n}\n\nexport function hasPslInputs(config: SchemaInputConfig): boolean {\n const source = config.contract?.source;\n return source?.sourceFormat === 'psl' && source.inputs !== undefined;\n}\n\nexport function resolveSchemaInputs(config: SchemaInputConfig): SchemaInputSet {\n const inputs = hasPslInputs(config) ? config.contract?.source.inputs : undefined;\n const uris = new Set(inputs?.map((input) => pathToFileURL(input).toString()));\n\n return {\n includes: (uri) => uris.has(uri),\n };\n}\n\nexport const emptySchemaInputSet: SchemaInputSet = {\n includes: () => false,\n};\n","import { loadConfig, type PrismaNextConfig } from '@prisma-next/config-loader';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport type { FormatOptions } from '@prisma-next/psl-parser/format';\nimport type { PipelineInputs } from './pipeline';\nimport { hasPslInputs, resolveSchemaInputs, type SchemaInputSet } from './schema-inputs';\n\nexport const CONFIG_FILENAME = 'prisma-next.config.ts';\n\nexport interface ConfigResolution {\n readonly inputs: SchemaInputSet;\n readonly formatter?: FormatOptions;\n readonly controlStack: PipelineInputs;\n}\n\nconst emptyPipelineInputs: PipelineInputs = {\n scalarTypes: [],\n pslBlockDescriptors: {},\n};\n\nexport async function resolveConfigInputs(configPath: string): Promise<ConfigResolution> {\n const config = await loadConfig(configPath);\n const inputs = resolveSchemaInputs(config);\n const controlStack = resolveControlStackInputs(config) ?? emptyPipelineInputs;\n return config.formatter === undefined\n ? { inputs, controlStack }\n : { inputs, formatter: config.formatter, controlStack };\n}\n\nexport function resolveControlStackInputs(config: PrismaNextConfig): PipelineInputs | undefined {\n if (!hasPslInputs(config)) {\n return undefined;\n }\n const stack = createControlStack(config);\n return {\n scalarTypes: [...stack.scalarTypeDescriptors.keys()],\n pslBlockDescriptors: stack.authoringContributions.pslBlockDescriptors,\n };\n}\n","import {\n type DocumentAst,\n NamespaceDeclarationAst,\n type NamespaceMemberAst,\n type SourceFile,\n type TypesBlockAst,\n} from '@prisma-next/psl-parser/syntax';\nimport { type FoldingRange, FoldingRangeKind } from 'vscode-languageserver';\n\ntype Declaration = NamespaceMemberAst | TypesBlockAst | NamespaceDeclarationAst;\n\n/**\n * Computes folding ranges for block declarations in a PSL document.\n *\n * Block types that produce folding ranges:\n * - model (e.g., `model User { ... }`)\n * - composite type (e.g., `type Address { ... }`)\n * - namespace (e.g., `namespace billing { ... }`)\n * - generic blocks (generator, datasource, extension blocks)\n * - types block (e.g., `types { ... }`)\n *\n * The range spans from the line containing `{` to the line containing `}`.\n */\nexport function computeFoldingRanges(\n document: DocumentAst,\n sourceFile: SourceFile,\n): FoldingRange[] {\n const ranges: FoldingRange[] = [];\n collectFoldingRanges(document, sourceFile, ranges);\n return ranges;\n}\n\nfunction collectFoldingRanges(\n document: DocumentAst,\n sourceFile: SourceFile,\n ranges: FoldingRange[],\n): void {\n for (const declaration of document.declarations()) {\n addFoldingRange(declaration, sourceFile, ranges);\n\n const namespace = NamespaceDeclarationAst.cast(declaration.syntax);\n if (namespace !== undefined) {\n for (const nested of namespace.declarations()) {\n addFoldingRange(nested, sourceFile, ranges);\n }\n }\n }\n}\n\nfunction addFoldingRange(\n declaration: Declaration,\n sourceFile: SourceFile,\n ranges: FoldingRange[],\n): void {\n const lbrace = declaration.lbrace();\n const rbrace = declaration.rbrace();\n\n if (lbrace === undefined || rbrace === undefined) {\n return;\n }\n\n const startLine = sourceFile.positionAt(lbrace.offset).line;\n const endLine = sourceFile.positionAt(rbrace.offset).line;\n\n ranges.push({\n startLine,\n endLine,\n kind: FoldingRangeKind.Region,\n });\n}\n","import type { AuthoringPslBlockDescriptorNamespace } from '@prisma-next/framework-components/authoring';\nimport { buildSymbolTable, type SymbolTable } from '@prisma-next/psl-parser';\nimport { type DocumentAst, parse, type SourceFile } from '@prisma-next/psl-parser/syntax';\nimport { type LspDiagnostic, mapParseDiagnostics } from './diagnostic-mapping';\n\n/**\n * `pslBlockDescriptors` is kept complete on the live path so extension-block\n * validation matches the build; the structural diagnostics (duplicate\n * declaration, invalid qualified type) hold even without descriptors.\n */\nexport interface PipelineInputs {\n readonly scalarTypes: readonly string[];\n readonly pslBlockDescriptors: AuthoringPslBlockDescriptorNamespace;\n}\n\nexport interface PipelineResult {\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n readonly symbolTable: SymbolTable;\n readonly diagnostics: readonly LspDiagnostic[];\n}\n\n/**\n * Composes the stages exactly as the contract-psl provider does, so the editor\n * and the build agree: `parse` then `buildSymbolTable`, parse diagnostics ahead\n * of symbol-table diagnostics. Never throws on malformed input — `parse`\n * recovers and `buildSymbolTable` is documented not to throw.\n */\nexport function runPipeline(text: string, inputs: PipelineInputs): PipelineResult {\n const { document, sourceFile, diagnostics: parseDiagnostics } = parse(text);\n const { table: symbolTable, diagnostics: symbolTableDiagnostics } = buildSymbolTable({\n document,\n sourceFile,\n scalarTypes: inputs.scalarTypes,\n pslBlockDescriptors: inputs.pslBlockDescriptors,\n });\n\n return {\n document,\n sourceFile,\n symbolTable,\n diagnostics: mapParseDiagnostics([...parseDiagnostics, ...symbolTableDiagnostics]),\n };\n}\n","import type { SymbolTable } from '@prisma-next/psl-parser';\nimport type { DocumentAst, SourceFile } from '@prisma-next/psl-parser/syntax';\nimport type { LspDiagnostic } from './diagnostic-mapping';\nimport { type PipelineInputs, runPipeline } from './pipeline';\nimport type { SchemaInputSet } from './schema-inputs';\n\nexport interface DocumentDiagnostics {\n readonly diagnostics: readonly LspDiagnostic[];\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n readonly symbolTable: SymbolTable;\n}\n\n/**\n * `null` (not a configured input) is distinct from a `DocumentDiagnostics` whose\n * `diagnostics` are `[]` (an input that parsed clean): the caller treats both as\n * \"publish no diagnostics\", but only the latter is a document we own and keep\n * diagnosing.\n */\nexport function computeDocumentDiagnostics(\n uri: string,\n text: string,\n inputs: SchemaInputSet,\n controlStack: PipelineInputs,\n): DocumentDiagnostics | null {\n if (!inputs.includes(uri)) {\n return null;\n }\n const { document, sourceFile, symbolTable, diagnostics } = runPipeline(text, controlStack);\n return { diagnostics, document, sourceFile, symbolTable };\n}\n","import type { SymbolTable } from '@prisma-next/psl-parser';\nimport type { DocumentAst, SourceFile } from '@prisma-next/psl-parser/syntax';\nimport type { LspDiagnostic } from './diagnostic-mapping';\nimport { computeDocumentDiagnostics } from './document-diagnostics';\nimport type { PipelineInputs } from './pipeline';\nimport type { SchemaInputSet } from './schema-inputs';\n\nexport interface CachedDocument {\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n readonly text: string;\n}\n\nexport interface ProjectArtifacts {\n getDocument(uri: string): CachedDocument | undefined;\n getSymbolTable(): SymbolTable | undefined;\n update(\n uri: string,\n text: string,\n inputs: SchemaInputSet,\n controlStack: PipelineInputs,\n ): readonly LspDiagnostic[] | null;\n remove(uri: string): void;\n}\n\nexport function createProjectArtifacts(): ProjectArtifacts {\n const documents = new Map<string, CachedDocument>();\n let symbolTable: SymbolTable | undefined;\n\n return {\n getDocument: (uri) => documents.get(uri),\n getSymbolTable: () => symbolTable,\n update: (uri, text, inputs, controlStack) => {\n const computed = computeDocumentDiagnostics(uri, text, inputs, controlStack);\n if (computed === null) {\n if (documents.delete(uri)) {\n symbolTable = undefined;\n }\n return null;\n }\n documents.set(uri, {\n document: computed.document,\n sourceFile: computed.sourceFile,\n text,\n });\n // One symbol table per project. Single-input reality: it is (re)built from\n // the one open configured input on every edit. Merging several open inputs\n // into one project table — and reading unopened `inputs` from disk — is the\n // deferred cross-file work; `buildSymbolTable`'s single-document signature\n // is left untouched for it.\n symbolTable = computed.symbolTable;\n return computed.diagnostics;\n },\n remove: (uri) => {\n if (documents.delete(uri)) {\n symbolTable = undefined;\n }\n },\n };\n}\n","import type { SymbolTable } from '@prisma-next/psl-parser';\nimport {\n ArrayLiteralAst,\n type AttributeArgAst,\n type AttributeArgListAst,\n type AttributeAst,\n type BlockMemberAst,\n BooleanLiteralExprAst,\n CompositeTypeDeclarationAst,\n type DeclarationAst,\n type DocumentAst,\n type ExpressionAst,\n FieldDeclarationAst,\n FunctionCallAst,\n filterChildren,\n type GenericBlockMemberAst,\n IdentifierAst,\n ModelDeclarationAst,\n type NamedTypeDeclarationAst,\n NamespaceDeclarationAst,\n NumberLiteralExprAst,\n ObjectLiteralExprAst,\n type QualifiedNameAst,\n type SourceFile,\n StringLiteralExprAst,\n type SyntaxToken,\n type TypeAnnotationAst,\n TypesBlockAst,\n} from '@prisma-next/psl-parser/syntax';\nimport {\n type Range,\n SemanticTokenModifiers,\n type SemanticTokens,\n type SemanticTokensLegend,\n SemanticTokenTypes,\n} from 'vscode-languageserver';\n\nexport type SemanticTokenType =\n | 'keyword'\n | 'namespace'\n | 'class'\n | 'struct'\n | 'type'\n | 'property'\n | 'decorator'\n | 'string'\n | 'number'\n | 'comment';\n\nexport type SemanticTokenModifier = 'declaration' | 'defaultLibrary';\n\nexport const semanticTokenTypes: readonly SemanticTokenType[] = [\n SemanticTokenTypes.keyword,\n SemanticTokenTypes.namespace,\n SemanticTokenTypes.class,\n SemanticTokenTypes.struct,\n SemanticTokenTypes.type,\n SemanticTokenTypes.property,\n SemanticTokenTypes.decorator,\n SemanticTokenTypes.string,\n SemanticTokenTypes.number,\n SemanticTokenTypes.comment,\n];\n\nexport const semanticTokenModifiers = [\n SemanticTokenModifiers.declaration,\n SemanticTokenModifiers.defaultLibrary,\n] as const satisfies readonly SemanticTokenModifier[];\n\nexport const semanticTokenModifierIndexes = {\n declaration: 0,\n defaultLibrary: 1,\n} as const satisfies Record<SemanticTokenModifier, number>;\n\nexport const semanticTokenModifierBits = {\n declaration: 1 << semanticTokenModifierIndexes.declaration,\n defaultLibrary: 1 << semanticTokenModifierIndexes.defaultLibrary,\n} as const satisfies Record<SemanticTokenModifier, number>;\n\nexport const semanticTokensLegend: SemanticTokensLegend = {\n tokenTypes: [...semanticTokenTypes],\n tokenModifiers: [...semanticTokenModifiers],\n};\n\nexport interface SemanticTokenSource {\n readonly document: DocumentAst;\n readonly sourceFile: SourceFile;\n readonly symbolTable: SymbolTable | undefined;\n readonly scalarTypes: readonly string[];\n}\n\nexport interface PendingSemanticToken {\n readonly startOffset: number;\n readonly endOffset: number;\n readonly tokenTypeIndex: number;\n readonly modifierBitset: number;\n readonly splitMultiline: boolean;\n}\n\ntype TypeReferenceKind = 'class' | 'struct' | 'type';\n\ninterface TypeReferenceClassification {\n readonly tokenType: TypeReferenceKind;\n readonly modifierBitset?: number;\n}\n\ninterface IdentifierSegment {\n readonly identifier: IdentifierAst;\n readonly text: string;\n}\n\ninterface ExpressionContext {\n readonly bareIdentifierTokenType?: SemanticTokenType;\n}\n\nexport function buildSemanticTokens(source: SemanticTokenSource, range?: Range): SemanticTokens {\n const builder = new SemanticTokensBuilder(source.sourceFile, range);\n for (const token of collectSemanticTokenEvents(source)) {\n builder.add(token);\n }\n return builder.build();\n}\n\nexport function collectSemanticTokenEvents(\n source: SemanticTokenSource,\n): readonly PendingSemanticToken[] {\n const comments = collectCommentTokens(source.document);\n const tokens: PendingSemanticToken[] = [];\n collectDeclarations(source, tokens);\n return mergeSourceOrderedTokens(comments, tokens);\n}\n\nexport class SemanticTokensBuilder {\n readonly #data: number[] = [];\n readonly #sourceFile: SourceFile;\n readonly #rangeOffsets: { readonly lower: number; readonly upper: number } | undefined;\n #previousLine = 0;\n #previousCharacter = 0;\n #first = true;\n\n constructor(sourceFile: SourceFile, range?: Range) {\n this.#sourceFile = sourceFile;\n if (range !== undefined) {\n const startOffset = sourceFile.offsetAt(range.start);\n const endOffset = sourceFile.offsetAt(range.end);\n this.#rangeOffsets = {\n lower: Math.min(startOffset, endOffset),\n upper: Math.max(startOffset, endOffset),\n };\n }\n }\n\n add(token: PendingSemanticToken): void {\n if (!this.#intersectsRange(token.startOffset, token.endOffset)) {\n return;\n }\n\n if (token.splitMultiline) {\n this.#addMultilineSplitToken(token);\n return;\n }\n\n this.#encode(token.startOffset, token.endOffset, token.tokenTypeIndex, token.modifierBitset);\n }\n\n build(): SemanticTokens {\n return { data: this.#data };\n }\n\n #intersectsRange(startOffset: number, endOffset: number): boolean {\n const rangeOffsets = this.#rangeOffsets;\n return (\n rangeOffsets === undefined ||\n (startOffset < rangeOffsets.upper && endOffset > rangeOffsets.lower)\n );\n }\n\n #addMultilineSplitToken(token: PendingSemanticToken): void {\n const start = this.#sourceFile.positionAt(token.startOffset);\n const end = this.#sourceFile.positionAt(token.endOffset);\n if (start.line === end.line) {\n this.#encode(token.startOffset, token.endOffset, token.tokenTypeIndex, token.modifierBitset);\n return;\n }\n\n for (let line = start.line; line <= end.line; line++) {\n const startOffset =\n line === start.line ? token.startOffset : this.#sourceFile.lineStartOffset(line);\n const endOffset = line === end.line ? token.endOffset : this.#sourceFile.lineEndOffset(line);\n if (endOffset > startOffset && this.#intersectsRange(startOffset, endOffset)) {\n this.#encode(startOffset, endOffset, token.tokenTypeIndex, token.modifierBitset);\n }\n }\n }\n\n #encode(\n startOffset: number,\n endOffset: number,\n tokenTypeIndex: number,\n modifierBitset: number,\n ): void {\n const start = this.#sourceFile.positionAt(startOffset);\n const deltaLine = this.#first ? start.line : start.line - this.#previousLine;\n const deltaStart =\n this.#first || deltaLine !== 0 ? start.character : start.character - this.#previousCharacter;\n this.#data.push(deltaLine, deltaStart, endOffset - startOffset, tokenTypeIndex, modifierBitset);\n this.#previousLine = start.line;\n this.#previousCharacter = start.character;\n this.#first = false;\n }\n}\n\nfunction collectCommentTokens(document: DocumentAst): readonly PendingSemanticToken[] {\n const tokens: PendingSemanticToken[] = [];\n for (const token of document.syntax.tokens()) {\n if (token.kind === 'Comment') {\n tokens.push(pendingTokenForToken(token, 'comment'));\n }\n }\n return tokens;\n}\n\nfunction collectDeclarations(source: SemanticTokenSource, tokens: PendingSemanticToken[]): void {\n for (const declaration of source.document.declarations()) {\n collectDeclaration(declaration, source, tokens, undefined);\n }\n}\n\nfunction collectDeclaration(\n declaration: DeclarationAst,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n if (declaration instanceof ModelDeclarationAst) {\n addToken(declaration.keyword(), 'keyword', tokens);\n addIdentifier(declaration.name(), 'class', tokens, semanticTokenModifierBits.declaration);\n collectBlockMembers(declaration.members(), source, tokens, namespace);\n return;\n }\n\n if (declaration instanceof CompositeTypeDeclarationAst) {\n addToken(declaration.keyword(), 'keyword', tokens);\n addIdentifier(declaration.name(), 'struct', tokens, semanticTokenModifierBits.declaration);\n collectBlockMembers(declaration.members(), source, tokens, namespace);\n return;\n }\n\n if (declaration instanceof NamespaceDeclarationAst) {\n addToken(declaration.keyword(), 'keyword', tokens);\n addIdentifier(declaration.name(), 'namespace', tokens, semanticTokenModifierBits.declaration);\n const nestedNamespace = declaration.name()?.name();\n for (const nested of declaration.declarations()) {\n collectDeclaration(nested, source, tokens, nestedNamespace);\n }\n return;\n }\n\n if (declaration instanceof TypesBlockAst) {\n addToken(declaration.keyword(), 'keyword', tokens);\n for (const namedType of declaration.declarations()) {\n collectNamedTypeDeclaration(namedType, source, tokens, namespace);\n }\n return;\n }\n\n addToken(declaration.keyword(), 'keyword', tokens);\n addIdentifier(declaration.name(), 'type', tokens, semanticTokenModifierBits.declaration);\n collectGenericBlockMembers(declaration.members(), source, tokens, namespace);\n}\n\nfunction collectNamedTypeDeclaration(\n declaration: NamedTypeDeclarationAst,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n addIdentifier(declaration.name(), 'type', tokens, semanticTokenModifierBits.declaration);\n collectTypeAnnotation(declaration.typeAnnotation(), source, tokens, namespace);\n collectAttributes(declaration.attributes(), source, tokens, namespace);\n}\n\nfunction collectGenericBlockMembers(\n members: Iterable<GenericBlockMemberAst>,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n for (const member of members) {\n if ('key' in member) {\n addIdentifier(member.key(), 'property', tokens);\n collectExpression(member.value(), source, tokens, namespace);\n continue;\n }\n collectAttribute(member, source, tokens, namespace);\n }\n}\n\nfunction collectBlockMembers(\n members: Iterable<BlockMemberAst>,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n for (const member of members) {\n if (member instanceof FieldDeclarationAst) {\n collectField(member, source, tokens, namespace);\n continue;\n }\n collectAttribute(member, source, tokens, namespace);\n }\n}\n\nfunction collectField(\n field: FieldDeclarationAst,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n addIdentifier(field.name(), 'property', tokens, semanticTokenModifierBits.declaration);\n collectTypeAnnotation(field.typeAnnotation(), source, tokens, namespace);\n collectAttributes(field.attributes(), source, tokens, namespace);\n}\n\nfunction collectTypeAnnotation(\n annotation: TypeAnnotationAst | undefined,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n if (annotation === undefined) {\n return;\n }\n collectTypeReference(annotation.name(), source, tokens, namespace);\n collectAttributeArgList(annotation.argList(), source, tokens, namespace);\n}\n\nfunction collectAttributes(\n attributes: Iterable<AttributeAst>,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n for (const attribute of attributes) {\n collectAttribute(attribute, source, tokens, namespace);\n }\n}\n\nfunction collectAttribute(\n attribute: AttributeAst,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n collectDecoratorName(attribute.name(), source.sourceFile.text, tokens);\n collectAttributeArgList(attribute.argList(), source, tokens, namespace);\n}\n\nfunction collectDecoratorName(\n name: QualifiedNameAst | undefined,\n sourceText: string,\n tokens: PendingSemanticToken[],\n): void {\n if (name === undefined) {\n return;\n }\n const segments = identifierSegments(name);\n for (const [index, segment] of segments.entries()) {\n tokens.push(rangeForDecoratorIdentifier(segment.identifier, sourceText, index === 0));\n }\n}\n\nfunction collectAttributeArgList(\n argList: AttributeArgListAst | undefined,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n if (argList === undefined) {\n return;\n }\n for (const arg of argList.args()) {\n collectAttributeArg(arg, source, tokens, namespace);\n }\n}\n\nfunction collectAttributeArg(\n arg: AttributeArgAst,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n const name = arg.name();\n addIdentifier(name, 'property', tokens);\n collectExpression(arg.value(), source, tokens, namespace, expressionContextForAttributeArg(name));\n}\n\nfunction collectExpression(\n expression: ExpressionAst | undefined,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n context: ExpressionContext = {},\n): void {\n if (expression === undefined) {\n return;\n }\n\n if (expression instanceof StringLiteralExprAst) {\n addToken(expression.token(), 'string', tokens);\n return;\n }\n\n if (expression instanceof NumberLiteralExprAst) {\n addToken(expression.token(), 'number', tokens);\n return;\n }\n\n if (expression instanceof BooleanLiteralExprAst) {\n addToken(expression.token(), 'keyword', tokens);\n return;\n }\n\n if (expression instanceof FunctionCallAst) {\n collectTypeReference(expression.name(), source, tokens, namespace);\n for (const arg of expression.args()) {\n collectAttributeArg(arg, source, tokens, namespace);\n }\n return;\n }\n\n if (expression instanceof ArrayLiteralAst) {\n for (const element of expression.elements()) {\n collectExpression(element, source, tokens, namespace, context);\n }\n return;\n }\n\n if (expression instanceof ObjectLiteralExprAst) {\n for (const field of expression.fields()) {\n addIdentifier(field.key(), 'property', tokens);\n collectExpression(field.value(), source, tokens, namespace);\n }\n return;\n }\n\n collectIdentifierExpression(expression, source, tokens, namespace, context);\n}\n\nfunction collectIdentifierExpression(\n identifier: IdentifierAst,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n context: ExpressionContext,\n): void {\n const text = identifier.name();\n if (text === undefined) {\n return;\n }\n const bareIdentifierTokenType = context.bareIdentifierTokenType;\n if (bareIdentifierTokenType !== undefined) {\n tokens.push(rangeForIdentifier(identifier, bareIdentifierTokenType));\n return;\n }\n const classification = classifyTypeReference([text], source, namespace);\n tokens.push(\n rangeForIdentifier(identifier, classification.tokenType, classification.modifierBitset),\n );\n}\n\nfunction expressionContextForAttributeArg(name: IdentifierAst | undefined): ExpressionContext {\n const argName = name?.name();\n return argName === 'fields' || argName === 'references'\n ? { bareIdentifierTokenType: 'property' }\n : {};\n}\n\nfunction collectTypeReference(\n name: QualifiedNameAst | undefined,\n source: SemanticTokenSource,\n tokens: PendingSemanticToken[],\n namespace: string | undefined,\n): void {\n if (name === undefined) {\n return;\n }\n\n const segments = identifierSegments(name);\n if (segments.length === 0) {\n return;\n }\n\n const path = segments.map((segment) => segment.text);\n for (const segment of segments.slice(0, -1)) {\n if (isKnownNamespace(segment.text, source.symbolTable)) {\n tokens.push(rangeForIdentifier(segment.identifier, 'namespace'));\n }\n }\n\n const finalSegment = segments[segments.length - 1];\n if (finalSegment === undefined) {\n return;\n }\n const classification = classifyTypeReference(path, source, namespace);\n tokens.push(\n rangeForIdentifier(\n finalSegment.identifier,\n classification.tokenType,\n classification.modifierBitset,\n ),\n );\n}\n\nfunction classifyTypeReference(\n path: readonly string[],\n source: SemanticTokenSource,\n namespace: string | undefined,\n): TypeReferenceClassification {\n const name = path[path.length - 1];\n if (name === undefined) {\n return { tokenType: 'type' };\n }\n\n const table = source.symbolTable;\n const namespaceName = path.length > 1 ? path[path.length - 2] : namespace;\n const namespaceScope =\n namespaceName !== undefined ? table?.topLevel.namespaces[namespaceName] : undefined;\n\n if (namespaceScope !== undefined) {\n if (Object.hasOwn(namespaceScope.models, name)) {\n return { tokenType: 'class' };\n }\n if (Object.hasOwn(namespaceScope.compositeTypes, name)) {\n return { tokenType: 'struct' };\n }\n if (Object.hasOwn(namespaceScope.blocks, name)) {\n return { tokenType: 'type' };\n }\n }\n\n if (table !== undefined) {\n if (Object.hasOwn(table.topLevel.models, name)) {\n return { tokenType: 'class' };\n }\n if (Object.hasOwn(table.topLevel.compositeTypes, name)) {\n return { tokenType: 'struct' };\n }\n if (Object.hasOwn(table.topLevel.scalars, name)) {\n return { tokenType: 'type', modifierBitset: semanticTokenModifierBits.defaultLibrary };\n }\n if (\n Object.hasOwn(table.topLevel.typeAliases, name) ||\n Object.hasOwn(table.topLevel.blocks, name)\n ) {\n return { tokenType: 'type' };\n }\n }\n\n if (source.scalarTypes.includes(name)) {\n return { tokenType: 'type', modifierBitset: semanticTokenModifierBits.defaultLibrary };\n }\n\n return { tokenType: 'type' };\n}\n\nfunction isKnownNamespace(name: string, table: SymbolTable | undefined): boolean {\n return table !== undefined && Object.hasOwn(table.topLevel.namespaces, name);\n}\n\nfunction identifierSegments(name: QualifiedNameAst): readonly IdentifierSegment[] {\n const segments: IdentifierSegment[] = [];\n for (const identifier of filterChildren(name.syntax, IdentifierAst.cast)) {\n const text = identifier.name();\n if (text !== undefined) {\n segments.push({ identifier, text });\n }\n }\n return segments;\n}\n\nfunction addIdentifier(\n identifier: IdentifierAst | undefined,\n tokenType: SemanticTokenType,\n tokens: PendingSemanticToken[],\n modifierBitset = 0,\n): void {\n if (identifier === undefined) {\n return;\n }\n tokens.push(rangeForIdentifier(identifier, tokenType, modifierBitset));\n}\n\nfunction addToken(\n token: SyntaxToken | undefined,\n tokenType: SemanticTokenType,\n tokens: PendingSemanticToken[],\n modifierBitset = 0,\n): void {\n if (token === undefined) {\n return;\n }\n tokens.push(pendingTokenForToken(token, tokenType, modifierBitset));\n}\n\nfunction rangeForIdentifier(\n identifier: IdentifierAst,\n tokenType: SemanticTokenType,\n modifierBitset = 0,\n): PendingSemanticToken {\n const token = identifier.token();\n if (token === undefined) {\n return createPendingSemanticToken(\n identifier.syntax.offset,\n identifier.syntax.offset,\n tokenType,\n modifierBitset,\n );\n }\n return pendingTokenForToken(token, tokenType, modifierBitset);\n}\n\nfunction rangeForDecoratorIdentifier(\n identifier: IdentifierAst,\n sourceText: string,\n includePrefix: boolean,\n): PendingSemanticToken {\n const range = rangeForIdentifier(identifier, 'decorator');\n if (!includePrefix) {\n return range;\n }\n\n let startOffset = range.startOffset;\n while (startOffset > 0 && sourceText.charAt(startOffset - 1) === '@') {\n startOffset--;\n }\n return createPendingSemanticToken(\n startOffset,\n range.endOffset,\n 'decorator',\n range.modifierBitset,\n );\n}\n\nfunction pendingTokenForToken(\n token: SyntaxToken,\n tokenType: SemanticTokenType,\n modifierBitset = 0,\n): PendingSemanticToken {\n return createPendingSemanticToken(\n token.offset,\n token.offset + token.text.length,\n tokenType,\n modifierBitset,\n );\n}\n\nfunction mergeSourceOrderedTokens(\n left: readonly PendingSemanticToken[],\n right: readonly PendingSemanticToken[],\n): readonly PendingSemanticToken[] {\n const result: PendingSemanticToken[] = [];\n let leftIndex = 0;\n let rightIndex = 0;\n\n while (leftIndex < left.length || rightIndex < right.length) {\n const leftToken = left[leftIndex];\n const rightToken = right[rightIndex];\n if (\n leftToken !== undefined &&\n (rightToken === undefined || leftToken.startOffset <= rightToken.startOffset)\n ) {\n result.push(leftToken);\n leftIndex++;\n } else if (rightToken !== undefined) {\n result.push(rightToken);\n rightIndex++;\n }\n }\n\n return result;\n}\n\nfunction createPendingSemanticToken(\n startOffset: number,\n endOffset: number,\n tokenType: SemanticTokenType,\n modifierBitset = 0,\n): PendingSemanticToken {\n return {\n startOffset,\n endOffset,\n tokenTypeIndex: tokenTypeIndex(tokenType),\n modifierBitset,\n splitMultiline: tokenType === 'string' || tokenType === 'comment',\n };\n}\n\nfunction tokenTypeIndex(tokenType: SemanticTokenType): number {\n return semanticTokenTypes.indexOf(tokenType);\n}\n","import { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { findNearestConfigPathForFile } from '@prisma-next/config-loader';\nimport type { SymbolTable } from '@prisma-next/psl-parser';\nimport { type FormatOptions, format } from '@prisma-next/psl-parser/format';\nimport {\n type Connection,\n type Diagnostic,\n DiagnosticSeverity,\n DidChangeWatchedFilesNotification,\n type FoldingRange,\n type InitializeParams,\n type InitializeResult,\n type Range,\n RegistrationRequest,\n type SemanticTokens,\n TextDocumentSyncKind,\n TextDocuments,\n type TextEdit,\n} from 'vscode-languageserver';\nimport { TextDocument } from 'vscode-languageserver-textdocument';\nimport { CONFIG_FILENAME, resolveConfigInputs } from './config-resolution';\nimport { ParseDiagnosticSeverity } from './diagnostic-mapping';\nimport { computeFoldingRanges } from './folding-ranges';\nimport type { PipelineInputs } from './pipeline';\nimport {\n type CachedDocument,\n createProjectArtifacts,\n type ProjectArtifacts,\n} from './project-artifacts';\nimport type { SchemaInputSet } from './schema-inputs';\nimport { buildSemanticTokens, semanticTokensLegend } from './semantic-tokens';\n\nexport interface LanguageServer {\n dispose(): void;\n /**\n * Exposed for future features (completion, semantic tokens); nothing consumes\n * them yet.\n */\n getDocumentAst(uri: string): CachedDocument | undefined;\n getProjectSymbolTable(uri: string): SymbolTable | undefined;\n}\n\ninterface ProjectState {\n readonly configPath: string;\n readonly inputs: SchemaInputSet;\n readonly formatter?: FormatOptions;\n /**\n * Resolved once per config and refreshed by the config-watch path — never\n * rebuilt per document.\n */\n readonly controlStack: PipelineInputs;\n readonly artifacts: ProjectArtifacts;\n}\n\nconst semanticTokenSourceLimit = 100_000;\n\nexport function createServer(connection: Connection): LanguageServer {\n const documents = new TextDocuments(TextDocument);\n const projects = new Map<string, ProjectState>();\n const projectLoads = new Map<string, Promise<ProjectState>>();\n const documentConfigPaths = new Map<string, string>();\n let rootPath = process.cwd();\n let watchedConfigGlob = join(rootPath, '**', CONFIG_FILENAME);\n let supportsWatchedFilesRegistration = false;\n\n async function publish(uri: string): Promise<void> {\n const project = await resolveProjectForDocument(uri);\n if (project === undefined) {\n return;\n }\n const document = documents.get(uri);\n if (document === undefined) {\n documentConfigPaths.delete(uri);\n return;\n }\n const computed = project.artifacts.update(\n uri,\n document.getText(),\n project.inputs,\n project.controlStack,\n );\n if (computed === null) {\n void connection.sendDiagnostics({ uri, diagnostics: [] });\n return;\n }\n const diagnostics: Diagnostic[] = computed.map((diagnostic) => ({\n range: diagnostic.range,\n message: diagnostic.message,\n code: diagnostic.code,\n severity: toLspSeverity(diagnostic.severity),\n source: 'prisma-next',\n }));\n void connection.sendDiagnostics({ uri, diagnostics });\n }\n\n async function resolveProjectForDocument(uri: string): Promise<ProjectState | undefined> {\n const knownConfigPath = documentConfigPaths.get(uri);\n if (knownConfigPath !== undefined) {\n const project = await resolveProjectIfLoadable(knownConfigPath);\n if (project === undefined) {\n documentConfigPaths.delete(uri);\n }\n return project;\n }\n\n const filePath = filePathFromUri(uri);\n if (filePath === undefined) {\n return undefined;\n }\n\n const configPath = await findNearestConfigPathForFile(filePath);\n if (configPath === undefined) {\n return undefined;\n }\n\n documentConfigPaths.set(uri, configPath);\n const project = await resolveProjectIfLoadable(configPath);\n if (project === undefined) {\n documentConfigPaths.delete(uri);\n }\n return project;\n }\n\n async function resolveProjectIfLoadable(configPath: string): Promise<ProjectState | undefined> {\n try {\n return await resolveProject(configPath);\n } catch {\n stopManagingProject(configPath);\n return undefined;\n }\n }\n\n async function resolveProject(configPath: string): Promise<ProjectState> {\n const existing = projects.get(configPath);\n if (existing !== undefined) {\n return existing;\n }\n const existingLoad = projectLoads.get(configPath);\n if (existingLoad !== undefined) {\n return existingLoad;\n }\n return queueProjectLoad(configPath);\n }\n\n function refreshProject(configPath: string): Promise<ProjectState> {\n return queueProjectLoad(configPath);\n }\n\n function queueProjectLoad(configPath: string): Promise<ProjectState> {\n const previousLoad = projectLoads.get(configPath) ?? Promise.resolve();\n const load = previousLoad\n .catch(() => undefined)\n .then(() => loadProject(configPath))\n .finally(() => {\n if (projectLoads.get(configPath) === load) {\n projectLoads.delete(configPath);\n }\n });\n projectLoads.set(configPath, load);\n return load;\n }\n\n async function loadProject(configPath: string): Promise<ProjectState> {\n const resolution = await resolveConfigInputs(configPath);\n // Preserve open-document ASTs across config reloads; the project symbol table\n // refreshes on the next publish against the new stack.\n const artifacts = projects.get(configPath)?.artifacts ?? createProjectArtifacts();\n const project: ProjectState =\n resolution.formatter === undefined\n ? {\n configPath,\n inputs: resolution.inputs,\n controlStack: resolution.controlStack,\n artifacts,\n }\n : {\n configPath,\n inputs: resolution.inputs,\n formatter: resolution.formatter,\n controlStack: resolution.controlStack,\n artifacts,\n };\n projects.set(configPath, project);\n return project;\n }\n\n function stopManagingProject(configPath: string): void {\n const hadProject = projects.delete(configPath);\n for (const document of documents.all()) {\n if (documentConfigPaths.get(document.uri) === configPath) {\n documentConfigPaths.delete(document.uri);\n if (hadProject) {\n void connection.sendDiagnostics({ uri: document.uri, diagnostics: [] });\n }\n }\n }\n }\n\n async function republishOpenDocumentsForConfig(configPath: string): Promise<void> {\n for (const document of documents.all()) {\n const knownConfigPath = documentConfigPaths.get(document.uri);\n if (knownConfigPath === configPath) {\n await publish(document.uri);\n continue;\n }\n\n const filePath = filePathFromUri(document.uri);\n if (filePath === undefined) {\n continue;\n }\n const nearestConfigPath = await findNearestConfigPathForFile(filePath);\n if (nearestConfigPath === configPath) {\n documentConfigPaths.set(document.uri, configPath);\n await publish(document.uri);\n }\n }\n }\n\n function publishSafely(uri: string): void {\n void publish(uri).catch((error: unknown) => {\n connection.console.error(error instanceof Error ? error.message : String(error));\n });\n }\n\n async function formatDocument(uri: string): Promise<TextEdit[]> {\n const document = documents.get(uri);\n if (document === undefined) {\n return [];\n }\n\n let project: ProjectState | undefined;\n try {\n project = await resolveProjectForDocument(uri);\n } catch {\n return [];\n }\n if (project === undefined || !project.inputs.includes(uri)) {\n return [];\n }\n\n const source = document.getText();\n let formatted: string;\n try {\n formatted = format(source, project.formatter);\n } catch {\n return [];\n }\n\n if (formatted === source) {\n return [];\n }\n\n return [\n {\n range: { start: { line: 0, character: 0 }, end: document.positionAt(source.length) },\n newText: formatted,\n },\n ];\n }\n\n async function semanticTokensForDocument(uri: string, range?: Range): Promise<SemanticTokens> {\n const document = documents.get(uri);\n if (document === undefined) {\n return emptySemanticTokens();\n }\n const text = document.getText();\n if (text.length > semanticTokenSourceLimit) {\n return emptySemanticTokens();\n }\n\n const project = await resolveProjectForDocument(uri);\n if (project === undefined) {\n return emptySemanticTokens();\n }\n\n const cached = project.artifacts.getDocument(uri);\n if (cached === undefined || cached.text !== text) {\n return emptySemanticTokens();\n }\n\n const source = {\n document: cached.document,\n sourceFile: cached.sourceFile,\n symbolTable: project.artifacts.getSymbolTable(),\n scalarTypes: project.controlStack.scalarTypes,\n };\n return buildSemanticTokens(source, range);\n }\n\n connection.onInitialize(async (params): Promise<InitializeResult> => {\n rootPath = resolveRootPath(params.rootUri, params.rootPath);\n watchedConfigGlob = join(rootPath, '**', CONFIG_FILENAME);\n supportsWatchedFilesRegistration = clientSupportsWatchedFilesRegistration(params);\n\n return {\n capabilities: {\n textDocumentSync: TextDocumentSyncKind.Incremental,\n documentFormattingProvider: true,\n foldingRangeProvider: true,\n semanticTokensProvider: {\n legend: semanticTokensLegend,\n full: true,\n range: true,\n },\n },\n };\n });\n\n connection.onInitialized(() => {\n if (supportsWatchedFilesRegistration) {\n void connection\n .sendRequest(RegistrationRequest.type, {\n registrations: [\n {\n id: 'prisma-next-config-watcher',\n method: DidChangeWatchedFilesNotification.type.method,\n registerOptions: { watchers: [{ globPattern: watchedConfigGlob }] },\n },\n ],\n })\n .catch(() => undefined);\n } else {\n connection.console.warn(\n 'Client does not support dynamic file-watcher registration; Prisma Next config changes will not be picked up without a restart.',\n );\n }\n });\n\n connection.onDidChangeWatchedFiles(async (params) => {\n const changedConfigPaths = configPathsFromWatchedChanges(\n params.changes.map((change) => filePathFromUri(change.uri)),\n );\n for (const configPath of changedConfigPaths) {\n try {\n await refreshProject(configPath);\n } catch {\n stopManagingProject(configPath);\n continue;\n }\n await republishOpenDocumentsForConfig(configPath);\n }\n });\n\n connection.onDocumentFormatting((params) => formatDocument(params.textDocument.uri));\n\n connection.languages.semanticTokens.on((params) =>\n semanticTokensForDocument(params.textDocument.uri),\n );\n connection.languages.semanticTokens.onRange((params) =>\n semanticTokensForDocument(params.textDocument.uri, params.range),\n );\n\n connection.onFoldingRanges(async (params): Promise<FoldingRange[]> => {\n let project: ProjectState | undefined;\n try {\n project = await resolveProjectForDocument(params.textDocument.uri);\n } catch {\n return [];\n }\n if (project === undefined) {\n return [];\n }\n const cached = project.artifacts.getDocument(params.textDocument.uri);\n if (cached === undefined) {\n return [];\n }\n return computeFoldingRanges(cached.document, cached.sourceFile);\n });\n\n documents.onDidOpen((event) => {\n publishSafely(event.document.uri);\n });\n documents.onDidChangeContent((event) => {\n publishSafely(event.document.uri);\n });\n documents.onDidClose((event) => {\n const uri = event.document.uri;\n const configPath = documentConfigPaths.get(uri);\n if (configPath !== undefined) {\n projects.get(configPath)?.artifacts.remove(uri);\n }\n documentConfigPaths.delete(uri);\n void connection.sendDiagnostics({ uri, diagnostics: [] });\n });\n\n documents.listen(connection);\n connection.listen();\n\n function artifactsForDocument(uri: string): ProjectArtifacts | undefined {\n const configPath = documentConfigPaths.get(uri);\n return configPath === undefined ? undefined : projects.get(configPath)?.artifacts;\n }\n\n return {\n dispose: () => {\n connection.dispose();\n },\n getDocumentAst: (uri) => artifactsForDocument(uri)?.getDocument(uri),\n getProjectSymbolTable: (uri) => artifactsForDocument(uri)?.getSymbolTable(),\n };\n}\n\nfunction emptySemanticTokens(): SemanticTokens {\n return { data: [] };\n}\n\nfunction toLspSeverity(severity: number): DiagnosticSeverity {\n switch (severity) {\n case ParseDiagnosticSeverity.Warning:\n return DiagnosticSeverity.Warning;\n case ParseDiagnosticSeverity.Information:\n return DiagnosticSeverity.Information;\n case ParseDiagnosticSeverity.Hint:\n return DiagnosticSeverity.Hint;\n default:\n return DiagnosticSeverity.Error;\n }\n}\n\nfunction clientSupportsWatchedFilesRegistration(params: InitializeParams): boolean {\n return params.capabilities.workspace?.didChangeWatchedFiles?.dynamicRegistration === true;\n}\n\nfunction resolveRootPath(\n rootUri: string | null | undefined,\n rootPath: string | null | undefined,\n): string {\n if (rootUri) {\n return fileURLToPath(rootUri);\n }\n if (rootPath) {\n return rootPath;\n }\n return process.cwd();\n}\n\nfunction filePathFromUri(uri: string): string | undefined {\n try {\n return fileURLToPath(uri);\n } catch {\n return undefined;\n }\n}\n\nfunction configPathsFromWatchedChanges(paths: readonly (string | undefined)[]): Set<string> {\n const configPaths = new Set<string>();\n for (const path of paths) {\n if (path?.endsWith(CONFIG_FILENAME)) {\n configPaths.add(path);\n }\n }\n return configPaths;\n}\n","import { createConnection, ProposedFeatures } from 'vscode-languageserver/node';\nimport { createServer, type LanguageServer } from './server';\n\nexport function startServer(): LanguageServer {\n const connection = createConnection(ProposedFeatures.all);\n return createServer(connection);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@prisma-next/language-server",
3
- "version": "0.14.0-dev.21",
3
+ "version": "0.14.0-dev.23",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "Prisma Next language server: PSL diagnostics and whole-document formatting over LSP",
8
8
  "dependencies": {
9
- "@prisma-next/config-loader": "0.14.0-dev.21",
10
- "@prisma-next/errors": "0.14.0-dev.21",
11
- "@prisma-next/framework-components": "0.14.0-dev.21",
12
- "@prisma-next/psl-parser": "0.14.0-dev.21",
13
- "@prisma-next/utils": "0.14.0-dev.21",
9
+ "@prisma-next/config-loader": "0.14.0-dev.23",
10
+ "@prisma-next/errors": "0.14.0-dev.23",
11
+ "@prisma-next/framework-components": "0.14.0-dev.23",
12
+ "@prisma-next/psl-parser": "0.14.0-dev.23",
13
+ "@prisma-next/utils": "0.14.0-dev.23",
14
14
  "vscode-languageserver": "10.0.0",
15
15
  "vscode-languageserver-textdocument": "1.0.12"
16
16
  },
17
17
  "devDependencies": {
18
- "@prisma-next/test-utils": "0.14.0-dev.21",
19
- "@prisma-next/tsconfig": "0.14.0-dev.21",
20
- "@prisma-next/tsdown": "0.14.0-dev.21",
18
+ "@prisma-next/test-utils": "0.14.0-dev.23",
19
+ "@prisma-next/tsconfig": "0.14.0-dev.23",
20
+ "@prisma-next/tsdown": "0.14.0-dev.23",
21
21
  "@types/node": "25.9.1",
22
22
  "tsdown": "0.22.1",
23
23
  "typescript": "5.9.3",
@@ -8,6 +8,7 @@ import type { SchemaInputSet } from './schema-inputs';
8
8
  export interface CachedDocument {
9
9
  readonly document: DocumentAst;
10
10
  readonly sourceFile: SourceFile;
11
+ readonly text: string;
11
12
  }
12
13
 
13
14
  export interface ProjectArtifacts {
@@ -40,6 +41,7 @@ export function createProjectArtifacts(): ProjectArtifacts {
40
41
  documents.set(uri, {
41
42
  document: computed.document,
42
43
  sourceFile: computed.sourceFile,
44
+ text,
43
45
  });
44
46
  // One symbol table per project. Single-input reality: it is (re)built from
45
47
  // the one open configured input on every edit. Merging several open inputs