UNPKG

@prisma/language-server

Version:
239 lines • 10.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.startServer = startServer; const vscode_languageserver_1 = require("vscode-languageserver"); const node_1 = require("vscode-languageserver/node"); const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument"); const MessageHandler = __importStar(require("./lib/MessageHandler")); const internals_1 = require("./lib/prisma-schema-wasm/internals"); const Schema_1 = require("./lib/Schema"); const packageJson = require('../package.json'); // eslint-disable-line function getConnection(options) { let connection = options?.connection; if (!connection) { connection = process.argv.includes('--stdio') ? (0, node_1.createConnection)(process.stdin, process.stdout) : (0, node_1.createConnection)(new node_1.IPCMessageReader(process), new node_1.IPCMessageWriter(process)); } return connection; } let hasCodeActionLiteralsCapability = false; let hasConfigurationCapability = false; /** * Starts the language server. * * @param options Options to customize behavior */ function startServer(options) { // Source code: https://github.com/microsoft/vscode-languageserver-node/blob/main/server/src/common/server.ts#L1044 const connection = getConnection(options); console.log = connection.console.log.bind(connection.console); console.error = connection.console.error.bind(connection.console); const documents = new vscode_languageserver_1.TextDocuments(vscode_languageserver_textdocument_1.TextDocument); connection.onInitialize((params) => { // Logging first... connection.console.info(`Default version of Prisma 'prisma-schema-wasm': ${(0, internals_1.getVersion)()}`); connection.console.info( // eslint-disable-next-line `Extension name ${packageJson.name} with version ${packageJson.version}`); const prismaEnginesVersion = (0, internals_1.getEnginesVersion)(); connection.console.info(`Prisma Engines version: ${prismaEnginesVersion}`); const prismaCliVersion = (0, internals_1.getCliVersion)(); connection.console.info(`Prisma CLI version: ${prismaCliVersion}`); // ... and then capabilities of the language server const capabilities = params.capabilities; hasCodeActionLiteralsCapability = Boolean(capabilities?.textDocument?.codeAction?.codeActionLiteralSupport); hasConfigurationCapability = Boolean(capabilities?.workspace?.configuration); const result = { capabilities: { definitionProvider: true, documentFormattingProvider: true, completionProvider: { resolveProvider: true, triggerCharacters: ['@', '"', '.'], }, hoverProvider: true, renameProvider: true, documentSymbolProvider: true, referencesProvider: true, }, }; if (hasCodeActionLiteralsCapability) { result.capabilities.codeActionProvider = { codeActionKinds: [vscode_languageserver_1.CodeActionKind.QuickFix], }; } return result; }); connection.onInitialized(() => { if (hasConfigurationCapability) { // Register for all configuration changes. // eslint-disable-next-line @typescript-eslint/no-floating-promises connection.client.register(vscode_languageserver_1.DidChangeConfigurationNotification.type, undefined); } }); // The global settings, used when the `workspace/configuration` request is not supported by the client or is not set by the user. // This does not apply to VS Code, as this client supports this setting. // const defaultSettings: LSSettings = {} // let globalSettings: LSSettings = defaultSettings // eslint-disable-line // Cache the settings of all open documents const documentSettings = new Map(); connection.onDidChangeConfiguration((_change) => { connection.console.info('Configuration changed.'); if (hasConfigurationCapability) { // Reset all cached document settings documentSettings.clear(); } else { // globalSettings = <LSSettings>(change.settings.prisma || defaultSettings) // eslint-disable-line @typescript-eslint/no-unsafe-member-access } // Revalidate all open prisma schemas documents.all().forEach(validateTextDocument); // eslint-disable-line @typescript-eslint/no-misused-promises }); // Only keep settings for open documents documents.onDidClose((e) => { documentSettings.delete(e.document.uri); }); function getDocumentSettings(resource) { if (!hasConfigurationCapability) { connection.console.info(`hasConfigurationCapability === false. Defaults will be used.`); return Promise.resolve({}); } let result = documentSettings.get(resource); if (!result) { result = connection.workspace.getConfiguration({ scopeUri: resource, section: 'prisma', }); documentSettings.set(resource, result); } return result; } // Note: VS Code strips newline characters from the message function showErrorToast(errorMessage) { connection.window.showErrorMessage(errorMessage); } async function validateTextDocument(textDocument) { const settings = await getDocumentSettings(textDocument.uri); if (settings.enableDiagnostics === false) { await connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] }); return; } const schema = await Schema_1.PrismaSchema.load(textDocument, documents); const diagnostics = MessageHandler.handleDiagnosticsRequest(schema, showErrorToast); for (const [uri, fileDiagnostics] of diagnostics.entries()) { await connection.sendDiagnostics({ uri, diagnostics: fileDiagnostics }); } } documents.onDidChangeContent(async (change) => { await validateTextDocument(change.document); }); function getDocument(uri) { return documents.get(uri); } connection.onDefinition(async (params) => { const doc = getDocument(params.textDocument.uri); if (doc) { const schema = await Schema_1.PrismaSchema.load(doc, documents); return MessageHandler.handleDefinitionRequest(schema, doc, params); } }); connection.onCompletion(async (params) => { const doc = getDocument(params.textDocument.uri); if (doc) { const schema = await Schema_1.PrismaSchema.load(doc, documents); return MessageHandler.handleCompletionRequest(schema, doc, params, showErrorToast); } }); connection.onReferences(async (params) => { const doc = getDocument(params.textDocument.uri); if (doc) { const schema = await Schema_1.PrismaSchema.load(doc, documents); return MessageHandler.handleReferencesRequest(schema, params, showErrorToast); } }); // This handler resolves additional information for the item selected in the completion list. connection.onCompletionResolve((completionItem) => { return MessageHandler.handleCompletionResolveRequest(completionItem); }); // Unused now // TODO remove or experiment new file watcher connection.onDidChangeWatchedFiles(() => { // Monitored files have changed in VS Code connection.console.log(`Types have changed. Sending request to restart TS Language Server.`); // Restart TS Language Server void connection.sendNotification('prisma/didChangeWatchedFiles', {}); }); connection.onHover(async (params) => { const doc = getDocument(params.textDocument.uri); if (doc) { const schema = await Schema_1.PrismaSchema.load(doc, documents); return MessageHandler.handleHoverRequest(schema, doc, params, showErrorToast); } }); connection.onDocumentFormatting(async (params) => { const doc = getDocument(params.textDocument.uri); if (doc) { const schema = await Schema_1.PrismaSchema.load(doc, documents); return MessageHandler.handleDocumentFormatting(schema, doc, params, showErrorToast); } }); connection.onCodeAction(async (params) => { const doc = getDocument(params.textDocument.uri); if (doc) { const schema = await Schema_1.PrismaSchema.load(doc, documents); return MessageHandler.handleCodeActions(schema, doc, params, showErrorToast); } }); connection.onRenameRequest(async (params) => { const doc = getDocument(params.textDocument.uri); if (doc) { const schema = await Schema_1.PrismaSchema.load(doc, documents); return MessageHandler.handleRenameRequest(schema, doc, params); } }); connection.onDocumentSymbol((params) => { const doc = getDocument(params.textDocument.uri); if (doc) { return MessageHandler.handleDocumentSymbol(params, doc); } }); // Make the text document manager listen on the connection // for open, change and close text document events documents.listen(connection); connection.listen(); } //# sourceMappingURL=server.js.map