vscode-apollo 1.20.0 → 2.0.1

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.
Files changed (109) hide show
  1. package/.circleci/config.yml +27 -18
  2. package/.git-blame-ignore-revs +2 -0
  3. package/.nvmrc +1 -1
  4. package/.vscode/launch.json +9 -4
  5. package/.vscode/tasks.json +58 -16
  6. package/.vscodeignore +12 -1
  7. package/CHANGELOG.md +84 -0
  8. package/CODEOWNERS +4 -0
  9. package/README.md +97 -48
  10. package/graphql.configuration.json +5 -1
  11. package/images/marketplace/apollo-wordmark.png +0 -0
  12. package/jest.config.ts +14 -4
  13. package/jest.e2e.config.js +17 -0
  14. package/package.json +67 -68
  15. package/renovate.json +7 -0
  16. package/sampleWorkspace/clientSchema/apollo.config.cjs +10 -0
  17. package/sampleWorkspace/clientSchema/src/clientSchema.js +16 -0
  18. package/sampleWorkspace/clientSchema/src/test.js +18 -0
  19. package/sampleWorkspace/fixtures/starwarsSchema.graphql +299 -0
  20. package/sampleWorkspace/httpSchema/apollo.config.ts +8 -0
  21. package/sampleWorkspace/httpSchema/src/test.js +9 -0
  22. package/sampleWorkspace/localSchema/apollo.config.js +8 -0
  23. package/sampleWorkspace/localSchema/src/test.js +8 -0
  24. package/sampleWorkspace/localSchemaArray/apollo.config.js +12 -0
  25. package/sampleWorkspace/localSchemaArray/planets.graphql +20 -0
  26. package/sampleWorkspace/localSchemaArray/src/test.js +12 -0
  27. package/sampleWorkspace/sampleWorkspace.code-workspace +20 -0
  28. package/sampleWorkspace/spotifyGraph/apollo.config.mjs +5 -0
  29. package/sampleWorkspace/spotifyGraph/src/test.js +11 -0
  30. package/src/__e2e__/mockServer.js +117 -0
  31. package/src/__e2e__/mocks.js +13094 -0
  32. package/src/__e2e__/run.js +23 -0
  33. package/src/__e2e__/runTests.js +44 -0
  34. package/src/__e2e__/setup.js +1 -0
  35. package/src/__e2e__/vscode-environment.js +16 -0
  36. package/src/__e2e__/vscode.js +1 -0
  37. package/src/build.js +57 -0
  38. package/src/env/index.ts +0 -3
  39. package/src/extension.ts +251 -225
  40. package/src/language-server/__e2e__/clientSchema.e2e.ts +147 -0
  41. package/src/language-server/__e2e__/httpSchema.e2e.ts +21 -0
  42. package/src/language-server/__e2e__/localSchema.e2e.ts +25 -0
  43. package/src/language-server/__e2e__/localSchemaArray.e2e.ts +31 -0
  44. package/src/language-server/__e2e__/studioGraph.e2e.ts +65 -0
  45. package/src/language-server/__e2e__/utils.ts +151 -0
  46. package/src/language-server/__tests__/diagnostics.test.ts +8 -8
  47. package/src/language-server/__tests__/fileSet.test.ts +1 -1
  48. package/src/language-server/__tests__/fixtures/starwarsSchema.ts +2 -2
  49. package/src/language-server/config/__tests__/config.ts +22 -96
  50. package/src/language-server/config/__tests__/loadConfig.ts +120 -220
  51. package/src/language-server/config/__tests__/utils.ts +22 -29
  52. package/src/language-server/config/config.ts +221 -156
  53. package/src/language-server/config/loadConfig.ts +32 -153
  54. package/src/language-server/config/loadTsConfig.ts +70 -0
  55. package/src/language-server/config/utils.ts +5 -16
  56. package/src/language-server/diagnostics.ts +17 -8
  57. package/src/language-server/document.ts +16 -16
  58. package/src/language-server/engine/index.ts +57 -39
  59. package/src/language-server/engine/operations/frontendUrlRoot.ts +9 -1
  60. package/src/language-server/engine/operations/schemaTagsAndFieldStats.ts +9 -1
  61. package/src/language-server/errors/__tests__/NoMissingClientDirectives.test.ts +10 -5
  62. package/src/language-server/errors/logger.ts +1 -1
  63. package/src/language-server/errors/validation.ts +20 -23
  64. package/src/language-server/fileSet.ts +10 -12
  65. package/src/language-server/format.ts +1 -1
  66. package/src/language-server/graphqlTypes.ts +13020 -3455
  67. package/src/language-server/index.ts +0 -1
  68. package/src/language-server/languageProvider.ts +29 -32
  69. package/src/language-server/loadingHandler.ts +10 -27
  70. package/src/language-server/project/base.ts +32 -25
  71. package/src/language-server/project/client.ts +80 -114
  72. package/src/language-server/project/defaultClientSchema.ts +29 -4
  73. package/src/language-server/providers/schema/__tests__/file.ts +60 -19
  74. package/src/language-server/providers/schema/base.ts +2 -2
  75. package/src/language-server/providers/schema/endpoint.ts +15 -34
  76. package/src/language-server/providers/schema/engine.ts +25 -18
  77. package/src/language-server/providers/schema/file.ts +41 -32
  78. package/src/language-server/providers/schema/index.ts +5 -21
  79. package/src/language-server/server.ts +72 -50
  80. package/src/language-server/typings/graphql.d.ts +3 -3
  81. package/src/language-server/utilities/__tests__/graphql.test.ts +42 -54
  82. package/src/language-server/utilities/debouncer.ts +1 -1
  83. package/src/language-server/utilities/debug.ts +6 -5
  84. package/src/language-server/utilities/graphql.ts +17 -16
  85. package/src/language-server/utilities/source.ts +16 -16
  86. package/src/language-server/utilities/uri.ts +2 -2
  87. package/src/language-server/workspace.ts +29 -37
  88. package/src/languageServerClient.ts +4 -4
  89. package/src/messages.ts +38 -47
  90. package/src/tools/__tests__/buildServiceDefinition.test.ts +2 -2
  91. package/src/tools/buildServiceDefinition.ts +11 -11
  92. package/src/tools/schema/resolveObject.ts +1 -1
  93. package/src/tools/utilities/predicates.ts +1 -1
  94. package/src/utils.ts +7 -6
  95. package/syntaxes/graphql.dart.json +2 -4
  96. package/syntaxes/graphql.ex.json +1 -4
  97. package/tsconfig.build.json +8 -1
  98. package/tsconfig.json +5 -3
  99. package/src/env/fetch/fetch.ts +0 -32
  100. package/src/env/fetch/global.ts +0 -30
  101. package/src/env/fetch/index.d.ts +0 -2
  102. package/src/env/fetch/index.ts +0 -2
  103. package/src/env/fetch/url.ts +0 -9
  104. package/src/env/polyfills/array.ts +0 -17
  105. package/src/env/polyfills/index.ts +0 -2
  106. package/src/env/polyfills/object.ts +0 -7
  107. package/src/language-server/engine/GraphQLDataSource.ts +0 -124
  108. package/src/language-server/project/service.ts +0 -48
  109. package/src/language-server/typings/codemirror.d.ts +0 -4
