vscode-apollo 1.19.2 → 1.20.0

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 (155) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +14 -0
  3. package/.circleci/config.yml +82 -0
  4. package/.eslintrc.js +10 -0
  5. package/.gitattributes +1 -0
  6. package/.github/workflows/release.yml +95 -0
  7. package/.gitleaks.toml +26 -0
  8. package/.nvmrc +1 -0
  9. package/.prettierrc +5 -0
  10. package/.vscode/launch.json +61 -0
  11. package/.vscode/settings.json +16 -0
  12. package/.vscode/tasks.json +18 -0
  13. package/.vscodeignore +17 -1
  14. package/CHANGELOG.md +172 -1
  15. package/LICENSE +2 -2
  16. package/README.md +9 -9
  17. package/codegen.yml +12 -0
  18. package/images/IconRun.svg +8 -0
  19. package/jest.config.ts +11 -0
  20. package/package.json +102 -22
  21. package/renovate.json +23 -0
  22. package/src/__mocks__/fs.js +3 -0
  23. package/src/__tests__/statusBar.test.ts +8 -7
  24. package/src/debug.ts +2 -5
  25. package/src/env/fetch/fetch.ts +32 -0
  26. package/src/env/fetch/global.ts +30 -0
  27. package/src/env/fetch/index.d.ts +2 -0
  28. package/src/env/fetch/index.ts +2 -0
  29. package/src/env/fetch/url.ts +9 -0
  30. package/src/env/index.ts +4 -0
  31. package/src/env/polyfills/array.ts +17 -0
  32. package/src/env/polyfills/index.ts +2 -0
  33. package/src/env/polyfills/object.ts +7 -0
  34. package/src/env/typescript-utility-types.ts +2 -0
  35. package/src/extension.ts +106 -37
  36. package/src/language-server/__tests__/diagnostics.test.ts +86 -0
  37. package/src/language-server/__tests__/document.test.ts +187 -0
  38. package/src/language-server/__tests__/fileSet.test.ts +46 -0
  39. package/src/language-server/__tests__/fixtures/starwarsSchema.ts +1917 -0
  40. package/src/language-server/config/__tests__/config.ts +128 -0
  41. package/src/language-server/config/__tests__/loadConfig.ts +508 -0
  42. package/src/language-server/config/__tests__/utils.ts +106 -0
  43. package/src/language-server/config/config.ts +219 -0
  44. package/src/language-server/config/index.ts +3 -0
  45. package/src/language-server/config/loadConfig.ts +228 -0
  46. package/src/language-server/config/utils.ts +56 -0
  47. package/src/language-server/diagnostics.ts +109 -0
  48. package/src/language-server/document.ts +277 -0
  49. package/src/language-server/engine/GraphQLDataSource.ts +124 -0
  50. package/src/language-server/engine/index.ts +105 -0
  51. package/src/language-server/engine/operations/frontendUrlRoot.ts +7 -0
  52. package/src/language-server/engine/operations/schemaTagsAndFieldStats.ts +24 -0
  53. package/src/language-server/errors/__tests__/NoMissingClientDirectives.test.ts +220 -0
  54. package/src/language-server/errors/logger.ts +58 -0
  55. package/src/language-server/errors/validation.ts +277 -0
  56. package/src/language-server/fileSet.ts +65 -0
  57. package/src/language-server/format.ts +48 -0
  58. package/src/language-server/graphqlTypes.ts +7176 -0
  59. package/src/language-server/index.ts +29 -0
  60. package/src/language-server/languageProvider.ts +798 -0
  61. package/src/language-server/loadingHandler.ts +64 -0
  62. package/src/language-server/project/base.ts +399 -0
  63. package/src/language-server/project/client.ts +602 -0
  64. package/src/language-server/project/defaultClientSchema.ts +45 -0
  65. package/src/language-server/project/service.ts +48 -0
  66. package/src/language-server/providers/schema/__tests__/file.ts +150 -0
  67. package/src/language-server/providers/schema/base.ts +15 -0
  68. package/src/language-server/providers/schema/endpoint.ts +157 -0
  69. package/src/language-server/providers/schema/engine.ts +197 -0
  70. package/src/language-server/providers/schema/file.ts +167 -0
  71. package/src/language-server/providers/schema/index.ts +75 -0
  72. package/src/language-server/server.ts +252 -0
  73. package/src/language-server/typings/codemirror.d.ts +4 -0
  74. package/src/language-server/typings/graphql.d.ts +27 -0
  75. package/src/language-server/utilities/__tests__/graphql.test.ts +411 -0
  76. package/src/language-server/utilities/__tests__/uri.ts +55 -0
  77. package/src/language-server/utilities/debouncer.ts +8 -0
  78. package/src/language-server/utilities/debug.ts +89 -0
  79. package/src/language-server/utilities/graphql.ts +432 -0
  80. package/src/language-server/utilities/index.ts +3 -0
  81. package/src/language-server/utilities/source.ts +182 -0
  82. package/src/language-server/utilities/uri.ts +19 -0
  83. package/src/language-server/workspace.ts +262 -0
  84. package/src/languageServerClient.ts +19 -12
  85. package/src/messages.ts +84 -0
  86. package/src/statusBar.ts +5 -5
  87. package/src/tools/__tests__/buildServiceDefinition.test.ts +491 -0
  88. package/src/tools/__tests__/snapshotSerializers/astSerializer.ts +19 -0
  89. package/src/tools/__tests__/snapshotSerializers/graphQLTypeSerializer.ts +14 -0
  90. package/src/tools/buildServiceDefinition.ts +241 -0
  91. package/src/tools/index.ts +6 -0
  92. package/src/tools/schema/index.ts +2 -0
  93. package/src/tools/schema/resolveObject.ts +18 -0
  94. package/src/tools/schema/resolverMap.ts +23 -0
  95. package/src/tools/utilities/graphql.ts +22 -0
  96. package/src/tools/utilities/index.ts +3 -0
  97. package/src/tools/utilities/invariant.ts +5 -0
  98. package/src/tools/utilities/predicates.ts +5 -0
  99. package/src/utils.ts +1 -16
  100. package/syntaxes/graphql.js.json +3 -3
  101. package/syntaxes/graphql.json +13 -9
  102. package/syntaxes/graphql.lua.json +51 -0
  103. package/syntaxes/graphql.rb.json +1 -1
  104. package/tsconfig.build.json +4 -0
  105. package/tsconfig.json +20 -7
  106. package/create-server-symlink.js +0 -8
  107. package/lib/debug.d.ts +0 -11
  108. package/lib/debug.d.ts.map +0 -1
  109. package/lib/debug.js +0 -48
  110. package/lib/debug.js.map +0 -1
  111. package/lib/extension.d.ts +0 -4
  112. package/lib/extension.d.ts.map +0 -1
  113. package/lib/extension.js +0 -187
  114. package/lib/extension.js.map +0 -1
  115. package/lib/languageServerClient.d.ts +0 -4
  116. package/lib/languageServerClient.d.ts.map +0 -1
  117. package/lib/languageServerClient.js +0 -57
  118. package/lib/languageServerClient.js.map +0 -1
  119. package/lib/statusBar.d.ts +0 -24
  120. package/lib/statusBar.d.ts.map +0 -1
  121. package/lib/statusBar.js +0 -46
  122. package/lib/statusBar.js.map +0 -1
  123. package/lib/testRunner/index.d.ts +0 -3
  124. package/lib/testRunner/index.d.ts.map +0 -1
  125. package/lib/testRunner/index.js +0 -49
  126. package/lib/testRunner/index.js.map +0 -1
  127. package/lib/testRunner/jest-config.d.ts +0 -14
  128. package/lib/testRunner/jest-config.d.ts.map +0 -1
  129. package/lib/testRunner/jest-config.js +0 -18
  130. package/lib/testRunner/jest-config.js.map +0 -1
  131. package/lib/testRunner/jest-vscode-environment.d.ts +0 -2
  132. package/lib/testRunner/jest-vscode-environment.d.ts.map +0 -1
  133. package/lib/testRunner/jest-vscode-environment.js +0 -19
  134. package/lib/testRunner/jest-vscode-environment.js.map +0 -1
  135. package/lib/testRunner/jest-vscode-framework-setup.d.ts +0 -1
  136. package/lib/testRunner/jest-vscode-framework-setup.d.ts.map +0 -1
  137. package/lib/testRunner/jest-vscode-framework-setup.js +0 -3
  138. package/lib/testRunner/jest-vscode-framework-setup.js.map +0 -1
  139. package/lib/testRunner/vscode-test-script.d.ts +0 -2
  140. package/lib/testRunner/vscode-test-script.d.ts.map +0 -1
  141. package/lib/testRunner/vscode-test-script.js +0 -23
  142. package/lib/testRunner/vscode-test-script.js.map +0 -1
  143. package/lib/utils.d.ts +0 -18
  144. package/lib/utils.d.ts.map +0 -1
  145. package/lib/utils.js +0 -52
  146. package/lib/utils.js.map +0 -1
  147. package/src/testRunner/README.md +0 -23
  148. package/src/testRunner/index.ts +0 -72
  149. package/src/testRunner/jest-config.ts +0 -17
  150. package/src/testRunner/jest-vscode-environment.ts +0 -25
  151. package/src/testRunner/jest-vscode-framework-setup.ts +0 -10
  152. package/src/testRunner/jest.d.ts +0 -37
  153. package/src/testRunner/vscode-test-script.ts +0 -38
  154. package/tsconfig.test.json +0 -4
  155. package/tsconfig.tsbuildinfo +0 -2486
