@apollo/gateway 2.4.5 → 2.4.7

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 (67) hide show
  1. package/dist/__generated__/graphqlTypes.d.ts +19 -1
  2. package/dist/__generated__/graphqlTypes.d.ts.map +1 -1
  3. package/dist/__generated__/graphqlTypes.js +1 -0
  4. package/dist/__generated__/graphqlTypes.js.map +1 -1
  5. package/dist/executeQueryPlan.js +1 -1
  6. package/dist/executeQueryPlan.js.map +1 -1
  7. package/package.json +4 -4
  8. package/src/__generated__/graphqlTypes.ts +33 -2
  9. package/src/executeQueryPlan.ts +1 -1
  10. package/src/__mocks__/tsconfig.json +0 -7
  11. package/src/__tests__/.gitkeep +0 -0
  12. package/src/__tests__/CucumberREADME.md +0 -96
  13. package/src/__tests__/build-query-plan.feature +0 -1471
  14. package/src/__tests__/buildQueryPlan.test.ts +0 -1225
  15. package/src/__tests__/executeQueryPlan.conditions.test.ts +0 -1488
  16. package/src/__tests__/executeQueryPlan.introspection.test.ts +0 -140
  17. package/src/__tests__/executeQueryPlan.test.ts +0 -6140
  18. package/src/__tests__/execution-utils.ts +0 -124
  19. package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +0 -195
  20. package/src/__tests__/gateway/buildService.test.ts +0 -249
  21. package/src/__tests__/gateway/endToEnd.test.ts +0 -486
  22. package/src/__tests__/gateway/executor.test.ts +0 -96
  23. package/src/__tests__/gateway/extensions.test.ts +0 -37
  24. package/src/__tests__/gateway/lifecycle-hooks.test.ts +0 -239
  25. package/src/__tests__/gateway/opentelemetry.test.ts +0 -123
  26. package/src/__tests__/gateway/queryPlanCache.test.ts +0 -231
  27. package/src/__tests__/gateway/queryPlannerConfig.test.ts +0 -101
  28. package/src/__tests__/gateway/reporting.test.ts +0 -616
  29. package/src/__tests__/gateway/supergraphSdl.test.ts +0 -396
  30. package/src/__tests__/gateway/testUtils.ts +0 -89
  31. package/src/__tests__/integration/abstract-types.test.ts +0 -1861
  32. package/src/__tests__/integration/aliases.test.ts +0 -180
  33. package/src/__tests__/integration/boolean.test.ts +0 -279
  34. package/src/__tests__/integration/complex-key.test.ts +0 -197
  35. package/src/__tests__/integration/configuration.test.ts +0 -404
  36. package/src/__tests__/integration/custom-directives.test.ts +0 -174
  37. package/src/__tests__/integration/execution-style.test.ts +0 -35
  38. package/src/__tests__/integration/fragments.test.ts +0 -237
  39. package/src/__tests__/integration/list-key.test.ts +0 -128
  40. package/src/__tests__/integration/logger.test.ts +0 -122
  41. package/src/__tests__/integration/managed.test.ts +0 -319
  42. package/src/__tests__/integration/merge-arrays.test.ts +0 -34
  43. package/src/__tests__/integration/multiple-key.test.ts +0 -327
  44. package/src/__tests__/integration/mutations.test.ts +0 -287
  45. package/src/__tests__/integration/networkRequests.test.ts +0 -542
  46. package/src/__tests__/integration/nockMocks.ts +0 -157
  47. package/src/__tests__/integration/provides.test.ts +0 -77
  48. package/src/__tests__/integration/requires.test.ts +0 -359
  49. package/src/__tests__/integration/scope.test.ts +0 -557
  50. package/src/__tests__/integration/single-service.test.ts +0 -119
  51. package/src/__tests__/integration/unions.test.ts +0 -79
  52. package/src/__tests__/integration/value-types.test.ts +0 -382
  53. package/src/__tests__/integration/variables.test.ts +0 -120
  54. package/src/__tests__/nockAssertions.ts +0 -20
  55. package/src/__tests__/queryPlanCucumber.test.ts +0 -55
  56. package/src/__tests__/resultShaping.test.ts +0 -605
  57. package/src/__tests__/testSetup.ts +0 -1
  58. package/src/__tests__/tsconfig.json +0 -8
  59. package/src/core/__tests__/core.test.ts +0 -412
  60. package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +0 -51
  61. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +0 -574
  62. package/src/schema-helper/__tests__/addExtensions.test.ts +0 -70
  63. package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +0 -364
  64. package/src/supergraphManagers/IntrospectAndCompose/__tests__/loadServicesFromRemoteEndpoint.test.ts +0 -40
  65. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/UplinkSupergraphManager.test.ts +0 -65
  66. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/loadSupergraphSdlFromStorage.test.ts +0 -511
  67. package/src/utilities/__tests__/deepMerge.test.ts +0 -77