@@ -1,18 +1,21 @@
1
1
  // EngineSchemaProvider (engine schema reg => schema)
2
- import { NotificationHandler } from "vscode-languageserver";
2
+ import { NotificationHandler } from "vscode-languageserver/node";
3
3
  import gql from "graphql-tag";
4
- import { GraphQLSchema, buildClientSchema } from "graphql";
4
+ import { GraphQLSchema, IntrospectionQuery, buildClientSchema } from "graphql";
5
5
  import { ApolloEngineClient, ClientIdentity } from "../../engine";
6
- import { ClientConfig, keyEnvVar, parseServiceSpecifier } from "../../config";
7
- import { getServiceFromKey, isServiceKey } from "../../config";
6
+ import { ClientConfig, keyEnvVar } from "../../config";
8
7
  import {
9
8
  GraphQLSchemaProvider,
10
9
  SchemaChangeUnsubscribeHandler,
11
10
  SchemaResolveConfig,
12
11
  } from "./base";
13
12
 
14
- import { GetSchemaByTagQuery } from "../../graphqlTypes";
13
+ import {
14
+ GetSchemaByTagQuery,
15
+ GetSchemaByTagQueryVariables,
16
+ } from "../../graphqlTypes";
15
17
  import { Debug } from "../../utilities";
