@apollo/gateway 2.4.5 → 2.4.6

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 (64) 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/package.json +4 -4
  6. package/src/__generated__/graphqlTypes.ts +33 -2
  7. package/src/__mocks__/tsconfig.json +0 -7
  8. package/src/__tests__/.gitkeep +0 -0
  9. package/src/__tests__/CucumberREADME.md +0 -96
  10. package/src/__tests__/build-query-plan.feature +0 -1471
  11. package/src/__tests__/buildQueryPlan.test.ts +0 -1225
  12. package/src/__tests__/executeQueryPlan.conditions.test.ts +0 -1488
  13. package/src/__tests__/executeQueryPlan.introspection.test.ts +0 -140
  14. package/src/__tests__/executeQueryPlan.test.ts +0 -6140
  15. package/src/__tests__/execution-utils.ts +0 -124
  16. package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +0 -195
  17. package/src/__tests__/gateway/buildService.test.ts +0 -249
  18. package/src/__tests__/gateway/endToEnd.test.ts +0 -486
  19. package/src/__tests__/gateway/executor.test.ts +0 -96
  20. package/src/__tests__/gateway/extensions.test.ts +0 -37
  21. package/src/__tests__/gateway/lifecycle-hooks.test.ts +0 -239
  22. package/src/__tests__/gateway/opentelemetry.test.ts +0 -123
  23. package/src/__tests__/gateway/queryPlanCache.test.ts +0 -231
  24. package/src/__tests__/gateway/queryPlannerConfig.test.ts +0 -101
  25. package/src/__tests__/gateway/reporting.test.ts +0 -616
  26. package/src/__tests__/gateway/supergraphSdl.test.ts +0 -396
  27. package/src/__tests__/gateway/testUtils.ts +0 -89
  28. package/src/__tests__/integration/abstract-types.test.ts +0 -1861
  29. package/src/__tests__/integration/aliases.test.ts +0 -180
  30. package/src/__tests__/integration/boolean.test.ts +0 -279
  31. package/src/__tests__/integration/complex-key.test.ts +0 -197
  32. package/src/__tests__/integration/configuration.test.ts +0 -404
  33. package/src/__tests__/integration/custom-directives.test.ts +0 -174
  34. package/src/__tests__/integration/execution-style.test.ts +0 -35
  35. package/src/__tests__/integration/fragments.test.ts +0 -237
  36. package/src/__tests__/integration/list-key.test.ts +0 -128
  37. package/src/__tests__/integration/logger.test.ts +0 -122
  38. package/src/__tests__/integration/managed.test.ts +0 -319
  39. package/src/__tests__/integration/merge-arrays.test.ts +0 -34
  40. package/src/__tests__/integration/multiple-key.test.ts +0 -327
  41. package/src/__tests__/integration/mutations.test.ts +0 -287
  42. package/src/__tests__/integration/networkRequests.test.ts +0 -542
  43. package/src/__tests__/integration/nockMocks.ts +0 -157
  44. package/src/__tests__/integration/provides.test.ts +0 -77
  45. package/src/__tests__/integration/requires.test.ts +0 -359
  46. package/src/__tests__/integration/scope.test.ts +0 -557
  47. package/src/__tests__/integration/single-service.test.ts +0 -119
  48. package/src/__tests__/integration/unions.test.ts +0 -79
  49. package/src/__tests__/integration/value-types.test.ts +0 -382
  50. package/src/__tests__/integration/variables.test.ts +0 -120
  51. package/src/__tests__/nockAssertions.ts +0 -20
  52. package/src/__tests__/queryPlanCucumber.test.ts +0 -55
  53. package/src/__tests__/resultShaping.test.ts +0 -605
  54. package/src/__tests__/testSetup.ts +0 -1
  55. package/src/__tests__/tsconfig.json +0 -8
  56. package/src/core/__tests__/core.test.ts +0 -412
  57. package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +0 -51
  58. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +0 -574
  59. package/src/schema-helper/__tests__/addExtensions.test.ts +0 -70
  60. package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +0 -364
  61. package/src/supergraphManagers/IntrospectAndCompose/__tests__/loadServicesFromRemoteEndpoint.test.ts +0 -40
  62. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/UplinkSupergraphManager.test.ts +0 -65
  63. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/loadSupergraphSdlFromStorage.test.ts +0 -511
  64. 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
- });