diff --git a/package.json b/package.json index 1a8c367c..1e2bc936 100644 --- a/package.json +++ b/package.json @@ -127,6 +127,12 @@ "default": true, "markdownDescription": "Show a \"Run in Studio\" button to the right of Operation Signatures.", "scope": "window" + }, + "apollographql.run.reloadServiceAfterLocalSchemaChanged": { + "type": "boolean", + "default": true, + "markdownDescription": "Reload service after local schema changed", + "scope": "window" } } }, diff --git a/src/extension.ts b/src/extension.ts index 529c2ed5..4f58d191 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -159,6 +159,19 @@ export function activate(context: ExtensionContext) { client.sendNotification("apollographql/reloadService"); }); + client.onNotification("apollographql/localSchemaChanged", (params) => { + if ( + workspace + .getConfiguration("apollographql") + .get("run.reloadServiceAfterLocalSchemaChanged") + ) { + client.outputChannel.appendLine("------------------------------"); + client.outputChannel.appendLine(`🚀 Apollo GraphQL Reload Service`); + client.outputChannel.appendLine("------------------------------"); + client.sendNotification("apollographql/reloadService"); + } + }); + // For some reason, non-strings can only be sent in one direction. For now, messages // coming from the language server just need to be stringified and parsed. client.onNotification("apollographql/tagsLoaded", (params) => { diff --git a/src/language-server/config/utils.ts b/src/language-server/config/utils.ts index 6b49d31c..da1eddf5 100644 --- a/src/language-server/config/utils.ts +++ b/src/language-server/config/utils.ts @@ -54,3 +54,7 @@ export function parseServiceSpecifier(specifier: ServiceSpecifier) { const [id, tag] = specifier.split("@").map((x) => x.trim()); return [id, tag] as ServiceIDAndTag; } + +export function getFileNameFromUri(uri: string) { + return uri.substring(uri.lastIndexOf("/") + 1); +} diff --git a/src/language-server/server.ts b/src/language-server/server.ts index e522da4f..6e9e50ac 100644 --- a/src/language-server/server.ts +++ b/src/language-server/server.ts @@ -152,6 +152,13 @@ connection.onDidChangeWatchedFiles((params) => { workspace.reloadProjectForConfig(uri); } + if (workspace.localSchemaChanged(uri)) { + connection.sendNotification( + "apollographql/localSchemaChanged", + undefined + ); + } + // Don't respond to changes in files that are currently open, // because we'll get content change notifications instead if (type === FileChangeType.Changed) { diff --git a/src/language-server/workspace.ts b/src/language-server/workspace.ts index c0c3ee6b..218f1bdf 100644 --- a/src/language-server/workspace.ts +++ b/src/language-server/workspace.ts @@ -3,7 +3,7 @@ import { NotificationHandler, PublishDiagnosticsParams, } from "vscode-languageserver"; -import { QuickPickItem } from "vscode"; +import { QuickPickItem, workspace } from "vscode"; import { GraphQLProject, DocumentUri } from "./project/base"; import { dirname } from "path"; import fg from "glob"; @@ -12,6 +12,7 @@ import { ApolloConfig, isClientConfig, ServiceConfig, + getFileNameFromUri, } from "./config"; import { LanguageServerLoadingHandler } from "./loadingHandler"; import { ServiceID, SchemaTag, ClientIdentity } from "./engine"; @@ -244,6 +245,25 @@ export class GraphQLWorkspace { return Array.from(this.projectsByFolderUri.values()).flat(); } + private getLocalSchemaFileNames(): string[] { + const localSchemaUris: string[] = []; + this.projects.forEach((p) => { + if (p.config.service?.localSchemaFile) { + if (typeof p.config.service.localSchemaFile === "string") { + localSchemaUris.push(p.config.service.localSchemaFile); + } else { + localSchemaUris.push(...p.config.service.localSchemaFile); + } + } + }); + return localSchemaUris.map((uri) => getFileNameFromUri(uri)); + } + + localSchemaChanged(uri: string): boolean { + const fileNames = this.getLocalSchemaFileNames(); + return fileNames.some((fileName) => uri.endsWith(fileName)) ? true : false; + } + projectForFile(uri: DocumentUri): GraphQLProject | undefined { const cachedResult = this._projectForFileCache.get(uri); if (cachedResult) { diff --git a/src/languageServerClient.ts b/src/languageServerClient.ts index b731ce3b..637d20af 100644 --- a/src/languageServerClient.ts +++ b/src/languageServerClient.ts @@ -54,12 +54,13 @@ export function getLanguageServerClient( "dart", "reason", "elixir", + "json", ], synchronize: { fileEvents: [ workspace.createFileSystemWatcher("**/.env?(.local)"), workspace.createFileSystemWatcher( - "**/*.{graphql,js,ts,jsx,tsx,vue,svelte,py,rb,dart,re,ex,exs}" + "**/*.{graphql,js,ts,jsx,tsx,vue,svelte,py,rb,dart,re,ex,exs,json}" ), ], }, diff --git a/src/messages.ts b/src/messages.ts index 0f57a499..fa15c6d1 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -47,6 +47,7 @@ type Messages = { "apollographql/loadingComplete": number; "apollographql/loading": { message: string; token: number }; "apollographql/engineDecorations": { decorations: EngineDecoration[] }; + "apollographql/localSchemaChanged": undefined; serverDebugMessage: { type: "info" | "warning" | "error" | "errorTelemetry"; message: string;