18
+ import { TypedDocumentNode } from "@apollo/client/core";
16
19
 
17
20
  export class EngineSchemaProvider implements GraphQLSchemaProvider {
18
21
  private schema?: GraphQLSchema;
@@ -20,7 +23,7 @@ export class EngineSchemaProvider implements GraphQLSchemaProvider {
20
23
 
21
24
  constructor(
22
25
  private config: ClientConfig,
23
- private clientIdentity?: ClientIdentity
26
+ private clientIdentity: ClientIdentity,
24
27
  ) {}
25
28
 
26
29
  async resolveSchema(override: SchemaResolveConfig) {
@@ -29,7 +32,7 @@ export class EngineSchemaProvider implements GraphQLSchemaProvider {
29
32
 
30
33
  if (!this.config.graph) {
31
34
  throw new Error(
32
- `No graph ID found for client. Please specify a graph ID via the config or the --graph flag`
35
+ `No graph ID found for client. Please specify a graph ID via the config or the --graph flag`,
33
36
  );
34
37
  }
35
38
 
@@ -37,42 +40,43 @@ export class EngineSchemaProvider implements GraphQLSchemaProvider {
37
40
  if (!this.client) {
38
41
  if (!engine.apiKey) {
39
42
  throw new Error(
40
- `No API key found. Please set ${keyEnvVar} or use --key`
43
+ `No API key found. Please set ${keyEnvVar} or use --key`,
41
44
  );
42
45
  }
43
46
  this.client = new ApolloEngineClient(
44
47
  engine.apiKey,
45
48
  engine.endpoint,
46
- this.clientIdentity
49
+ this.clientIdentity,
47
50
  );
48
51
  }
49
52
 
50
- const { data, errors } = await this.client.execute<GetSchemaByTagQuery>({
53
+ const { data, errors } = await this.client.query({
51
54
  query: SCHEMA_QUERY,
52
55
  variables: {
53
56
  id: this.config.graph,
54
57
  tag: override && override.tag ? override.tag : this.config.variant,
55
58
  },
59
+ fetchPolicy: "no-cache",
56
60
  });
57
61
  if (errors) {
58
62
  // XXX better error handling of GraphQL errors
59
- throw new Error(errors.map(({ message }: Error) => message).join("\n"));
63
+ throw new Error(errors.map(({ message }) => message).join("\n"));
60
64
  }
61
65
 
62
66
  if (!(data && data.service && data.service.__typename === "Service")) {
63
67
  throw new Error(
64
- `Unable to get schema from the Apollo registry for graph ${this.config.graph}`
68
+ `Unable to get schema from the Apollo registry for graph ${this.config.graph}`,
65
69
  );
66
70
  }
67
71
 
68
- // @ts-ignore
69
- // XXX Types of `data.service.schema` won't match closely enough with `IntrospectionQuery`
70
- this.schema = buildClientSchema(data.service.schema);
72
+ this.schema = buildClientSchema(
73
+ data.service.schema as unknown as IntrospectionQuery,
74
+ );
71
75
  return this.schema;
72
76
  }
73
77
 
74
78
  onSchemaChange(
75
- _handler: NotificationHandler<GraphQLSchema>
79
+ _handler: NotificationHandler<GraphQLSchema>,
76
80
  ): SchemaChangeUnsubscribeHandler {
77
81
  throw new Error("Polling of Apollo not implemented yet");
78
82
  return () => {};
@@ -80,13 +84,16 @@ export class EngineSchemaProvider implements GraphQLSchemaProvider {
80
84
 
81
85
  async resolveFederatedServiceSDL() {
82
86
  Debug.error(
83
- "Cannot resolve a federated service's SDL from Apollo. Use an endpoint or a file instead"
87
+ "Cannot resolve a federated service's SDL from Apollo. Use an endpoint or a file instead",
84
88
  );
85
89
  return;
86
90
  }
87
91
  }
88
92
 
89
- export const SCHEMA_QUERY = gql`
93
+ export const SCHEMA_QUERY: TypedDocumentNode<
94
+ GetSchemaByTagQuery,
95
+ GetSchemaByTagQueryVariables
96
+ > = gql`
90
97
  query GetSchemaByTag($tag: String!, $id: ID!) {
91
98
  service(id: $id) {
92
99
  ... on Service {
@@ -3,23 +3,18 @@ import {
3
3
  GraphQLSchema,
4
4
  buildClientSchema,
5
5
  Source,
6
- buildSchema,
7
6
  printSchema,
8
7
  parse,
9
- visit,
8
+ buildASTSchema,
10
9
  } from "graphql";
11
- import { readFileSync } from "fs";
12
- import { extname, resolve } from "path";
10
+ import { mergeTypeDefs } from "@graphql-tools/merge";
11
+ import { existsSync, readFileSync } from "fs";
12
+ import { extname, resolve, isAbsolute } from "path";
13
13
  import { GraphQLSchemaProvider, SchemaChangeUnsubscribeHandler } from "./base";
14
- import { NotificationHandler } from "vscode-languageserver";
14
+ import { NotificationHandler } from "vscode-languageserver/node";
15
15
  import { Debug } from "../../utilities";
16
- import { buildSchemaFromSDL } from "apollo-graphql";
17
- import {
18
- buildFederatedSchema,
19
- composeServices,
20
- printSchema as printFederatedSchema,
21
- } from "@apollo/federation";
22
- import URI from "vscode-uri";
16
+ import { buildSubgraphSchema } from "@apollo/subgraph";
17
+ import { URI } from "vscode-uri";
23
18
  // import federationDirectives from "@apollo/federation/src/directives";
24
19
 
25
20
  export interface FileSchemaProviderConfig {
@@ -31,7 +26,10 @@ export class FileSchemaProvider implements GraphQLSchemaProvider {
31
26
  private schema?: GraphQLSchema;
32
27
  private federatedServiceSDL?: string;
33
28
 
34
- constructor(private config: FileSchemaProviderConfig) {}
29
+ constructor(
30
+ private config: FileSchemaProviderConfig,
31
+ private configDir: URI | undefined,
32
+ ) {}
35
33
 
36
34
  async resolveSchema() {
37
35
  if (this.schema) return this.schema;
@@ -48,10 +46,10 @@ export class FileSchemaProvider implements GraphQLSchemaProvider {
48
46
  throw new Error(
49
47
  `Schema could not be loaded for [${
50
48
  path ? path : paths ? paths.join(", ") : "undefined"
51
- }]`
49
+ }]`,
52
50
  );
53
51
 
54
- this.schema = buildSchemaFromSDL(documents);
52
+ this.schema = buildASTSchema(mergeTypeDefs(documents));
55
53
 
56
54
  if (!this.schema) throw new Error(`Schema could not be loaded for ${path}`);
57
55
  return this.schema;
@@ -62,9 +60,7 @@ export class FileSchemaProvider implements GraphQLSchemaProvider {
62
60
  loadFileAndGetDocument(path: string) {
63
61
  let result;
64
62
  try {
65
- result = readFileSync(path, {
66
- encoding: "utf-8",
67
- });
63
+ result = this.readFileSync(path);
68
64
  } catch (err: any) {
69
65
  throw new Error(`Unable to read file ${path}. ${err.message}`);
70
66
  }
@@ -87,12 +83,12 @@ export class FileSchemaProvider implements GraphQLSchemaProvider {
87
83
  return parse(new Source(result, uri));
88
84
  }
89
85
  throw new Error(
90
- "File Type not supported for schema loading. Must be a .json, .graphql, .gql, or .graphqls file"
86
+ "File Type not supported for schema loading. Must be a .json, .graphql, .gql, or .graphqls file",
91
87
  );
92
88
  }
93
89
 
94
90
  onSchemaChange(
95
- _handler: NotificationHandler<GraphQLSchema>
91
+ _handler: NotificationHandler<GraphQLSchema>,
96
92
  ): SchemaChangeUnsubscribeHandler {
97
93
  throw new Error("File watching not implemented yet");
98
94
  return () => {};
@@ -116,11 +112,11 @@ export class FileSchemaProvider implements GraphQLSchemaProvider {
116
112
  return Debug.error(
117
113
  `SDL could not be loaded for one of more files: [${
118
114
  path ? path : paths ? paths.join(", ") : "undefined"
119
- }]`
115
+ }]`,
120
116
  );
121
117
 
122
- const federatedSchema = buildFederatedSchema(
123
- SDLs.map((sdl) => ({ typeDefs: parse(sdl as string) }))
118
+ const federatedSchema = buildSubgraphSchema(
119
+ SDLs.map((sdl) => ({ typeDefs: parse(sdl as string) })),
124
120
  );
125
121
 
126
122
  // call the `Query._service` resolver to get the actual printed sdl
@@ -128,14 +124,16 @@ export class FileSchemaProvider implements GraphQLSchemaProvider {
128
124
  if (!queryType)
129
125
  return Debug.error("No query type found for federated schema");
130
126
  const serviceField = queryType.getFields()["_service"];
131
- const serviceResults =
132
- serviceField &&
133
- serviceField.resolve &&
134
- serviceField.resolve(null, {}, null, {} as any);
127
+ const serviceResults = serviceField?.resolve?.(
128
+ null,
129
+ {},
130
+ null,
131
+ {} as any,
132
+ ) as { sdl?: string };
135
133
 
136
134
  if (!serviceResults || !serviceResults.sdl)
137
135
  return Debug.error(
138
- "No SDL resolver or result from federated schema after building"
136
+ "No SDL resolver or result from federated schema after building",
139
137
  );
140
138
 
141
139
  this.federatedServiceSDL = serviceResults.sdl;
@@ -146,9 +144,7 @@ export class FileSchemaProvider implements GraphQLSchemaProvider {
146
144
  loadFileAndGetSDL(path: string) {
147
145
  let result;
148
146
  try {
149
- result = readFileSync(path, {
150
- encoding: "utf-8",
151
- });
147
+ result = this.readFileSync(path);
152
148
  } catch (err: any) {
153
149
  return Debug.error(`Unable to read file ${path}. ${err.message}`);
154
150
  }
@@ -160,8 +156,21 @@ export class FileSchemaProvider implements GraphQLSchemaProvider {
160
156
  return result as string;
161
157
  } else {
162
158
  return Debug.error(
163
- "When using localSchemaFile to check or push a federated service, you can only use .graphql, .gql, and .graphqls files"
159
+ "When using localSchemaFile to check or push a federated service, you can only use .graphql, .gql, and .graphqls files",
164
160
  );
165
161
  }
166
162
  }
163
+
164
+ private readFileSync(path: string) {
165
+ let finalPath = path;
166
+ if (!isAbsolute(finalPath) && this.configDir) {
167
+ const resolvedPath = resolve(this.configDir?.fsPath, path);
168
+ if (existsSync(resolvedPath)) {
169
+ finalPath = resolvedPath;
170
+ }
171
+ }
172
+ return readFileSync(finalPath, {
173
+ encoding: "utf-8",
174
+ });
175
+ }
167
176
  }
@@ -6,7 +6,6 @@ import {
6
6
  import {
7
7
  ApolloConfig,
8
8
  isClientConfig,
9
- isServiceConfig,
10
9
  isLocalServiceConfig,
11
10
  ClientConfig,
12
11
  } from "../../config";
@@ -24,24 +23,8 @@ export {
24
23
 
25
24
  export function schemaProviderFromConfig(
26
25
  config: ApolloConfig,
27
- clientIdentity?: ClientIdentity // engine provider needs this
26
+ clientIdentity: ClientIdentity, // engine provider needs this
28
27
  ): GraphQLSchemaProvider {
29
- // we need this to be first because there will pretty much always be a
30
- // url (since it's a default). If there is a localSchemaFile, we need to
31
- // use that instead of the url.
32
- if (config.service && config.service.localSchemaFile) {
33
- const isListOfSchemaFiles = Array.isArray(config.service.localSchemaFile);
34
- return new FileSchemaProvider(
35
- isListOfSchemaFiles
36
- ? { paths: config.service.localSchemaFile as string[] }
37
- : { path: config.service.localSchemaFile as string }
38
- );
39
- }
40
-
41
- if (config.service && config.service.endpoint) {
42
- return new EndpointSchemaProvider(config.service.endpoint);
43
- }
44
-
45
28
  if (isClientConfig(config)) {
46
29
  if (typeof config.client.service === "string") {
47
30
  return new EngineSchemaProvider(config, clientIdentity);
@@ -50,14 +33,15 @@ export function schemaProviderFromConfig(
50
33
  if (config.client.service) {
51
34
  if (isLocalServiceConfig(config.client.service)) {
52
35
  const isListOfSchemaFiles = Array.isArray(
53
- config.client.service.localSchemaFile
36
+ config.client.service.localSchemaFile,
54
37
  );
55
38
  return new FileSchemaProvider(
56
39
  isListOfSchemaFiles
57
40
  ? { paths: config.client.service.localSchemaFile as string[] }
58
41
  : {
59
42
  path: config.client.service.localSchemaFile as string,
60
- }
43
+ },
44
+ config.configDirURI,
61
45
  );
62
46
  }
63
47
 
@@ -70,6 +54,6 @@ export function schemaProviderFromConfig(
70
54
  }
71
55
 
72
56
  throw new Error(
73
- "No schema provider was created, because the project type was unable to be resolved from your config. Please add either a client or service config. For more information, please refer to https://go.apollo.dev/t/config"
57
+ "No schema provider was created, because the project type was unable to be resolved from your config. Please add either a client or service config. For more information, please refer to https://go.apollo.dev/t/config",
74
58
  );
75
59
  }
@@ -1,41 +1,57 @@
1
1
  import "../env";
2
- // FIXME: The global fetch dependency comes from `apollo-link-http` and should be removed there.
3
- import "../env/fetch/global";
4
2
  import {
5
3
  createConnection,
6
4
  ProposedFeatures,
7
5
  TextDocuments,
8
6
  FileChangeType,
9
7
  ServerCapabilities,
10
- } from "vscode-languageserver";
8
+ TextDocumentSyncKind,
9
+ } from "vscode-languageserver/node";
10
+ import { TextDocument } from "vscode-languageserver-textdocument";
11
11
  import type { QuickPickItem } from "vscode";
12
12
  import { GraphQLWorkspace } from "./workspace";
13
13
  import { GraphQLLanguageProvider } from "./languageProvider";
14
14
  import { LanguageServerLoadingHandler } from "./loadingHandler";
15
15
  import { debounceHandler, Debug } from "./utilities";
16
- import type { Connection } from "src/messages";
17
- import URI from "vscode-uri";
16
+ import { URI } from "vscode-uri";
17
+ import {
18
+ LanguageServerNotifications as Notifications,
19
+ LanguageServerCommands as Commands,
20
+ LanguageServerRequests as Requests,
21
+ } from "../messages";
22
+ import { isValidationError } from "zod-validation-error";
23
+
24
+ const connection = createConnection(ProposedFeatures.all);
18
25
 
19
- const connection: Connection = createConnection(ProposedFeatures.all);
20
26
  Debug.SetConnection(connection);
27
+ const { sendNotification: originalSendNotification } = connection;
28
+ connection.sendNotification = async (...args: [any, ...any[]]) => {
29
+ await whenConnectionInitialized;
30
+ connection.sendNotification = originalSendNotification;
31
+ connection.sendNotification(...args);
32
+ };
21
33
 
22
34
  let hasWorkspaceFolderCapability = false;
23
35
 
24
36
  // Awaitable promise for sending messages before the connection is initialized
25
37
  let initializeConnection: () => void;
26
38
  const whenConnectionInitialized: Promise<void> = new Promise(
27
- (resolve) => (initializeConnection = resolve)
39
+ (resolve) => (initializeConnection = resolve),
28
40
  );
29
41
 
30
42
  const workspace = new GraphQLWorkspace(
31
43
  new LanguageServerLoadingHandler(connection),
32
44
  {
33
45
  clientIdentity: {
34
- name: process.env["APOLLO_CLIENT_NAME"],
35
- version: process.env["APOLLO_CLIENT_VERSION"],
36
- referenceID: process.env["APOLLO_CLIENT_REFERENCE_ID"],
46
+ name: process.env["APOLLO_CLIENT_NAME"] || "Apollo Language Server",
47
+ version:
48
+ process.env["APOLLO_CLIENT_VERSION"] ||
49
+ "146d29c0-912c-46d3-b686-920e52586be6",
50
+ referenceID:
51
+ process.env["APOLLO_CLIENT_REFERENCE_ID"] ||
52
+ require("../../package.json").version,
37
53
  },
38
- }
54
+ },
39
55
  );
40
56
 
41
57
  workspace.onDiagnostics((params) => {
@@ -43,27 +59,25 @@ workspace.onDiagnostics((params) => {
43
59
  });
44
60
 
45
61
  workspace.onDecorations((params) => {
46
- connection.sendNotification("apollographql/engineDecorations", {
62
+ connection.sendNotification(Notifications.EngineDecorations, {
47
63
  decorations: params,
48
64
  });
49
65
  });
50
66
 
51
67
  workspace.onSchemaTags((params) => {
52
- connection.sendNotification(
53
- "apollographql/tagsLoaded",
54
- JSON.stringify(params)
55
- );
68
+ connection.sendNotification(Notifications.TagsLoaded, JSON.stringify(params));
56
69
  });
57
70
 
58
71
  workspace.onConfigFilesFound(async (params) => {
59
- await whenConnectionInitialized;
60
-
61
72
  connection.sendNotification(
62
- "apollographql/configFilesFound",
63
- params instanceof Error
64
- ? // Can't stringify Errors, just results in "{}"
65
- JSON.stringify({ message: params.message, stack: params.stack })
66
- : JSON.stringify(params)
73
+ Notifications.ConfigFilesFound,
74
+ JSON.stringify(params, (_key, value) =>
75
+ !value
76
+ ? value
77
+ : value instanceof Error || isValidationError(value)
78
+ ? { message: value.message, stack: value.stack }
79
+ : value,
80
+ ),
67
81
  );
68
82
  });
69
83
 
@@ -77,7 +91,7 @@ connection.onInitialize(async ({ capabilities, workspaceFolders }) => {
77
91
  // like `textDocument/codeLens`, and that way these can await `GraphQLProject#whenReady` to make sure
78
92
  // we provide them eventually.
79
93
  await Promise.all(
80
- workspaceFolders.map((folder) => workspace.addProjectsInFolder(folder))
94
+ workspaceFolders.map((folder) => workspace.addProjectsInFolder(folder)),
81
95
  );
82
96
  }
83
97
 
@@ -99,7 +113,7 @@ connection.onInitialize(async ({ capabilities, workspaceFolders }) => {
99
113
  executeCommandProvider: {
100
114
  commands: [],
101
115
  },
102
- textDocumentSync: documents.syncKind,
116
+ textDocumentSync: TextDocumentSyncKind.Full,
103
117
  } as ServerCapabilities,
104
118
  };
105
119
  });
@@ -110,7 +124,7 @@ connection.onInitialized(async () => {
110
124
  connection.workspace.onDidChangeWorkspaceFolders(async (event) => {
111
125
  await Promise.all([
112
126
  ...event.removed.map((folder) =>
113
- workspace.removeProjectsInFolder(folder)
127
+ workspace.removeProjectsInFolder(folder),
114
128
  ),
115
129
  ...event.added.map((folder) => workspace.addProjectsInFolder(folder)),
116
130
  ]);
@@ -118,7 +132,7 @@ connection.onInitialized(async () => {
118
132
  }
119
133
  });
120
134
 
121
- const documents: TextDocuments = new TextDocuments();
135
+ const documents = new TextDocuments(TextDocument);
122
136
 
123
137
  // Make the text document manager listen on the connection
124
138
  // for open, change and close text document events
@@ -139,7 +153,7 @@ documents.onDidChangeContent(
139
153
  }
140
154
 
141
155
  project.documentDidChange(params.document);
142
- })
156
+ }),
143
157
  );
144
158
 
145
159
  connection.onDidChangeWatchedFiles((params) => {
@@ -147,6 +161,8 @@ connection.onDidChangeWatchedFiles((params) => {
147
161
  if (
148
162
  uri.endsWith("apollo.config.js") ||
149
163
  uri.endsWith("apollo.config.cjs") ||
164
+ uri.endsWith("apollo.config.mjs") ||
165
+ uri.endsWith("apollo.config.ts") ||
150
166
  uri.endsWith(".env")
151
167
  ) {
152
168
  workspace.reloadProjectForConfig(uri);
@@ -180,15 +196,19 @@ connection.onDidChangeWatchedFiles((params) => {
180
196
  const languageProvider = new GraphQLLanguageProvider(workspace);
181
197
 
182
198
  connection.onHover((params, token) =>
183
- languageProvider.provideHover(params.textDocument.uri, params.position, token)
199
+ languageProvider.provideHover(
200
+ params.textDocument.uri,
201
+ params.position,
202
+ token,
203
+ ),
184
204
  );
185
205
 
186
206
  connection.onDefinition((params, token) =>
187
207
  languageProvider.provideDefinition(
188
208
  params.textDocument.uri,
189
209
  params.position,
190
- token
191
- )
210
+ token,
211
+ ),
192
212
  );
193
213
 
194
214
  connection.onReferences((params, token) =>
@@ -196,16 +216,16 @@ connection.onReferences((params, token) =>
196
216
  params.textDocument.uri,
197
217
  params.position,
198
218
  params.context,
199
- token
200
- )
219
+ token,
220
+ ),
201
221
  );
202
222
 
203
223
  connection.onDocumentSymbol((params, token) =>
204
- languageProvider.provideDocumentSymbol(params.textDocument.uri, token)
224
+ languageProvider.provideDocumentSymbol(params.textDocument.uri, token),
205
225
  );
206
226
 
207
227
  connection.onWorkspaceSymbol((params, token) =>
208
- languageProvider.provideWorkspaceSymbol(params.query, token)
228
+ languageProvider.provideWorkspaceSymbol(params.query, token),
209
229
  );
210
230
 
211
231
  connection.onCompletion(
@@ -213,15 +233,15 @@ connection.onCompletion(
213
233
  languageProvider.provideCompletionItems(
214
234
  params.textDocument.uri,
215
235
  params.position,
216
- token
217
- )
218
- )
236
+ token,
237
+ ),
238
+ ),
219
239
  );
220
240
 
221
241
  connection.onCodeLens(
222
242
  debounceHandler((params, token) =>
223
- languageProvider.provideCodeLenses(params.textDocument.uri, token)
224
- )
243
+ languageProvider.provideCodeLenses(params.textDocument.uri, token),
244
+ ),
225
245
  );
226
246
 
227
247
  connection.onCodeAction(
@@ -229,23 +249,25 @@ connection.onCodeAction(
229
249
  languageProvider.provideCodeAction(
230
250
  params.textDocument.uri,
231
251
  params.range,
232
- token
233
- )
234
- )
252
+ token,
253
+ ),
254
+ ),
235
255
  );
236
256
 
237
- connection.onNotification("apollographql/reloadService", () =>
238
- workspace.reloadService()
257
+ connection.onNotification(Commands.ReloadService, () =>
258
+ workspace.reloadService(),
239
259
  );
240
260
 
241
- connection.onNotification(
242
- "apollographql/tagSelected",
243
- (selection: QuickPickItem) => workspace.updateSchemaTag(selection)
261
+ connection.onNotification(Commands.TagSelected, (selection: QuickPickItem) =>
262
+ workspace.updateSchemaTag(selection),
244
263
  );
245
264
 
246
- connection.onNotification("apollographql/getStats", async ({ uri }) => {
265
+ connection.onNotification(Commands.GetStats, async ({ uri }) => {
247
266
  const status = await languageProvider.provideStats(uri);
248
- connection.sendNotification("apollographql/statsLoaded", status);
267
+ connection.sendNotification(Notifications.StatsLoaded, status);
268
+ });
269
+ connection.onRequest(Requests.FileStats, async ({ uri }) => {
270
+ return languageProvider.provideStats(uri);
249
271
  });
250
272
 
251
273
  // Listen on the connection
@@ -10,13 +10,13 @@ import {
10
10
  // to `@types/graphql`.
11
11
  declare module "graphql/language/predicates" {
12
12
  function isExecutableDefinitionNode(
13
- node: ASTNode
13
+ node: ASTNode,
14
14
  ): node is OperationDefinitionNode | FragmentDefinitionNode;
15
15
  function isTypeSystemDefinitionNode(
16
- node: ASTNode
16
+ node: ASTNode,
17
17
  ): node is TypeSystemDefinitionNode;
18
18
  function isTypeSystemExtensionNode(
19
- node: ASTNode
19
+ node: ASTNode,
20
20
  ): node is TypeSystemExtensionNode;
21
21
  }
22
22