@@ -1,79 +0,0 @@
1
- import gql from 'graphql-tag';
2
- import { astSerializer, queryPlanSerializer } from 'apollo-federation-integration-testsuite';
3
- import { execute } from '../execution-utils';
4
-
5
- expect.addSnapshotSerializer(astSerializer);
6
- expect.addSnapshotSerializer(queryPlanSerializer);
7
-
8
- it('handles multiple union type conditions that share a response name (media)', async () => {
9
- const query = `#graphql
10
- query {
11
- content {
12
- ...Audio
13
- ... on Video {
14
- media {
15
- aspectRatio
16
- }
17
- }
18
- }
19
- }
20
- fragment Audio on Audio {
21
- media {
22
- url
23
- }
24
- }
25
- `;
26
-
27
- const { queryPlan, errors } = await execute(
28
- { query },
29
- [
30
- {
31
- name: 'contentService',
32
- typeDefs: gql`
33
- extend type Query {
34
- content: Content
35
- }
36
- union Content = Audio | Video
37
- type Audio {
38
- media: AudioURL
39
- }
40
- type AudioURL {
41
- url: String
42
- }
43
- type Video {
44
- media: VideoAspectRatio
45
- }
46
- type VideoAspectRatio {
47
- aspectRatio: String
48
- }
49
- `,
50
- resolvers: {
51
- Query: {},
52
- },
53
- },
54
- ],
55
- );
56
-
57
- expect(errors).toBeUndefined();
58
- expect(queryPlan).toMatchInlineSnapshot(`
59
- QueryPlan {
60
- Fetch(service: "contentService") {
61
- {
62
- content {
63
- __typename
64
- ... on Audio {
65
- media {
66
- url
67
- }
68
- }
69
- ... on Video {
70
- media {
71
- aspectRatio
72
- }
73
- }
74
- }
75
- }
76
- },
77
- }
78
- `);
79
- });
@@ -1,382 +0,0 @@
1
- import { execute } from '../execution-utils';
2
- import {
3
- astSerializer,
4
- fed2gql as gql,
5
- queryPlanSerializer,
6
- } from 'apollo-federation-integration-testsuite';
7
-
8
- expect.addSnapshotSerializer(astSerializer);
9
- expect.addSnapshotSerializer(queryPlanSerializer);
10
-
11
- describe('value types', () => {
12
- it('resolves value types within their respective services', async () => {
13
- const query = `#graphql
14
- fragment Metadata on MetadataOrError {
15
- ... on KeyValue {
16
- key
17
- value
18
- }
19
- ... on Error {
20
- code
21
- message
22
- }
23
- }
24
-
25
- query ProducsWithMetadata {
26
- topProducts(first: 10) {
27
- upc
28
- ... on Book {
29
- metadata {
30
- ...Metadata
31
- }
32
- }
33
- ... on Furniture {
34
- metadata {
35
- ...Metadata
36
- }
37
- }
38
- reviews {
39
- metadata {
40
- ...Metadata
41
- }
42
- }
43
- }
44
- }
45
- `;
46
-
47
- const { data, errors, queryPlan } = await execute({
48
- query,
49
- });
50
-
51
- expect(errors).toBeUndefined();
52
-
53
- expect(queryPlan).toMatchInlineSnapshot(`
54
- QueryPlan {
55
- Sequence {
56
- Fetch(service: "product") {
57
- {
58
- topProducts(first: 10) {
59
- __typename
60
- upc
61
- ... on Book {
62
- __typename
63
- isbn
64
- }
65
- ... on Furniture {
66
- __typename
67
- upc
68
- metadata {
69
- __typename
70
- ... on KeyValue {
71
- key
72
- value
73
- }
74
- ... on Error {
75
- code
76
- message
77
- }
78
- }
79
- }
80
- }
81
- }
82
- },
83
- Parallel {
84
- Flatten(path: "topProducts.@") {
85
- Fetch(service: "reviews") {
86
- {
87
- ... on Book {
88
- __typename
89
- isbn
90
- }
91
- ... on Furniture {
92
- __typename
93
- upc
94
- }
95
- } =>
96
- {
97
- ... on Book {
98
- reviews {
99
- metadata {
100
- __typename
101
- ...Metadata
102
- }
103
- }
104
- }
105
- ... on Furniture {
106
- reviews {
107
- metadata {
108
- __typename
109
- ...Metadata
110
- }
111
- }
112
- }
113
- }
114
-
115
- fragment Metadata on MetadataOrError {
116
- ... on KeyValue {
117
- key
118
- value
119
- }
120
- ... on Error {
121
- code
122
- message
123
- }
124
- }
125
- },
126
- },
127
- Flatten(path: "topProducts.@") {
128
- Fetch(service: "books") {
129
- {
130
- ... on Book {
131
- __typename
132
- isbn
133
- }
134
- } =>
135
- {
136
- ... on Book {
137
- metadata {
138
- __typename
139
- ... on KeyValue {
140
- key
141
- value
142
- }
143
- ... on Error {
144
- code
145
- message
146
- }
147
- }
148
- }
149
- }
150
- },
151
- },
152
- },
153
- },
154
- }
155
- `);
156
-
157
- const [furniture, , , , book] = data!.topProducts;
158
-
159
- // Sanity check, referenceable ID
160
- expect(furniture.upc).toEqual('1');
161
- // Value type resolves from the correct service
162
- expect(furniture.metadata[0]).toEqual({
163
- key: 'Condition',
164
- value: 'excellent',
165
- });
166
-
167
- // Value type from a different service (reviews) also resolves correctly
168
- expect(furniture.reviews[0].metadata[0]).toEqual({
169
- code: 418,
170
- message: "I'm a teapot",
171
- });
172
-
173
- // Sanity check, referenceable ID
174
- expect(book.upc).toEqual('0136291554');
175
- // Value type as a union resolves correctly
176
- expect(book.metadata).toEqual([
177
- {
178
- key: 'Condition',
179
- value: 'used',
180
- },
181
- {
182
- code: 401,
183
- message: 'Unauthorized',
184
- },
185
- ]);
186
-
187
- expect(queryPlan).toCallService('product');
188
- expect(queryPlan).toCallService('books');
189
- expect(queryPlan).toCallService('reviews');
190
- });
191
-
192
- it('resolves @provides fields on value types correctly via contrived example', async () => {
193
- const firstService = {
194
- name: 'firstService',
195
- typeDefs: gql`
196
- extend type Query {
197
- valueType: ValueType
198
- }
199
-
200
- type ValueType @shareable {
201
- id: ID!
202
- user: User! @provides(fields: "name")
203
- }
204
-
205
- extend type User @key(fields: "id") {
206
- id: ID! @external
207
- name: String! @external
208
- }
209
- `,
210
- resolvers: {
211
- Query: {
212
- valueType() {
213
- return { id: '123', user: { id: '1', name: 'trevor' } };
214
- },
215
- },
216
- },
217
- };
218
-
219
- const secondService = {
220
- name: 'secondService',
221
- typeDefs: gql`
222
- extend type Query {
223
- otherValueType: ValueType
224
- }
225
-
226
- type ValueType @shareable {
227
- id: ID!
228
- user: User! @provides(fields: "name")
229
- }
230
-
231
- extend type User @key(fields: "id") {
232
- id: ID! @external
233
- name: String! @external
234
- }
235
- `,
236
- resolvers: {
237
- Query: {
238
- otherValueType() {
239
- return { id: '456', user: { id: '2', name: 'james' } };
240
- },
241
- },
242
- },
243
- };
244
-
245
- const userService = {
246
- name: 'userService',
247
- typeDefs: gql`
248
- type User @key(fields: "id") {
249
- id: ID!
250
- name: String! @shareable
251
- address: String!
252
- }
253
- `,
254
- resolvers: {
255
- User: {
256
- __resolveReference(user: any) {
257
- return user.id === '1'
258
- ? { id: '1', name: 'trevor', address: '123 Abc St' }
259
- : { id: '2', name: 'james', address: '456 Hello St.' };
260
- },
261
- },
262
- },
263
- };
264
-
265
- const query = `#graphql
266
- query Hello {
267
- valueType {
268
- id
269
- user {
270
- id
271
- name
272
- address
273
- }
274
- }
275
- otherValueType {
276
- id
277
- user {
278
- id
279
- name
280
- address
281
- }
282
- }
283
- }
284
- `;
285
-
286
- const { data, errors, queryPlan } = await execute(
287
- {
288
- query,
289
- },
290
- [firstService, secondService, userService],
291
- );
292
-
293
- expect(errors).toBeUndefined();
294
- expect(queryPlan).toCallService('firstService');
295
- expect(queryPlan).toCallService('secondService');
296
- expect(queryPlan).toCallService('userService');
297
- expect(data).toMatchInlineSnapshot(`
298
- Object {
299
- "otherValueType": Object {
300
- "id": "456",
301
- "user": Object {
302
- "address": "456 Hello St.",
303
- "id": "2",
304
- "name": "james",
305
- },
306
- },
307
- "valueType": Object {
308
- "id": "123",
309
- "user": Object {
310
- "address": "123 Abc St",
311
- "id": "1",
312
- "name": "trevor",
313
- },
314
- },
315
- }
316
- `);
317
- expect(queryPlan).toMatchInlineSnapshot(`
318
- QueryPlan {
319
- Parallel {
320
- Sequence {
321
- Fetch(service: "firstService") {
322
- {
323
- valueType {
324
- id
325
- user {
326
- __typename
327
- id
328
- name
329
- }
330
- }
331
- }
332
- },
333
- Flatten(path: "valueType.user") {
334
- Fetch(service: "userService") {
335
- {
336
- ... on User {
337
- __typename
338
- id
339
- }
340
- } =>
341
- {
342
- ... on User {
343
- address
344
- }
345
- }
346
- },
347
- },
348
- },
349
- Sequence {
350
- Fetch(service: "secondService") {
351
- {
352
- otherValueType {
353
- id
354
- user {
355
- __typename
356
- id
357
- name
358
- }
359
- }
360
- }
361
- },
362
- Flatten(path: "otherValueType.user") {
363
- Fetch(service: "userService") {
364
- {
365
- ... on User {
366
- __typename
367
- id
368
- }
369
- } =>
370
- {
371
- ... on User {
372
- address
373
- }
374
- }
375
- },
376
- },
377
- },
378
- },
379
- }
380
- `);
381
- });
382
- });
@@ -1,120 +0,0 @@
1
- import { execute } from '../execution-utils';
2
-
3
- it('passes variables to root fields', async () => {
4
- const query = `#graphql
5
- query GetProduct($upc: String!) {
6
- product(upc: $upc) {
7
- name
8
- }
9
- }
10
- `;
11
-
12
- const upc = '1';
13
- const { data, errors, queryPlan } = await execute({
14
- query,
15
- variables: { upc },
16
- });
17
-
18
- expect(errors).toBeUndefined();
19
- expect(data).toEqual({
20
- product: {
21
- name: 'Table',
22
- },
23
- });
24
-
25
- expect(queryPlan).toCallService('product');
26
- });
27
-
28
- it('supports default variables in a variable definition', async () => {
29
- const query = `#graphql
30
- query GetProduct($upc: String = "1") {
31
- product(upc: $upc) {
32
- name
33
- }
34
- }
35
- `;
36
-
37
- const { data, errors, queryPlan } = await execute({
38
- query,
39
- });
40
-
41
- expect(errors).toBeUndefined();
42
- expect(data).toEqual({
43
- product: {
44
- name: 'Table',
45
- },
46
- });
47
-
48
- expect(queryPlan).toCallService('product');
49
- });
50
-
51
- it('passes variables to nested services', async () => {
52
- const query = `#graphql
53
- query GetProductsForUser($format: Boolean) {
54
- me {
55
- reviews {
56
- body(format: $format)
57
- }
58
- }
59
- }
60
- `;
61
-
62
- const format = true;
63
- const { data, errors, queryPlan } = await execute({
64
- query,
65
- variables: { format },
66
- });
67
-
68
- expect(errors).toBeUndefined();
69
- expect(data).toEqual({
70
- me: {
71
- reviews: [
72
- { body: 'Love it!' },
73
- { body: 'Too expensive.' },
74
- {
75
- body: 'A classic.',
76
- },
77
- ],
78
- },
79
- });
80
-
81
- expect(queryPlan).toCallService('accounts');
82
- expect(queryPlan).toCallService('reviews');
83
- });
84
-
85
- it('works with default variables in the schema', async () => {
86
- const query = `#graphql
87
- query LibraryUser($libraryId: ID!, $userId: ID) {
88
- library(id: $libraryId) {
89
- userAccount(id: $userId) {
90
- id
91
- name {
92
- first
93
- last
94
- }
95
- }
96
- }
97
- }
98
- `;
99
-
100
- const { data, queryPlan, errors } = await execute({
101
- query,
102
- variables: { libraryId: '1' },
103
- });
104
-
105
- expect(data).toEqual({
106
- library: {
107
- userAccount: {
108
- id: '1',
109
- name: {
110
- first: 'Ada',
111
- last: 'Lovelace',
112
- }
113
- },
114
- },
115
- });
116
-
117
- expect(errors).toBeUndefined();
118
- expect(queryPlan).toCallService('books');
119
- expect(queryPlan).toCallService('accounts');
120
- });
@@ -1,20 +0,0 @@
1
- import nock from 'nock';
2
-
3
- // Ensures an active and clean nock before every test
4
- export function nockBeforeEach() {
5
- if (!nock.isActive()) {
6
- nock.activate();
7
- }
8
- // Cleaning _before_ each test ensures that any mocks from a previous test
9
- // which failed don't affect the current test.
10
- nock.cleanAll();
11
- }
12
-
13
- // Ensures a test is complete (all expected requests were run) and a clean
14
- // global state after each test.
15
- export function nockAfterEach() {
16
- // unmock HTTP interceptor
17
- nock.restore();
18
- // effectively nock.isDone() but with more helpful messages in test failures
19
- expect(nock.activeMocks()).toEqual([]);
20
- };
@@ -1,55 +0,0 @@
1
- import gql from 'graphql-tag';
2
- import { defineFeature, loadFeature } from 'jest-cucumber';
3
- import { DocumentNode } from 'graphql';
4
-
5
- import { QueryPlan } from '@apollo/query-planner';
6
- import { getFederatedTestingSchema } from './execution-utils';
7
- import { operationFromDocument } from '@apollo/federation-internals';
8
-
9
- const buildQueryPlanFeature = loadFeature(
10
- './gateway-js/src/__tests__/build-query-plan.feature'
11
- );
12
-
13
-
14
- const features = [
15
- buildQueryPlanFeature
16
- ];
17
-
18
- features.forEach((feature) => {
19
- defineFeature(feature, (test) => {
20
- feature.scenarios.forEach((scenario) => {
21
- test(scenario.title, async ({ given, then }) => {
22
- let operationDocument: DocumentNode;
23
- let queryPlan: QueryPlan;
24
-
25
- // throws on composition errors
26
- const { schema, queryPlanner } = getFederatedTestingSchema();
27
-
28
- const givenQuery = () => {
29
- given(/^query$/im, (operation: string) => {
30
- operationDocument = gql(operation);
31
- })
32
- }
33
-
34
- const thenQueryPlanShouldBe = () => {
35
- then(/^query plan$/i, (expectedQueryPlan: string) => {
36
- queryPlan = queryPlanner.buildQueryPlan(operationFromDocument(schema, operationDocument));
37
-
38
- const parsedExpectedPlan = JSON.parse(expectedQueryPlan);
39
-
40
- expect(queryPlan).toEqual(parsedExpectedPlan);
41
- })
42
- }
43
-
44
- // step over each defined step in the .feature and execute the correct
45
- // matching step fn defined above
46
- scenario.steps.forEach(({ stepText }) => {
47
- const title = stepText.toLocaleLowerCase();
48
- if (title === "query") givenQuery();
49
- else if (title === "query plan") thenQueryPlanShouldBe();
50
- else throw new Error(`Unrecognized steps used in "build-query-plan.feature"`);
51
- });
52
- });
53
- });
54
- });
55
- });