@@ -0,0 +1,411 @@
1
+ import gql from "graphql-tag";
2
+ import { parse, print } from "graphql";
3
+ import {
4
+ withTypenameFieldAddedWhereNeeded,
5
+ removeDirectiveAnnotatedFields,
6
+ } from "../graphql";
7
+
8
+ describe("withTypenameFieldAddedWhereNeeded", () => {
9
+ it("properly adds __typename to each selectionSet", () => {
10
+ const query = gql`
11
+ query Product {
12
+ product {
13
+ sku
14
+ color {
15
+ id
16
+ value
17
+ }
18
+ }
19
+ }
20
+ `;
21
+
22
+ const withTypenames = withTypenameFieldAddedWhereNeeded(query);
23
+
24
+ expect(print(withTypenames)).toMatchInlineSnapshot(`
25
+ "query Product {
26
+ product {
27
+ __typename
28
+ sku
29
+ color {
30
+ __typename
31
+ id
32
+ value
33
+ }
34
+ }
35
+ }
36
+ "
37
+ `);
38
+ });
39
+
40
+ it("adds __typename to InlineFragment nodes (as ApolloClient does)", () => {
41
+ const query = gql`
42
+ query CartItems {
43
+ product {
44
+ items {
45
+ ... on Table {
46
+ material
47
+ }
48
+ ... on Paint {
49
+ color
50
+ }
51
+ }
52
+ }
53
+ }
54
+ `;
55
+
56
+ const withTypenames = withTypenameFieldAddedWhereNeeded(query);
57
+
58
+ expect(print(withTypenames)).toMatchInlineSnapshot(`
59
+ "query CartItems {
60
+ product {
61
+ __typename
62
+ items {
63
+ __typename
64
+ ... on Table {
65
+ __typename
66
+ material
67
+ }
68
+ ... on Paint {
69
+ __typename
70
+ color
71
+ }
72
+ }
73
+ }
74
+ }
75
+ "
76
+ `);
77
+ });
78
+ });
79
+
80
+ describe("removeDirectiveAnnotatedFields", () => {
81
+ it("should remove fields with matching directives", () => {
82
+ expect(
83
+ print(
84
+ removeDirectiveAnnotatedFields(
85
+ parse(`query Query { fieldToKeep fieldToRemove @client }`),
86
+ ["client"]
87
+ )
88
+ )
89
+ ).toMatchInlineSnapshot(`
90
+ "query Query {
91
+ fieldToKeep
92
+ }
93
+ "
94
+ `);
95
+ });
96
+
97
+ it("trim selections sets that are client only", () => {
98
+ expect(
99
+ print(
100
+ removeDirectiveAnnotatedFields(
101
+ parse(`
102
+ query Query {
103
+ fieldToKeep
104
+ fieldToRemove @client {
105
+ childField
106
+ }
107
+ }
108
+ `),
109
+ ["client"]
110
+ )
111
+ )
112
+ ).toMatchInlineSnapshot(`
113
+ "query Query {
114
+ fieldToKeep
115
+ }
116
+ "
117
+ `);
118
+ });
119
+
120
+ it("should remove fragments when a directive is used on a fragment spread", () => {
121
+ expect(
122
+ print(
123
+ removeDirectiveAnnotatedFields(
124
+ parse(`
125
+ {
126
+ me { name }
127
+ ...ClientFields @client
128
+ }
129
+ fragment ClientFields on Query {
130
+ hello
131
+ }
132
+ `),
133
+ ["client"]
134
+ )
135
+ )
136
+ ).toMatchInlineSnapshot(`
137
+ "{
138
+ me {
139
+ name
140
+ }
141
+ }
142
+ "
143
+ `);
144
+ });
145
+
146
+ it("should remove fragments when client directive is used inline", () => {
147
+ expect(
148
+ print(
149
+ removeDirectiveAnnotatedFields(
150
+ parse(`
151
+ {
152
+ me { name }
153
+ ... on Query @client {
154
+ hello
155
+ }
156
+ }
157
+ `),
158
+ ["client"]
159
+ )
160
+ )
161
+ ).toMatchInlineSnapshot(`
162
+ "{
163
+ me {
164
+ name
165
+ }
166
+ }
167
+ "
168
+ `);
169
+ });
170
+
171
+ it("should remove fragments when the client directive is on the definition", () => {
172
+ expect(
173
+ print(
174
+ removeDirectiveAnnotatedFields(
175
+ parse(`
176
+ fragment ClientObject on Query @client {
177
+ hello
178
+ }
179
+ {
180
+ me { name }
181
+ ... ClientObject
182
+ }
183
+ `),
184
+ ["client"]
185
+ )
186
+ )
187
+ ).toMatchInlineSnapshot(`
188
+ "{
189
+ me {
190
+ name
191
+ }
192
+ }
193
+ "
194
+ `);
195
+ });
196
+
197
+ it("should remove fragments that become unused when antecendant directives are removed", () => {
198
+ expect(
199
+ print(
200
+ removeDirectiveAnnotatedFields(
201
+ parse(`
202
+ fragment ClientObjectFragment on ClientObject {
203
+ string
204
+ number
205
+ }
206
+
207
+ fragment LaunchTile on Launch {
208
+ __typename
209
+ id
210
+ isBooked
211
+ rocket {
212
+ id
213
+ name
214
+ }
215
+ mission {
216
+ name
217
+ missionPatch
218
+ }
219
+ }
220
+
221
+ query LaunchDetails($launchId: ID!) {
222
+ launch(id: $launchId) {
223
+ isInCart @client
224
+ clientObject @client {
225
+ ...ClientObjectFragment
226
+ }
227
+ site
228
+ rocket {
229
+ type
230
+ }
231
+ ...LaunchTile
232
+ }
233
+ }
234
+ `),
235
+ ["client"]
236
+ )
237
+ )
238
+ ).toMatchInlineSnapshot(`
239
+ "fragment LaunchTile on Launch {
240
+ __typename
241
+ id
242
+ isBooked
243
+ rocket {
244
+ id
245
+ name
246
+ }
247
+ mission {
248
+ name
249
+ missionPatch
250
+ }
251
+ }
252
+
253
+ query LaunchDetails($launchId: ID!) {
254
+ launch(id: $launchId) {
255
+ site
256
+ rocket {
257
+ type
258
+ }
259
+ ...LaunchTile
260
+ }
261
+ }
262
+ "
263
+ `);
264
+ });
265
+
266
+ it("should recursively remove fragments that become unused when antecendant directives are removed", () => {
267
+ expect(
268
+ print(
269
+ removeDirectiveAnnotatedFields(
270
+ parse(`
271
+ fragment One on Node {
272
+ ...Two
273
+ user {
274
+ friends {
275
+ name
276
+ ...Two @client
277
+ }
278
+ }
279
+ }
280
+ fragment Two on Node {
281
+ id
282
+ }
283
+
284
+ query {
285
+ me {
286
+ ...One
287
+ }
288
+ }
289
+ `),
290
+ ["client"]
291
+ )
292
+ )
293
+ ).toMatchInlineSnapshot(`
294
+ "fragment One on Node {
295
+ ...Two
296
+ user {
297
+ friends {
298
+ name
299
+ }
300
+ }
301
+ }
302
+
303
+ fragment Two on Node {
304
+ id
305
+ }
306
+
307
+ {
308
+ me {
309
+ ...One
310
+ }
311
+ }
312
+ "
313
+ `);
314
+ });
315
+
316
+ it("should remove fragment spreads from @client fragment definitions", () => {
317
+ expect(
318
+ print(
319
+ removeDirectiveAnnotatedFields(
320
+ parse(`
321
+ fragment One on Node @client {
322
+ ...Two
323
+ }
324
+
325
+ fragment Two on Node {
326
+ id
327
+ }
328
+
329
+ query {
330
+ me {
331
+ name
332
+ ...One
333
+ }
334
+ }
335
+ `),
336
+ ["client"]
337
+ )
338
+ )
339
+ ).toMatchInlineSnapshot(`
340
+ "{
341
+ me {
342
+ name
343
+ }
344
+ }
345
+ "
346
+ `);
347
+ });
348
+
349
+ it("should remove all operations that have no selection set after fragments are removed", () => {
350
+ expect(
351
+ print(
352
+ removeDirectiveAnnotatedFields(
353
+ parse(`
354
+ fragment One on Node @client {
355
+ ...Two
356
+ }
357
+
358
+ fragment Two on Node {
359
+ id
360
+ }
361
+
362
+ {
363
+ name
364
+ me {
365
+ ...One
366
+ }
367
+ }
368
+ `),
369
+ ["client"]
370
+ )
371
+ )
372
+ ).toMatchInlineSnapshot(`
373
+ "{
374
+ name
375
+ }
376
+ "
377
+ `);
378
+ });
379
+
380
+ it("should not remove fragment definitions that weren't removed by `removeDirectiveAnnotatedFields`", () => {
381
+ expect(
382
+ print(
383
+ removeDirectiveAnnotatedFields(
384
+ parse(`
385
+ fragment One on Node {
386
+ id
387
+ }
388
+
389
+ {
390
+ me {
391
+ name
392
+ }
393
+ }
394
+ `),
395
+ ["client"]
396
+ )
397
+ )
398
+ ).toMatchInlineSnapshot(`
399
+ "fragment One on Node {
400
+ id
401
+ }
402
+
403
+ {
404
+ me {
405
+ name
406
+ }
407
+ }
408
+ "
409
+ `);
410
+ });
411
+ });
@@ -0,0 +1,55 @@
1
+ import { normalizeURI } from "../uri";
2
+
3
+ describe("Unix URIs", () => {
4
+ // this is the format that `glob` returns on unix
5
+ const uriToMatchForUnix = "/test/myFile.js";
6
+
7
+ // single forward slash (unix)
8
+ it("handles /Users/me URIs", () => {
9
+ const uri = "/test/myFile.js";
10
+ const parsed = normalizeURI(uri);
11
+ expect(parsed).toEqual(uriToMatchForUnix);
12
+ });
13
+
14
+ // single escaped backslash
15
+ // treat these as forward slashes?
16
+ it("handles \\Users\\me URIs", () => {
17
+ const uri = "\\test\\myFile.js";
18
+ const parsed = normalizeURI(uri);
19
+ expect(parsed).toEqual(uriToMatchForUnix);
20
+ });
21
+ });
22
+
23
+ describe("Windows URIs", () => {
24
+ // this is the format that `glob` returns for windows
25
+ const uriToMatchForWindows = "c:/test/myFile.js";
26
+
27
+ // this format is sent by the native extension notification system on windows
28
+ it("handles file:///c%3A/ URIs", () => {
29
+ const uri = "file:///c%3A/test/myFile.js";
30
+ const parsed = normalizeURI(uri);
31
+ expect(parsed).toEqual(uriToMatchForWindows);
32
+ });
33
+
34
+ // same as above without URI encoded :
35
+ it("handles handles file:///c:/ URIs", () => {
36
+ const uri = "file:///c:/test/myFile.js";
37
+ const parsed = normalizeURI(uri);
38
+ expect(parsed).toEqual(uriToMatchForWindows);
39
+ });
40
+
41
+ // result of glob.sync
42
+ it("handles c:/ URIs", () => {
43
+ const uri = "c:/test/myFile.js";
44
+ const parsed = normalizeURI(uri);
45
+ expect(parsed).toEqual(uriToMatchForWindows);
46
+ });
47
+
48
+ // from status bar notification
49
+ // single (escaped) backslash
50
+ it("handles c:\\ URIs", () => {
51
+ const uri = "c:\\test\\myFile.js";
52
+ const parsed = normalizeURI(uri);
53
+ expect(parsed).toEqual(uriToMatchForWindows);
54
+ });
55
+ });
@@ -0,0 +1,8 @@
1
+ import debounce from "lodash.debounce";
2
+
3
+ export function debounceHandler(
4
+ handler: (...args: any[]) => any,
5
+ leading: boolean = true
6
+ ) {
7
+ return debounce(handler, 250, { leading });
8
+ }
@@ -0,0 +1,89 @@
1
+ import { Connection } from "src/messages";
2
+
3
+ /**
4
+ * for errors (and other logs in debug mode) we want to print
5
+ * a stack trace showing where they were thrown. This uses an
6
+ * Error's stack trace, removes the three frames regarding
7
+ * this file (since they're useless) and returns the rest of the trace.
8
+ */
9
+ const createAndTrimStackTrace = () => {
10
+ let stack: string | undefined = new Error().stack;
11
+ // remove the lines in the stack from _this_ function and the caller (in this file) and shorten the trace
12
+ return stack && stack.split("\n").length > 2
13
+ ? stack.split("\n").slice(3, 7).join("\n")
14
+ : stack;
15
+ };
16
+
17
+ type Logger = (message?: any) => void;
18
+
19
+ export class Debug {
20
+ private static connection?: Connection;
21
+ private static infoLogger: Logger = (message) =>
22
+ console.log("[INFO] " + message);
23
+ private static warningLogger: Logger = (message) =>
24
+ console.warn("[WARNING] " + message);
25
+ private static errorLogger: Logger = (message) =>
26
+ console.error("[ERROR] " + message);
27
+
28
+ /**
29
+ * Setting a connection overrides the default info/warning/error
30
+ * loggers to pass a notification to the connection
31
+ */
32
+ public static SetConnection(conn: Connection) {
33
+ Debug.connection = conn;
34
+ Debug.infoLogger = (message) =>
35
+ Debug.connection!.sendNotification("serverDebugMessage", {
36
+ type: "info",
37
+ message: message,
38
+ });
39
+ Debug.warningLogger = (message) =>
40
+ Debug.connection!.sendNotification("serverDebugMessage", {
41
+ type: "warning",
42
+ message: message,
43
+ });
44
+ Debug.errorLogger = (message) =>
45
+ Debug.connection!.sendNotification("serverDebugMessage", {
46
+ type: "error",
47
+ message: message,
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Allow callers to set their own error logging utils.
53
+ * These will default to console.log/warn/error
54
+ */
55
+ public static SetLoggers({
56
+ info,
57
+ warning,
58
+ error,
59
+ }: {
60
+ info?: Logger;
61
+ warning?: Logger;
62
+ error?: Logger;
63
+ }) {
64
+ if (info) Debug.infoLogger = info;
65
+ if (warning) Debug.warningLogger = warning;
66
+ if (error) Debug.errorLogger = error;
67
+ }
68
+
69
+ public static info(message: string) {
70
+ Debug.infoLogger(message);
71
+ }
72
+
73
+ public static error(message: string) {
74
+ const stack = createAndTrimStackTrace();
75
+ Debug.errorLogger(`${message}\n${stack}`);
76
+ }
77
+
78
+ public static warning(message: string) {
79
+ Debug.warningLogger(message);
80
+ }
81
+
82
+ public static sendErrorTelemetry(message: string) {
83
+ Debug.connection &&
84
+ Debug.connection.sendNotification("serverDebugMessage", {
85
+ type: "errorTelemetry",
86
+ message: message,
87
+ });
88
+ }
89
+ }