UNPKG

apollo-language-server

Version:

A language server for Apollo GraphQL projects

172 lines 6.71 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GraphQLWorkspace = void 0; const path_1 = require("path"); const glob_1 = __importDefault(require("glob")); const config_1 = require("./config"); const client_1 = require("./project/client"); const service_1 = require("./project/service"); const vscode_uri_1 = __importDefault(require("vscode-uri")); const utilities_1 = require("./utilities"); class GraphQLWorkspace { constructor(LanguageServerLoadingHandler, config) { this.LanguageServerLoadingHandler = LanguageServerLoadingHandler; this.config = config; this._projectForFileCache = new Map(); this.projectsByFolderUri = new Map(); } onDiagnostics(handler) { this._onDiagnostics = handler; } onDecorations(handler) { this._onDecorations = handler; } onSchemaTags(handler) { this._onSchemaTags = handler; } onConfigFilesFound(handler) { this._onConfigFilesFound = handler; } createProject({ config, folder, }) { const { clientIdentity } = this.config; const project = (0, config_1.isClientConfig)(config) ? new client_1.GraphQLClientProject({ config, loadingHandler: this.LanguageServerLoadingHandler, rootURI: vscode_uri_1.default.parse(folder.uri), clientIdentity, }) : new service_1.GraphQLServiceProject({ config: config, loadingHandler: this.LanguageServerLoadingHandler, rootURI: vscode_uri_1.default.parse(folder.uri), clientIdentity, }); project.onDiagnostics((params) => { this._onDiagnostics && this._onDiagnostics(params); }); if ((0, client_1.isClientProject)(project)) { project.onDecorations((params) => { this._onDecorations && this._onDecorations(params); }); project.onSchemaTags((tags) => { this._onSchemaTags && this._onSchemaTags(tags); }); } project.whenReady.then(() => project.validate()); return project; } async addProjectsInFolder(folder) { const apolloConfigFiles = glob_1.default.sync("**/apollo.config.@(js|ts|cjs)", { cwd: vscode_uri_1.default.parse(folder.uri).fsPath, absolute: true, ignore: "**/node_modules/**", }); const apolloConfigFolders = new Set(apolloConfigFiles.map(path_1.dirname)); let foundConfigs = []; const projectConfigs = Array.from(apolloConfigFolders).map((configFolder) => (0, config_1.loadConfig)({ configPath: configFolder, requireConfig: true }) .then((config) => { if (config) { foundConfigs.push(config); const projectsForConfig = config.projects.map((projectConfig) => this.createProject({ config, folder })); const existingProjects = this.projectsByFolderUri.get(folder.uri) || []; this.projectsByFolderUri.set(folder.uri, [ ...existingProjects, ...projectsForConfig, ]); } else { utilities_1.Debug.error(`Workspace failed to load config from: ${configFolder}/`); } }) .catch((error) => utilities_1.Debug.error(error))); await Promise.all(projectConfigs); if (this._onConfigFilesFound) { this._onConfigFilesFound(foundConfigs); } } reloadService() { this._projectForFileCache.clear(); this.projectsByFolderUri.forEach((projects, uri) => { this.projectsByFolderUri.set(uri, projects.map((project) => { project.clearAllDiagnostics(); return this.createProject({ config: project.config, folder: { uri }, }); })); }); } async reloadProjectForConfig(configUri) { const configPath = (0, path_1.dirname)(vscode_uri_1.default.parse(configUri).fsPath); let config, error; try { config = await (0, config_1.loadConfig)({ configPath, requireConfig: true }); } catch (e) { error = e; } const project = this.projectForFile(configUri); if (!config && this._onConfigFilesFound) { this._onConfigFilesFound(error); } if (project && config) { await Promise.all(project.updateConfig(config)); this.reloadService(); } if (!project && config) { const folderUri = vscode_uri_1.default.file(configPath).toString(); const newProject = this.createProject({ config, folder: { uri: folderUri }, }); const existingProjects = this.projectsByFolderUri.get(folderUri) || []; this.projectsByFolderUri.set(folderUri, [ ...existingProjects, newProject, ]); this.reloadService(); } } updateSchemaTag(selection) { const serviceID = selection.detail; if (!serviceID) return; this.projectsByFolderUri.forEach((projects) => { projects.forEach((project) => { if ((0, client_1.isClientProject)(project) && project.serviceID === serviceID) { project.updateSchemaTag(selection.label); } }); }); } removeProjectsInFolder(folder) { const projects = this.projectsByFolderUri.get(folder.uri); if (projects) { projects.forEach((project) => project.clearAllDiagnostics()); this.projectsByFolderUri.delete(folder.uri); } } get projects() { return Array.from(this.projectsByFolderUri.values()).flat(); } projectForFile(uri) { const cachedResult = this._projectForFileCache.get(uri); if (cachedResult) { return cachedResult; } for (const projects of this.projectsByFolderUri.values()) { const project = projects.find((project) => project.includesFile(uri)); if (project) { this._projectForFileCache.set(uri, project); return project; } } return undefined; } } exports.GraphQLWorkspace = GraphQLWorkspace; //# sourceMappingURL=workspace.js.map