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.
- package/.circleci/config.yml +27 -18
- package/.git-blame-ignore-revs +2 -0
- package/.nvmrc +1 -1
- package/.vscode/launch.json +9 -4
- package/.vscode/tasks.json +58 -16
- package/.vscodeignore +12 -1
- package/CHANGELOG.md +84 -0
- package/CODEOWNERS +4 -0
- package/README.md +97 -48
- package/graphql.configuration.json +5 -1
- package/images/marketplace/apollo-wordmark.png +0 -0
- package/jest.config.ts +14 -4
- package/jest.e2e.config.js +17 -0
- package/package.json +67 -68
- package/renovate.json +7 -0
- package/sampleWorkspace/clientSchema/apollo.config.cjs +10 -0
- package/sampleWorkspace/clientSchema/src/clientSchema.js +16 -0
- package/sampleWorkspace/clientSchema/src/test.js +18 -0
- package/sampleWorkspace/fixtures/starwarsSchema.graphql +299 -0
- package/sampleWorkspace/httpSchema/apollo.config.ts +8 -0
- package/sampleWorkspace/httpSchema/src/test.js +9 -0
- package/sampleWorkspace/localSchema/apollo.config.js +8 -0
- package/sampleWorkspace/localSchema/src/test.js +8 -0
- package/sampleWorkspace/localSchemaArray/apollo.config.js +12 -0
- package/sampleWorkspace/localSchemaArray/planets.graphql +20 -0
- package/sampleWorkspace/localSchemaArray/src/test.js +12 -0
- package/sampleWorkspace/sampleWorkspace.code-workspace +20 -0
- package/sampleWorkspace/spotifyGraph/apollo.config.mjs +5 -0
- package/sampleWorkspace/spotifyGraph/src/test.js +11 -0
- package/src/__e2e__/mockServer.js +117 -0
- package/src/__e2e__/mocks.js +13094 -0
- package/src/__e2e__/run.js +23 -0
- package/src/__e2e__/runTests.js +44 -0
- package/src/__e2e__/setup.js +1 -0
- package/src/__e2e__/vscode-environment.js +16 -0
- package/src/__e2e__/vscode.js +1 -0
- package/src/build.js +57 -0
- package/src/env/index.ts +0 -3
- package/src/extension.ts +251 -225
- package/src/language-server/__e2e__/clientSchema.e2e.ts +147 -0
- package/src/language-server/__e2e__/httpSchema.e2e.ts +21 -0
- package/src/language-server/__e2e__/localSchema.e2e.ts +25 -0
- package/src/language-server/__e2e__/localSchemaArray.e2e.ts +31 -0
- package/src/language-server/__e2e__/studioGraph.e2e.ts +65 -0
- package/src/language-server/__e2e__/utils.ts +151 -0
- package/src/language-server/__tests__/diagnostics.test.ts +8 -8
- package/src/language-server/__tests__/fileSet.test.ts +1 -1
- package/src/language-server/__tests__/fixtures/starwarsSchema.ts +2 -2
- package/src/language-server/config/__tests__/config.ts +22 -96
- package/src/language-server/config/__tests__/loadConfig.ts +120 -220
- package/src/language-server/config/__tests__/utils.ts +22 -29
- package/src/language-server/config/config.ts +221 -156
- package/src/language-server/config/loadConfig.ts +32 -153
- package/src/language-server/config/loadTsConfig.ts +70 -0
- package/src/language-server/config/utils.ts +5 -16
- package/src/language-server/diagnostics.ts +17 -8
- package/src/language-server/document.ts +16 -16
- package/src/language-server/engine/index.ts +57 -39
- package/src/language-server/engine/operations/frontendUrlRoot.ts +9 -1
- package/src/language-server/engine/operations/schemaTagsAndFieldStats.ts +9 -1
- package/src/language-server/errors/__tests__/NoMissingClientDirectives.test.ts +10 -5
- package/src/language-server/errors/logger.ts +1 -1
- package/src/language-server/errors/validation.ts +20 -23
- package/src/language-server/fileSet.ts +10 -12
- package/src/language-server/format.ts +1 -1
- package/src/language-server/graphqlTypes.ts +13020 -3455
- package/src/language-server/index.ts +0 -1
- package/src/language-server/languageProvider.ts +29 -32
- package/src/language-server/loadingHandler.ts +10 -27
- package/src/language-server/project/base.ts +32 -25
- package/src/language-server/project/client.ts +80 -114
- package/src/language-server/project/defaultClientSchema.ts +29 -4
- package/src/language-server/providers/schema/__tests__/file.ts +60 -19
- package/src/language-server/providers/schema/base.ts +2 -2
- package/src/language-server/providers/schema/endpoint.ts +15 -34
- package/src/language-server/providers/schema/engine.ts +25 -18
- package/src/language-server/providers/schema/file.ts +41 -32
- package/src/language-server/providers/schema/index.ts +5 -21
- package/src/language-server/server.ts +72 -50
- package/src/language-server/typings/graphql.d.ts +3 -3
- package/src/language-server/utilities/__tests__/graphql.test.ts +42 -54
- package/src/language-server/utilities/debouncer.ts +1 -1
- package/src/language-server/utilities/debug.ts +6 -5
- package/src/language-server/utilities/graphql.ts +17 -16
- package/src/language-server/utilities/source.ts +16 -16
- package/src/language-server/utilities/uri.ts +2 -2
- package/src/language-server/workspace.ts +29 -37
- package/src/languageServerClient.ts +4 -4
- package/src/messages.ts +38 -47
- package/src/tools/__tests__/buildServiceDefinition.test.ts +2 -2
- package/src/tools/buildServiceDefinition.ts +11 -11
- package/src/tools/schema/resolveObject.ts +1 -1
- package/src/tools/utilities/predicates.ts +1 -1
- package/src/utils.ts +7 -6
- package/syntaxes/graphql.dart.json +2 -4
- package/syntaxes/graphql.ex.json +1 -4
- package/tsconfig.build.json +8 -1
- package/tsconfig.json +5 -3
- package/src/env/fetch/fetch.ts +0 -32
- package/src/env/fetch/global.ts +0 -30
- package/src/env/fetch/index.d.ts +0 -2
- package/src/env/fetch/index.ts +0 -2
- package/src/env/fetch/url.ts +0 -9
- package/src/env/polyfills/array.ts +0 -17
- package/src/env/polyfills/index.ts +0 -2
- package/src/env/polyfills/object.ts +0 -7
- package/src/language-server/engine/GraphQLDataSource.ts +0 -124
- package/src/language-server/project/service.ts +0 -48
- 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
|
|
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 {
|
|
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
|
|
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.
|
|
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 }
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
|
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
|
-
|
|
8
|
+
buildASTSchema,
|
|
10
9
|
} from "graphql";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
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 {
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
17
|
-
import
|
|
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:
|
|
36
|
-
|
|
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(
|
|
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
|
-
|
|
63
|
-
params
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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:
|
|
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
|
|
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(
|
|
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(
|
|
238
|
-
workspace.reloadService()
|
|
257
|
+
connection.onNotification(Commands.ReloadService, () =>
|
|
258
|
+
workspace.reloadService(),
|
|
239
259
|
);
|
|
240
260
|
|
|
241
|
-
connection.onNotification(
|
|
242
|
-
|
|
243
|
-
(selection: QuickPickItem) => workspace.updateSchemaTag(selection)
|
|
261
|
+
connection.onNotification(Commands.TagSelected, (selection: QuickPickItem) =>
|
|
262
|
+
workspace.updateSchemaTag(selection),
|
|
244
263
|
);
|
|
245
264
|
|
|
246
|
-
connection.onNotification(
|
|
265
|
+
connection.onNotification(Commands.GetStats, async ({ uri }) => {
|
|
247
266
|
const status = await languageProvider.provideStats(uri);
|
|
248
|
-
connection.sendNotification(
|
|
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
|
|