UNPKG

7.75 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.GraphQLProject = void 0;
7const path_1 = require("path");
8const fs_1 = require("fs");
9const vscode_uri_1 = __importDefault(require("vscode-uri"));
10const graphql_1 = require("graphql");
11const vscode_languageserver_1 = require("vscode-languageserver");
12const document_1 = require("../document");
13const config_1 = require("../config");
14const schema_1 = require("../providers/schema");
15const engine_1 = require("../engine");
16const fileAssociations = {
17 ".graphql": "graphql",
18 ".gql": "graphql",
19 ".js": "javascript",
20 ".ts": "typescript",
21 ".jsx": "javascriptreact",
22 ".tsx": "typescriptreact",
23 ".vue": "vue",
24 ".py": "python",
25 ".rb": "ruby",
26 ".dart": "dart",
27 ".re": "reason",
28 ".ex": "elixir",
29 ".exs": "elixir"
30};
31class GraphQLProject {
32 constructor({ config, fileSet, loadingHandler, clientIdentity }) {
33 this.needsValidation = false;
34 this.documentsByFile = new Map();
35 this.config = config;
36 this.fileSet = fileSet;
37 this.loadingHandler = loadingHandler;
38 this.schemaProvider = schema_1.schemaProviderFromConfig(config, clientIdentity);
39 const { engine } = config;
40 if (engine.apiKey) {
41 this.engineClient = new engine_1.ApolloEngineClient(engine.apiKey, engine.endpoint, clientIdentity);
42 }
43 this._isReady = false;
44 this.readyPromise = Promise.all(this.initialize())
45 .then(() => {
46 this._isReady = true;
47 })
48 .catch(error => {
49 console.error(error);
50 this.loadingHandler.showError(`Error initializing Apollo GraphQL project "${this.displayName}": ${error}`);
51 });
52 }
53 get isReady() {
54 return this._isReady;
55 }
56 get engine() {
57 if (!this.engineClient) {
58 throw new Error(`Unable to find ${config_1.keyEnvVar}`);
59 }
60 return this.engineClient;
61 }
62 get whenReady() {
63 return this.readyPromise;
64 }
65 updateConfig(config) {
66 this.config = config;
67 return this.initialize();
68 }
69 resolveSchema(config) {
70 this.lastLoadDate = +new Date();
71 return this.schemaProvider.resolveSchema(config);
72 }
73 resolveFederatedServiceSDL() {
74 return this.schemaProvider.resolveFederatedServiceSDL();
75 }
76 onSchemaChange(handler) {
77 this.lastLoadDate = +new Date();
78 return this.schemaProvider.onSchemaChange(handler);
79 }
80 onDiagnostics(handler) {
81 this._onDiagnostics = handler;
82 }
83 includesFile(uri) {
84 return this.fileSet.includesFile(uri);
85 }
86 async scanAllIncludedFiles() {
87 await this.loadingHandler.handle(`Loading queries for ${this.displayName}`, (async () => {
88 for (const filePath of this.fileSet.allFiles()) {
89 const uri = vscode_uri_1.default.file(filePath).toString();
90 if (this.documentsByFile.has(uri))
91 continue;
92 this.fileDidChange(uri);
93 }
94 })());
95 }
96 fileDidChange(uri) {
97 const filePath = vscode_uri_1.default.parse(uri).fsPath;
98 const extension = path_1.extname(filePath);
99 const languageId = fileAssociations[extension];
100 if (!languageId)
101 return;
102 if (!fs_1.lstatSync(filePath).isFile())
103 return;
104 const contents = fs_1.readFileSync(filePath, "utf8");
105 const document = vscode_languageserver_1.TextDocument.create(uri, languageId, -1, contents);
106 this.documentDidChange(document);
107 }
108 fileWasDeleted(uri) {
109 this.removeGraphQLDocumentsFor(uri);
110 this.checkForDuplicateOperations();
111 }
112 documentDidChange(document) {
113 const documents = document_1.extractGraphQLDocuments(document, this.config.client && this.config.client.tagName);
114 if (documents) {
115 this.documentsByFile.set(document.uri, documents);
116 this.invalidate();
117 }
118 else {
119 this.removeGraphQLDocumentsFor(document.uri);
120 }
121 this.checkForDuplicateOperations();
122 }
123 checkForDuplicateOperations() {
124 const operations = Object.create(null);
125 for (const document of this.documents) {
126 if (!document.ast)
127 continue;
128 for (const definition of document.ast.definitions) {
129 if (definition.kind === graphql_1.Kind.OPERATION_DEFINITION && definition.name) {
130 if (operations[definition.name.value]) {
131 throw new Error(`️️There are multiple definitions for the \`${definition.name.value}\` operation. Please rename or remove all operations with the duplicated name before continuing.`);
132 }
133 operations[definition.name.value] = definition;
134 }
135 }
136 }
137 }
138 removeGraphQLDocumentsFor(uri) {
139 if (this.documentsByFile.has(uri)) {
140 this.documentsByFile.delete(uri);
141 if (this._onDiagnostics) {
142 this._onDiagnostics({ uri: uri, diagnostics: [] });
143 }
144 this.invalidate();
145 }
146 }
147 invalidate() {
148 if (!this.needsValidation && this.isReady) {
149 setTimeout(() => {
150 this.validateIfNeeded();
151 }, 0);
152 this.needsValidation = true;
153 }
154 }
155 validateIfNeeded() {
156 if (!this.needsValidation || !this.isReady)
157 return;
158 this.validate();
159 this.needsValidation = false;
160 }
161 clearAllDiagnostics() {
162 if (!this._onDiagnostics)
163 return;
164 for (const uri of this.documentsByFile.keys()) {
165 this._onDiagnostics({ uri, diagnostics: [] });
166 }
167 }
168 documentsAt(uri) {
169 return this.documentsByFile.get(uri);
170 }
171 documentAt(uri, position) {
172 const queryDocuments = this.documentsByFile.get(uri);
173 if (!queryDocuments)
174 return undefined;
175 return queryDocuments.find(document => document.containsPosition(position));
176 }
177 get documents() {
178 const documents = [];
179 for (const documentsForFile of this.documentsByFile.values()) {
180 documents.push(...documentsForFile);
181 }
182 return documents;
183 }
184 get definitions() {
185 const definitions = [];
186 for (const document of this.documents) {
187 if (!document.ast)
188 continue;
189 definitions.push(...document.ast.definitions);
190 }
191 return definitions;
192 }
193 definitionsAt(uri) {
194 const documents = this.documentsAt(uri);
195 if (!documents)
196 return [];
197 const definitions = [];
198 for (const document of documents) {
199 if (!document.ast)
200 continue;
201 definitions.push(...document.ast.definitions);
202 }
203 return definitions;
204 }
205 get typeSystemDefinitionsAndExtensions() {
206 const definitionsAndExtensions = [];
207 for (const document of this.documents) {
208 if (!document.ast)
209 continue;
210 for (const definition of document.ast.definitions) {
211 if (graphql_1.isTypeSystemDefinitionNode(definition) ||
212 graphql_1.isTypeSystemExtensionNode(definition)) {
213 definitionsAndExtensions.push(definition);
214 }
215 }
216 }
217 return definitionsAndExtensions;
218 }
219}
220exports.GraphQLProject = GraphQLProject;
221//# sourceMappingURL=base.js.map
\No newline at end of file