@apollo/gateway 0.300.0-alpha.2 → 2.0.0-alpha.2
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/LICENSE +95 -0
- package/README.md +1 -1
- package/dist/__generated__/graphqlTypes.d.ts +130 -0
- package/dist/__generated__/graphqlTypes.d.ts.map +1 -0
- package/dist/__generated__/graphqlTypes.js +25 -0
- package/dist/__generated__/graphqlTypes.js.map +1 -0
- package/dist/config.d.ts +104 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +47 -0
- package/dist/config.js.map +1 -0
- package/dist/datasources/LocalGraphQLDataSource.d.ts +3 -3
- package/dist/datasources/LocalGraphQLDataSource.d.ts.map +1 -1
- package/dist/datasources/LocalGraphQLDataSource.js +5 -5
- package/dist/datasources/LocalGraphQLDataSource.js.map +1 -1
- package/dist/datasources/RemoteGraphQLDataSource.d.ts +6 -4
- package/dist/datasources/RemoteGraphQLDataSource.d.ts.map +1 -1
- package/dist/datasources/RemoteGraphQLDataSource.js +60 -17
- package/dist/datasources/RemoteGraphQLDataSource.js.map +1 -1
- package/dist/datasources/index.d.ts +1 -1
- package/dist/datasources/index.d.ts.map +1 -1
- package/dist/datasources/index.js +1 -0
- package/dist/datasources/index.js.map +1 -1
- package/dist/datasources/parseCacheControlHeader.d.ts +2 -0
- package/dist/datasources/parseCacheControlHeader.d.ts.map +1 -0
- package/dist/datasources/parseCacheControlHeader.js +16 -0
- package/dist/datasources/parseCacheControlHeader.js.map +1 -0
- package/dist/datasources/types.d.ts +16 -1
- package/dist/datasources/types.d.ts.map +1 -1
- package/dist/datasources/types.js +7 -0
- package/dist/datasources/types.js.map +1 -1
- package/dist/executeQueryPlan.d.ts +2 -1
- package/dist/executeQueryPlan.d.ts.map +1 -1
- package/dist/executeQueryPlan.js +199 -112
- package/dist/executeQueryPlan.js.map +1 -1
- package/dist/index.d.ts +62 -80
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +543 -234
- package/dist/index.js.map +1 -1
- package/dist/loadServicesFromRemoteEndpoint.d.ts +9 -9
- package/dist/loadServicesFromRemoteEndpoint.d.ts.map +1 -1
- package/dist/loadServicesFromRemoteEndpoint.js +13 -8
- package/dist/loadServicesFromRemoteEndpoint.js.map +1 -1
- package/dist/loadSupergraphSdlFromStorage.d.ts +13 -0
- package/dist/loadSupergraphSdlFromStorage.d.ts.map +1 -0
- package/dist/loadSupergraphSdlFromStorage.js +101 -0
- package/dist/loadSupergraphSdlFromStorage.js.map +1 -0
- package/dist/operationContext.d.ts +17 -0
- package/dist/operationContext.d.ts.map +1 -0
- package/dist/operationContext.js +42 -0
- package/dist/operationContext.js.map +1 -0
- package/dist/outOfBandReporter.d.ts +15 -0
- package/dist/outOfBandReporter.d.ts.map +1 -0
- package/dist/outOfBandReporter.js +88 -0
- package/dist/outOfBandReporter.js.map +1 -0
- package/dist/utilities/array.d.ts +1 -2
- package/dist/utilities/array.d.ts.map +1 -1
- package/dist/utilities/array.js +7 -14
- package/dist/utilities/array.js.map +1 -1
- package/dist/utilities/assert.d.ts +2 -0
- package/dist/utilities/assert.d.ts.map +1 -0
- package/dist/utilities/assert.js +10 -0
- package/dist/utilities/assert.js.map +1 -0
- package/dist/utilities/cleanErrorOfInaccessibleNames.d.ts +3 -0
- package/dist/utilities/cleanErrorOfInaccessibleNames.d.ts.map +1 -0
- package/dist/utilities/cleanErrorOfInaccessibleNames.js +27 -0
- package/dist/utilities/cleanErrorOfInaccessibleNames.js.map +1 -0
- package/dist/utilities/deepMerge.js +2 -2
- package/dist/utilities/deepMerge.js.map +1 -1
- package/dist/utilities/graphql.d.ts +1 -4
- package/dist/utilities/graphql.d.ts.map +1 -1
- package/dist/utilities/graphql.js +3 -36
- package/dist/utilities/graphql.js.map +1 -1
- package/dist/utilities/opentelemetry.d.ts +10 -0
- package/dist/utilities/opentelemetry.d.ts.map +1 -0
- package/dist/utilities/opentelemetry.js +19 -0
- package/dist/utilities/opentelemetry.js.map +1 -0
- package/package.json +30 -21
- package/src/__generated__/graphqlTypes.ts +140 -0
- package/src/__mocks__/apollo-server-env.ts +56 -0
- package/src/__mocks__/make-fetch-happen-fetcher.ts +55 -0
- package/src/__mocks__/tsconfig.json +7 -0
- package/src/__tests__/build-query-plan.feature +40 -311
- package/src/__tests__/buildQueryPlan.test.ts +246 -426
- package/src/__tests__/executeQueryPlan.test.ts +1691 -194
- package/src/__tests__/execution-utils.ts +33 -26
- package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +195 -0
- package/src/__tests__/gateway/buildService.test.ts +16 -19
- package/src/__tests__/gateway/composedSdl.test.ts +44 -0
- package/src/__tests__/gateway/endToEnd.test.ts +166 -0
- package/src/__tests__/gateway/executor.test.ts +49 -43
- package/src/__tests__/gateway/lifecycle-hooks.test.ts +58 -29
- package/src/__tests__/gateway/opentelemetry.test.ts +123 -0
- package/src/__tests__/gateway/queryPlanCache.test.ts +19 -20
- package/src/__tests__/gateway/reporting.test.ts +76 -55
- package/src/__tests__/integration/abstract-types.test.ts +1086 -22
- package/src/__tests__/integration/aliases.test.ts +5 -6
- package/src/__tests__/integration/boolean.test.ts +40 -38
- package/src/__tests__/integration/complex-key.test.ts +41 -56
- package/src/__tests__/integration/configuration.test.ts +321 -0
- package/src/__tests__/integration/custom-directives.test.ts +61 -46
- package/src/__tests__/integration/fragments.test.ts +8 -2
- package/src/__tests__/integration/list-key.test.ts +2 -2
- package/src/__tests__/integration/logger.test.ts +2 -2
- package/src/__tests__/integration/multiple-key.test.ts +11 -12
- package/src/__tests__/integration/mutations.test.ts +8 -5
- package/src/__tests__/integration/networkRequests.test.ts +447 -289
- package/src/__tests__/integration/nockMocks.ts +95 -66
- package/src/__tests__/integration/provides.test.ts +9 -6
- package/src/__tests__/integration/requires.test.ts +17 -15
- package/src/__tests__/integration/scope.test.ts +557 -0
- package/src/__tests__/integration/unions.test.ts +1 -1
- package/src/__tests__/integration/value-types.test.ts +35 -32
- package/src/__tests__/integration/variables.test.ts +8 -2
- package/src/__tests__/loadServicesFromRemoteEndpoint.test.ts +6 -2
- package/src/__tests__/loadSupergraphSdlFromStorage.test.ts +694 -0
- package/src/__tests__/queryPlanCucumber.test.ts +11 -61
- package/src/__tests__/testSetup.ts +1 -4
- package/src/__tests__/tsconfig.json +2 -1
- package/src/config.ts +225 -0
- package/src/core/__tests__/core.test.ts +412 -0
- package/src/datasources/LocalGraphQLDataSource.ts +9 -10
- package/src/datasources/RemoteGraphQLDataSource.ts +117 -43
- package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +11 -4
- package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +148 -79
- package/src/datasources/__tests__/tsconfig.json +4 -2
- package/src/datasources/index.ts +1 -1
- package/src/datasources/parseCacheControlHeader.ts +43 -0
- package/src/datasources/types.ts +47 -2
- package/src/executeQueryPlan.ts +264 -153
- package/src/index.ts +925 -480
- package/src/loadServicesFromRemoteEndpoint.ts +24 -17
- package/src/loadSupergraphSdlFromStorage.ts +140 -0
- package/src/make-fetch-happen.d.ts +2 -2
- package/src/operationContext.ts +70 -0
- package/src/outOfBandReporter.ts +128 -0
- package/src/utilities/__tests__/cleanErrorOfInaccessibleElements.test.ts +104 -0
- package/src/utilities/__tests__/tsconfig.json +8 -0
- package/src/utilities/array.ts +6 -28
- package/src/utilities/assert.ts +14 -0
- package/src/utilities/cleanErrorOfInaccessibleNames.ts +29 -0
- package/src/utilities/graphql.ts +0 -64
- package/src/utilities/opentelemetry.ts +13 -0
- package/CHANGELOG.md +0 -226
- package/LICENSE.md +0 -20
- package/dist/FieldSet.d.ts +0 -18
- package/dist/FieldSet.d.ts.map +0 -1
- package/dist/FieldSet.js +0 -96
- package/dist/FieldSet.js.map +0 -1
- package/dist/QueryPlan.d.ts +0 -41
- package/dist/QueryPlan.d.ts.map +0 -1
- package/dist/QueryPlan.js +0 -15
- package/dist/QueryPlan.js.map +0 -1
- package/dist/buildQueryPlan.d.ts +0 -44
- package/dist/buildQueryPlan.d.ts.map +0 -1
- package/dist/buildQueryPlan.js +0 -670
- package/dist/buildQueryPlan.js.map +0 -1
- package/dist/loadServicesFromStorage.d.ts +0 -21
- package/dist/loadServicesFromStorage.d.ts.map +0 -1
- package/dist/loadServicesFromStorage.js +0 -64
- package/dist/loadServicesFromStorage.js.map +0 -1
- package/dist/snapshotSerializers/astSerializer.d.ts +0 -3
- package/dist/snapshotSerializers/astSerializer.d.ts.map +0 -1
- package/dist/snapshotSerializers/astSerializer.js +0 -14
- package/dist/snapshotSerializers/astSerializer.js.map +0 -1
- package/dist/snapshotSerializers/index.d.ts +0 -13
- package/dist/snapshotSerializers/index.d.ts.map +0 -1
- package/dist/snapshotSerializers/index.js +0 -15
- package/dist/snapshotSerializers/index.js.map +0 -1
- package/dist/snapshotSerializers/queryPlanSerializer.d.ts +0 -3
- package/dist/snapshotSerializers/queryPlanSerializer.d.ts.map +0 -1
- package/dist/snapshotSerializers/queryPlanSerializer.js +0 -78
- package/dist/snapshotSerializers/queryPlanSerializer.js.map +0 -1
- package/dist/snapshotSerializers/selectionSetSerializer.d.ts +0 -3
- package/dist/snapshotSerializers/selectionSetSerializer.d.ts.map +0 -1
- package/dist/snapshotSerializers/selectionSetSerializer.js +0 -12
- package/dist/snapshotSerializers/selectionSetSerializer.js.map +0 -1
- package/dist/snapshotSerializers/typeSerializer.d.ts +0 -3
- package/dist/snapshotSerializers/typeSerializer.d.ts.map +0 -1
- package/dist/snapshotSerializers/typeSerializer.js +0 -12
- package/dist/snapshotSerializers/typeSerializer.js.map +0 -1
- package/dist/utilities/MultiMap.d.ts +0 -4
- package/dist/utilities/MultiMap.d.ts.map +0 -1
- package/dist/utilities/MultiMap.js +0 -17
- package/dist/utilities/MultiMap.js.map +0 -1
- package/src/FieldSet.ts +0 -169
- package/src/QueryPlan.ts +0 -57
- package/src/__tests__/matchers/toCallService.ts +0 -105
- package/src/__tests__/matchers/toHaveBeenCalledBefore.ts +0 -40
- package/src/__tests__/matchers/toHaveFetched.ts +0 -81
- package/src/__tests__/matchers/toMatchAST.ts +0 -64
- package/src/buildQueryPlan.ts +0 -1190
- package/src/loadServicesFromStorage.ts +0 -170
- package/src/snapshotSerializers/astSerializer.ts +0 -21
- package/src/snapshotSerializers/index.ts +0 -21
- package/src/snapshotSerializers/queryPlanSerializer.ts +0 -144
- package/src/snapshotSerializers/selectionSetSerializer.ts +0 -13
- package/src/snapshotSerializers/typeSerializer.ts +0 -11
- package/src/utilities/MultiMap.ts +0 -11
|
@@ -1,43 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import gql from 'graphql-tag';
|
|
3
|
-
import { buildQueryPlan, buildOperationContext } from '../buildQueryPlan';
|
|
4
|
-
import { astSerializer, queryPlanSerializer } from '../snapshotSerializers';
|
|
1
|
+
import { astSerializer, queryPlanSerializer } from 'apollo-federation-integration-testsuite';
|
|
5
2
|
import { getFederatedTestingSchema } from './execution-utils';
|
|
3
|
+
import { QueryPlan, QueryPlanner } from '@apollo/query-planner';
|
|
4
|
+
import { Schema, parseOperation } from '@apollo/federation-internals';
|
|
6
5
|
|
|
7
6
|
expect.addSnapshotSerializer(astSerializer);
|
|
8
7
|
expect.addSnapshotSerializer(queryPlanSerializer);
|
|
9
8
|
|
|
9
|
+
|
|
10
10
|
describe('buildQueryPlan', () => {
|
|
11
|
-
let schema:
|
|
12
|
-
let
|
|
11
|
+
let schema: Schema;
|
|
12
|
+
let queryPlanner: QueryPlanner;
|
|
13
|
+
|
|
14
|
+
const buildPlan = (operation: string): QueryPlan => {
|
|
15
|
+
return queryPlanner.buildQueryPlan(parseOperation(schema, operation));
|
|
16
|
+
}
|
|
13
17
|
|
|
14
18
|
beforeEach(() => {
|
|
15
|
-
(
|
|
16
|
-
|
|
19
|
+
expect(
|
|
20
|
+
() => ({ schema, queryPlanner } = getFederatedTestingSchema()),
|
|
21
|
+
).not.toThrow();
|
|
17
22
|
});
|
|
18
23
|
|
|
19
24
|
it(`should not confuse union types with overlapping field names`, () => {
|
|
20
|
-
const
|
|
25
|
+
const operationString = `#graphql
|
|
21
26
|
query {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
body {
|
|
28
|
+
... on Image {
|
|
29
|
+
attributes {
|
|
30
|
+
url
|
|
31
|
+
}
|
|
26
32
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
... on Text {
|
|
34
|
+
attributes {
|
|
35
|
+
bold
|
|
36
|
+
text
|
|
37
|
+
}
|
|
32
38
|
}
|
|
33
39
|
}
|
|
34
40
|
}
|
|
35
|
-
}
|
|
36
41
|
`;
|
|
37
|
-
|
|
38
|
-
const queryPlan = buildQueryPlan(
|
|
39
|
-
buildOperationContext(schema, query, undefined),
|
|
40
|
-
);
|
|
42
|
+
const queryPlan = buildPlan(operationString);
|
|
41
43
|
|
|
42
44
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
43
45
|
QueryPlan {
|
|
@@ -64,22 +66,25 @@ describe('buildQueryPlan', () => {
|
|
|
64
66
|
});
|
|
65
67
|
|
|
66
68
|
it(`should use a single fetch when requesting a root field from one service`, () => {
|
|
67
|
-
const
|
|
69
|
+
const operationString = `#graphql
|
|
68
70
|
query {
|
|
69
71
|
me {
|
|
70
|
-
name
|
|
72
|
+
name {
|
|
73
|
+
first
|
|
74
|
+
}
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
`;
|
|
74
78
|
|
|
75
|
-
const queryPlan =
|
|
76
|
-
|
|
79
|
+
const queryPlan = buildPlan(operationString);
|
|
77
80
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
78
81
|
QueryPlan {
|
|
79
82
|
Fetch(service: "accounts") {
|
|
80
83
|
{
|
|
81
84
|
me {
|
|
82
|
-
name
|
|
85
|
+
name {
|
|
86
|
+
first
|
|
87
|
+
}
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
},
|
|
@@ -88,10 +93,12 @@ describe('buildQueryPlan', () => {
|
|
|
88
93
|
});
|
|
89
94
|
|
|
90
95
|
it(`should use two independent fetches when requesting root fields from two services`, () => {
|
|
91
|
-
const
|
|
96
|
+
const operationString = `#graphql
|
|
92
97
|
query {
|
|
93
98
|
me {
|
|
94
|
-
name
|
|
99
|
+
name {
|
|
100
|
+
first
|
|
101
|
+
}
|
|
95
102
|
}
|
|
96
103
|
topProducts {
|
|
97
104
|
name
|
|
@@ -99,7 +106,7 @@ describe('buildQueryPlan', () => {
|
|
|
99
106
|
}
|
|
100
107
|
`;
|
|
101
108
|
|
|
102
|
-
const queryPlan =
|
|
109
|
+
const queryPlan = buildPlan(operationString);
|
|
103
110
|
|
|
104
111
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
105
112
|
QueryPlan {
|
|
@@ -107,7 +114,9 @@ describe('buildQueryPlan', () => {
|
|
|
107
114
|
Fetch(service: "accounts") {
|
|
108
115
|
{
|
|
109
116
|
me {
|
|
110
|
-
name
|
|
117
|
+
name {
|
|
118
|
+
first
|
|
119
|
+
}
|
|
111
120
|
}
|
|
112
121
|
}
|
|
113
122
|
},
|
|
@@ -136,8 +145,6 @@ describe('buildQueryPlan', () => {
|
|
|
136
145
|
} =>
|
|
137
146
|
{
|
|
138
147
|
... on Book {
|
|
139
|
-
__typename
|
|
140
|
-
isbn
|
|
141
148
|
title
|
|
142
149
|
year
|
|
143
150
|
}
|
|
@@ -149,9 +156,9 @@ describe('buildQueryPlan', () => {
|
|
|
149
156
|
{
|
|
150
157
|
... on Book {
|
|
151
158
|
__typename
|
|
152
|
-
isbn
|
|
153
159
|
title
|
|
154
160
|
year
|
|
161
|
+
isbn
|
|
155
162
|
}
|
|
156
163
|
} =>
|
|
157
164
|
{
|
|
@@ -168,7 +175,7 @@ describe('buildQueryPlan', () => {
|
|
|
168
175
|
});
|
|
169
176
|
|
|
170
177
|
it(`should use a single fetch when requesting multiple root fields from the same service`, () => {
|
|
171
|
-
const
|
|
178
|
+
const operationString = `#graphql
|
|
172
179
|
query {
|
|
173
180
|
topProducts {
|
|
174
181
|
name
|
|
@@ -179,7 +186,7 @@ describe('buildQueryPlan', () => {
|
|
|
179
186
|
}
|
|
180
187
|
`;
|
|
181
188
|
|
|
182
|
-
const queryPlan =
|
|
189
|
+
const queryPlan = buildPlan(operationString);
|
|
183
190
|
|
|
184
191
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
185
192
|
QueryPlan {
|
|
@@ -220,8 +227,6 @@ describe('buildQueryPlan', () => {
|
|
|
220
227
|
} =>
|
|
221
228
|
{
|
|
222
229
|
... on Book {
|
|
223
|
-
__typename
|
|
224
|
-
isbn
|
|
225
230
|
title
|
|
226
231
|
year
|
|
227
232
|
}
|
|
@@ -233,9 +238,9 @@ describe('buildQueryPlan', () => {
|
|
|
233
238
|
{
|
|
234
239
|
... on Book {
|
|
235
240
|
__typename
|
|
236
|
-
isbn
|
|
237
241
|
title
|
|
238
242
|
year
|
|
243
|
+
isbn
|
|
239
244
|
}
|
|
240
245
|
} =>
|
|
241
246
|
{
|
|
@@ -257,8 +262,6 @@ describe('buildQueryPlan', () => {
|
|
|
257
262
|
} =>
|
|
258
263
|
{
|
|
259
264
|
... on Book {
|
|
260
|
-
__typename
|
|
261
|
-
isbn
|
|
262
265
|
title
|
|
263
266
|
year
|
|
264
267
|
}
|
|
@@ -270,9 +273,9 @@ describe('buildQueryPlan', () => {
|
|
|
270
273
|
{
|
|
271
274
|
... on Book {
|
|
272
275
|
__typename
|
|
273
|
-
isbn
|
|
274
276
|
title
|
|
275
277
|
year
|
|
278
|
+
isbn
|
|
276
279
|
}
|
|
277
280
|
} =>
|
|
278
281
|
{
|
|
@@ -290,7 +293,7 @@ describe('buildQueryPlan', () => {
|
|
|
290
293
|
});
|
|
291
294
|
|
|
292
295
|
it(`should use a single fetch when requesting relationship subfields from the same service`, () => {
|
|
293
|
-
const
|
|
296
|
+
const operationString = `#graphql
|
|
294
297
|
query {
|
|
295
298
|
topReviews {
|
|
296
299
|
body
|
|
@@ -303,7 +306,7 @@ describe('buildQueryPlan', () => {
|
|
|
303
306
|
}
|
|
304
307
|
`;
|
|
305
308
|
|
|
306
|
-
const queryPlan =
|
|
309
|
+
const queryPlan = buildPlan(operationString);
|
|
307
310
|
|
|
308
311
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
309
312
|
QueryPlan {
|
|
@@ -324,7 +327,7 @@ describe('buildQueryPlan', () => {
|
|
|
324
327
|
});
|
|
325
328
|
|
|
326
329
|
it(`should use a single fetch when requesting relationship subfields and provided keys from the same service`, () => {
|
|
327
|
-
const
|
|
330
|
+
const operationString = `#graphql
|
|
328
331
|
query {
|
|
329
332
|
topReviews {
|
|
330
333
|
body
|
|
@@ -338,7 +341,7 @@ describe('buildQueryPlan', () => {
|
|
|
338
341
|
}
|
|
339
342
|
`;
|
|
340
343
|
|
|
341
|
-
const queryPlan =
|
|
344
|
+
const queryPlan = buildPlan(operationString);
|
|
342
345
|
|
|
343
346
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
344
347
|
QueryPlan {
|
|
@@ -361,10 +364,12 @@ describe('buildQueryPlan', () => {
|
|
|
361
364
|
|
|
362
365
|
describe(`when requesting an extension field from another service`, () => {
|
|
363
366
|
it(`should add the field's representation requirements to the parent selection set and use a dependent fetch`, () => {
|
|
364
|
-
const
|
|
367
|
+
const operationString = `#graphql
|
|
365
368
|
query {
|
|
366
369
|
me {
|
|
367
|
-
name
|
|
370
|
+
name {
|
|
371
|
+
first
|
|
372
|
+
}
|
|
368
373
|
reviews {
|
|
369
374
|
body
|
|
370
375
|
}
|
|
@@ -372,7 +377,7 @@ describe('buildQueryPlan', () => {
|
|
|
372
377
|
}
|
|
373
378
|
`;
|
|
374
379
|
|
|
375
|
-
const queryPlan =
|
|
380
|
+
const queryPlan = buildPlan(operationString);
|
|
376
381
|
|
|
377
382
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
378
383
|
QueryPlan {
|
|
@@ -380,9 +385,11 @@ describe('buildQueryPlan', () => {
|
|
|
380
385
|
Fetch(service: "accounts") {
|
|
381
386
|
{
|
|
382
387
|
me {
|
|
383
|
-
name
|
|
384
388
|
__typename
|
|
385
389
|
id
|
|
390
|
+
name {
|
|
391
|
+
first
|
|
392
|
+
}
|
|
386
393
|
}
|
|
387
394
|
}
|
|
388
395
|
},
|
|
@@ -410,7 +417,7 @@ describe('buildQueryPlan', () => {
|
|
|
410
417
|
|
|
411
418
|
describe(`when the parent selection set is empty`, () => {
|
|
412
419
|
it(`should add the field's requirements to the parent selection set and use a dependent fetch`, () => {
|
|
413
|
-
const
|
|
420
|
+
const operationString = `#graphql
|
|
414
421
|
query {
|
|
415
422
|
me {
|
|
416
423
|
reviews {
|
|
@@ -420,7 +427,7 @@ describe('buildQueryPlan', () => {
|
|
|
420
427
|
}
|
|
421
428
|
`;
|
|
422
429
|
|
|
423
|
-
const queryPlan =
|
|
430
|
+
const queryPlan = buildPlan(operationString);
|
|
424
431
|
|
|
425
432
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
426
433
|
QueryPlan {
|
|
@@ -458,7 +465,7 @@ describe('buildQueryPlan', () => {
|
|
|
458
465
|
|
|
459
466
|
// TODO: Ask martijn about the meaning of this test
|
|
460
467
|
it(`should only add requirements once`, () => {
|
|
461
|
-
const
|
|
468
|
+
const operationString = `#graphql
|
|
462
469
|
query {
|
|
463
470
|
me {
|
|
464
471
|
reviews {
|
|
@@ -469,7 +476,7 @@ describe('buildQueryPlan', () => {
|
|
|
469
476
|
}
|
|
470
477
|
`;
|
|
471
478
|
|
|
472
|
-
const queryPlan =
|
|
479
|
+
const queryPlan = buildPlan(operationString);
|
|
473
480
|
|
|
474
481
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
475
482
|
QueryPlan {
|
|
@@ -508,18 +515,20 @@ describe('buildQueryPlan', () => {
|
|
|
508
515
|
|
|
509
516
|
describe(`when requesting a composite field with subfields from another service`, () => {
|
|
510
517
|
it(`should add key fields to the parent selection set and use a dependent fetch`, () => {
|
|
511
|
-
|
|
518
|
+
const operationString = `#graphql
|
|
512
519
|
query {
|
|
513
520
|
topReviews {
|
|
514
521
|
body
|
|
515
522
|
author {
|
|
516
|
-
name
|
|
523
|
+
name {
|
|
524
|
+
first
|
|
525
|
+
}
|
|
517
526
|
}
|
|
518
527
|
}
|
|
519
528
|
}
|
|
520
529
|
`;
|
|
521
530
|
|
|
522
|
-
const queryPlan =
|
|
531
|
+
const queryPlan = buildPlan(operationString);
|
|
523
532
|
|
|
524
533
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
525
534
|
QueryPlan {
|
|
@@ -545,7 +554,9 @@ describe('buildQueryPlan', () => {
|
|
|
545
554
|
} =>
|
|
546
555
|
{
|
|
547
556
|
... on User {
|
|
548
|
-
name
|
|
557
|
+
name {
|
|
558
|
+
first
|
|
559
|
+
}
|
|
549
560
|
}
|
|
550
561
|
}
|
|
551
562
|
},
|
|
@@ -557,7 +568,7 @@ describe('buildQueryPlan', () => {
|
|
|
557
568
|
|
|
558
569
|
describe(`when requesting a field defined in another service which requires a field in the base service`, () => {
|
|
559
570
|
it(`should add the field provided by base service in first Fetch`, () => {
|
|
560
|
-
const
|
|
571
|
+
const operationString = `#graphql
|
|
561
572
|
query {
|
|
562
573
|
topCars {
|
|
563
574
|
retailPrice
|
|
@@ -565,7 +576,7 @@ describe('buildQueryPlan', () => {
|
|
|
565
576
|
}
|
|
566
577
|
`;
|
|
567
578
|
|
|
568
|
-
const queryPlan =
|
|
579
|
+
const queryPlan = buildPlan(operationString);
|
|
569
580
|
|
|
570
581
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
571
582
|
QueryPlan {
|
|
@@ -603,17 +614,19 @@ describe('buildQueryPlan', () => {
|
|
|
603
614
|
|
|
604
615
|
describe(`when the parent selection set is empty`, () => {
|
|
605
616
|
it(`should add key fields to the parent selection set and use a dependent fetch`, () => {
|
|
606
|
-
const
|
|
617
|
+
const operationString = `#graphql
|
|
607
618
|
query {
|
|
608
619
|
topReviews {
|
|
609
620
|
author {
|
|
610
|
-
name
|
|
621
|
+
name {
|
|
622
|
+
first
|
|
623
|
+
}
|
|
611
624
|
}
|
|
612
625
|
}
|
|
613
626
|
}
|
|
614
627
|
`;
|
|
615
628
|
|
|
616
|
-
const queryPlan =
|
|
629
|
+
const queryPlan = buildPlan(operationString);
|
|
617
630
|
|
|
618
631
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
619
632
|
QueryPlan {
|
|
@@ -638,7 +651,9 @@ describe('buildQueryPlan', () => {
|
|
|
638
651
|
} =>
|
|
639
652
|
{
|
|
640
653
|
... on User {
|
|
641
|
-
name
|
|
654
|
+
name {
|
|
655
|
+
first
|
|
656
|
+
}
|
|
642
657
|
}
|
|
643
658
|
}
|
|
644
659
|
},
|
|
@@ -651,7 +666,7 @@ describe('buildQueryPlan', () => {
|
|
|
651
666
|
});
|
|
652
667
|
describe(`when requesting a relationship field with extension subfields from a different service`, () => {
|
|
653
668
|
it(`should first fetch the object using a key from the base service and then pass through the requirements`, () => {
|
|
654
|
-
const
|
|
669
|
+
const operationString = `#graphql
|
|
655
670
|
query {
|
|
656
671
|
topReviews {
|
|
657
672
|
author {
|
|
@@ -661,7 +676,7 @@ describe('buildQueryPlan', () => {
|
|
|
661
676
|
}
|
|
662
677
|
`;
|
|
663
678
|
|
|
664
|
-
const queryPlan =
|
|
679
|
+
const queryPlan = buildPlan(operationString);
|
|
665
680
|
|
|
666
681
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
667
682
|
QueryPlan {
|
|
@@ -702,7 +717,7 @@ describe('buildQueryPlan', () => {
|
|
|
702
717
|
// Probably an issue with extending / interfaces in composition. None of the fields from the base Book type
|
|
703
718
|
// are showing up in the resulting schema.
|
|
704
719
|
it(`should add __typename when fetching objects of an interface type from a service`, () => {
|
|
705
|
-
const
|
|
720
|
+
const operationString = `#graphql
|
|
706
721
|
query {
|
|
707
722
|
topProducts {
|
|
708
723
|
price
|
|
@@ -710,7 +725,7 @@ describe('buildQueryPlan', () => {
|
|
|
710
725
|
}
|
|
711
726
|
`;
|
|
712
727
|
|
|
713
|
-
const queryPlan =
|
|
728
|
+
const queryPlan = buildPlan(operationString);
|
|
714
729
|
|
|
715
730
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
716
731
|
QueryPlan {
|
|
@@ -718,25 +733,164 @@ describe('buildQueryPlan', () => {
|
|
|
718
733
|
{
|
|
719
734
|
topProducts {
|
|
720
735
|
__typename
|
|
721
|
-
|
|
722
|
-
price
|
|
723
|
-
}
|
|
724
|
-
... on Furniture {
|
|
725
|
-
price
|
|
726
|
-
}
|
|
736
|
+
price
|
|
727
737
|
}
|
|
728
738
|
}
|
|
729
739
|
},
|
|
730
740
|
}
|
|
731
741
|
`);
|
|
732
742
|
});
|
|
743
|
+
|
|
744
|
+
it(`should not get confused by a fragment spread multiple times`, () => {
|
|
745
|
+
const operationString = `#graphql
|
|
746
|
+
fragment Price on Product {
|
|
747
|
+
price
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
query {
|
|
751
|
+
topProducts {
|
|
752
|
+
__typename
|
|
753
|
+
... on Book {
|
|
754
|
+
...Price
|
|
755
|
+
}
|
|
756
|
+
... on Furniture {
|
|
757
|
+
...Price
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
`;
|
|
762
|
+
|
|
763
|
+
const queryPlan = buildPlan(operationString);
|
|
764
|
+
|
|
765
|
+
expect(queryPlan).toMatchInlineSnapshot(`
|
|
766
|
+
QueryPlan {
|
|
767
|
+
Fetch(service: "product") {
|
|
768
|
+
{
|
|
769
|
+
topProducts {
|
|
770
|
+
__typename
|
|
771
|
+
... on Book {
|
|
772
|
+
price
|
|
773
|
+
}
|
|
774
|
+
... on Furniture {
|
|
775
|
+
price
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
},
|
|
780
|
+
}
|
|
781
|
+
`);
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
it(`should not get confused by an inline fragment multiple times`, () => {
|
|
785
|
+
const operationString = `#graphql
|
|
786
|
+
query {
|
|
787
|
+
topProducts {
|
|
788
|
+
__typename
|
|
789
|
+
... on Book {
|
|
790
|
+
...on Product {
|
|
791
|
+
price
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
... on Furniture {
|
|
795
|
+
... on Product {
|
|
796
|
+
price
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
`;
|
|
802
|
+
|
|
803
|
+
const queryPlan = buildPlan(operationString);
|
|
804
|
+
|
|
805
|
+
expect(queryPlan).toMatchInlineSnapshot(`
|
|
806
|
+
QueryPlan {
|
|
807
|
+
Fetch(service: "product") {
|
|
808
|
+
{
|
|
809
|
+
topProducts {
|
|
810
|
+
__typename
|
|
811
|
+
... on Book {
|
|
812
|
+
price
|
|
813
|
+
}
|
|
814
|
+
... on Furniture {
|
|
815
|
+
price
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
}
|
|
821
|
+
`);
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
it(`eliminate unecessary type conditions`, () => {
|
|
825
|
+
const operationString = `#graphql
|
|
826
|
+
query {
|
|
827
|
+
body {
|
|
828
|
+
... on Image {
|
|
829
|
+
... on NamedObject {
|
|
830
|
+
name
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
`;
|
|
836
|
+
|
|
837
|
+
const queryPlan = buildPlan(operationString);
|
|
838
|
+
|
|
839
|
+
expect(queryPlan).toMatchInlineSnapshot(`
|
|
840
|
+
QueryPlan {
|
|
841
|
+
Fetch(service: "documents") {
|
|
842
|
+
{
|
|
843
|
+
body {
|
|
844
|
+
__typename
|
|
845
|
+
... on Image {
|
|
846
|
+
name
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
}
|
|
852
|
+
`);
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
it(`should preserve directives on inline fragments even if the fragment is otherwise useless`, () => {
|
|
856
|
+
const operationString = `#graphql
|
|
857
|
+
query myQuery($b: Boolean!) {
|
|
858
|
+
body {
|
|
859
|
+
... on Image {
|
|
860
|
+
... on NamedObject @include(if: $b) {
|
|
861
|
+
name
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
`;
|
|
867
|
+
|
|
868
|
+
const queryPlan = buildPlan(operationString);
|
|
869
|
+
|
|
870
|
+
expect(queryPlan).toMatchInlineSnapshot(`
|
|
871
|
+
QueryPlan {
|
|
872
|
+
Fetch(service: "documents") {
|
|
873
|
+
{
|
|
874
|
+
body {
|
|
875
|
+
__typename
|
|
876
|
+
... on Image {
|
|
877
|
+
... on NamedObject @include(if: $b) {
|
|
878
|
+
name
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
},
|
|
884
|
+
}
|
|
885
|
+
`);
|
|
886
|
+
});
|
|
733
887
|
});
|
|
734
888
|
|
|
735
889
|
// GraphQLError: Cannot query field "isbn" on type "Book"
|
|
736
890
|
// Probably an issue with extending / interfaces in composition. None of the fields from the base Book type
|
|
737
891
|
// are showing up in the resulting schema.
|
|
738
892
|
it(`should break up when traversing an extension field on an interface type from a service`, () => {
|
|
739
|
-
const
|
|
893
|
+
const operationString = `#graphql
|
|
740
894
|
query {
|
|
741
895
|
topProducts {
|
|
742
896
|
price
|
|
@@ -747,7 +901,7 @@ describe('buildQueryPlan', () => {
|
|
|
747
901
|
}
|
|
748
902
|
`;
|
|
749
903
|
|
|
750
|
-
const queryPlan =
|
|
904
|
+
const queryPlan = buildPlan(operationString);
|
|
751
905
|
|
|
752
906
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
753
907
|
QueryPlan {
|
|
@@ -756,13 +910,12 @@ describe('buildQueryPlan', () => {
|
|
|
756
910
|
{
|
|
757
911
|
topProducts {
|
|
758
912
|
__typename
|
|
913
|
+
price
|
|
759
914
|
... on Book {
|
|
760
|
-
price
|
|
761
915
|
__typename
|
|
762
916
|
isbn
|
|
763
917
|
}
|
|
764
918
|
... on Furniture {
|
|
765
|
-
price
|
|
766
919
|
__typename
|
|
767
920
|
upc
|
|
768
921
|
}
|
|
@@ -801,7 +954,7 @@ describe('buildQueryPlan', () => {
|
|
|
801
954
|
});
|
|
802
955
|
|
|
803
956
|
it(`interface fragments should expand into possible types only`, () => {
|
|
804
|
-
const
|
|
957
|
+
const operationString = `#graphql
|
|
805
958
|
query {
|
|
806
959
|
books {
|
|
807
960
|
... on Product {
|
|
@@ -814,7 +967,7 @@ describe('buildQueryPlan', () => {
|
|
|
814
967
|
}
|
|
815
968
|
`;
|
|
816
969
|
|
|
817
|
-
const queryPlan =
|
|
970
|
+
const queryPlan = buildPlan(operationString);
|
|
818
971
|
|
|
819
972
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
820
973
|
QueryPlan {
|
|
@@ -851,8 +1004,8 @@ describe('buildQueryPlan', () => {
|
|
|
851
1004
|
`);
|
|
852
1005
|
});
|
|
853
1006
|
|
|
854
|
-
it(`interface inside interface should
|
|
855
|
-
const
|
|
1007
|
+
it(`interface inside interface should not type explode if possible`, () => {
|
|
1008
|
+
const operationString = `#graphql
|
|
856
1009
|
query {
|
|
857
1010
|
product(upc: "") {
|
|
858
1011
|
details {
|
|
@@ -862,7 +1015,7 @@ describe('buildQueryPlan', () => {
|
|
|
862
1015
|
}
|
|
863
1016
|
`;
|
|
864
1017
|
|
|
865
|
-
const queryPlan =
|
|
1018
|
+
const queryPlan = buildPlan(operationString);
|
|
866
1019
|
|
|
867
1020
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
868
1021
|
QueryPlan {
|
|
@@ -870,15 +1023,9 @@ describe('buildQueryPlan', () => {
|
|
|
870
1023
|
{
|
|
871
1024
|
product(upc: "") {
|
|
872
1025
|
__typename
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
... on Furniture {
|
|
879
|
-
details {
|
|
880
|
-
country
|
|
881
|
-
}
|
|
1026
|
+
details {
|
|
1027
|
+
__typename
|
|
1028
|
+
country
|
|
882
1029
|
}
|
|
883
1030
|
}
|
|
884
1031
|
}
|
|
@@ -887,319 +1034,8 @@ describe('buildQueryPlan', () => {
|
|
|
887
1034
|
`);
|
|
888
1035
|
});
|
|
889
1036
|
|
|
890
|
-
describe(`experimental compression to downstream services`, () => {
|
|
891
|
-
it(`should generate fragments internally to downstream requests`, () => {
|
|
892
|
-
const query = gql`
|
|
893
|
-
query {
|
|
894
|
-
topReviews {
|
|
895
|
-
body
|
|
896
|
-
author
|
|
897
|
-
product {
|
|
898
|
-
name
|
|
899
|
-
price
|
|
900
|
-
details {
|
|
901
|
-
country
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
`;
|
|
907
|
-
|
|
908
|
-
const queryPlan = buildQueryPlan(
|
|
909
|
-
buildOperationContext(schema, query, undefined),
|
|
910
|
-
{ autoFragmentization: true },
|
|
911
|
-
);
|
|
912
|
-
|
|
913
|
-
expect(queryPlan).toMatchInlineSnapshot(`
|
|
914
|
-
QueryPlan {
|
|
915
|
-
Sequence {
|
|
916
|
-
Fetch(service: "reviews") {
|
|
917
|
-
{
|
|
918
|
-
topReviews {
|
|
919
|
-
...__QueryPlanFragment_1__
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
fragment __QueryPlanFragment_1__ on Review {
|
|
923
|
-
body
|
|
924
|
-
author
|
|
925
|
-
product {
|
|
926
|
-
...__QueryPlanFragment_0__
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
fragment __QueryPlanFragment_0__ on Product {
|
|
930
|
-
__typename
|
|
931
|
-
... on Book {
|
|
932
|
-
__typename
|
|
933
|
-
isbn
|
|
934
|
-
}
|
|
935
|
-
... on Furniture {
|
|
936
|
-
__typename
|
|
937
|
-
upc
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
},
|
|
941
|
-
Parallel {
|
|
942
|
-
Sequence {
|
|
943
|
-
Flatten(path: "topReviews.@.product") {
|
|
944
|
-
Fetch(service: "books") {
|
|
945
|
-
{
|
|
946
|
-
... on Book {
|
|
947
|
-
__typename
|
|
948
|
-
isbn
|
|
949
|
-
}
|
|
950
|
-
} =>
|
|
951
|
-
{
|
|
952
|
-
... on Book {
|
|
953
|
-
__typename
|
|
954
|
-
isbn
|
|
955
|
-
title
|
|
956
|
-
year
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
},
|
|
960
|
-
},
|
|
961
|
-
Flatten(path: "topReviews.@.product") {
|
|
962
|
-
Fetch(service: "product") {
|
|
963
|
-
{
|
|
964
|
-
... on Book {
|
|
965
|
-
__typename
|
|
966
|
-
isbn
|
|
967
|
-
title
|
|
968
|
-
year
|
|
969
|
-
}
|
|
970
|
-
} =>
|
|
971
|
-
{
|
|
972
|
-
... on Book {
|
|
973
|
-
name
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
},
|
|
977
|
-
},
|
|
978
|
-
},
|
|
979
|
-
Flatten(path: "topReviews.@.product") {
|
|
980
|
-
Fetch(service: "product") {
|
|
981
|
-
{
|
|
982
|
-
... on Furniture {
|
|
983
|
-
__typename
|
|
984
|
-
upc
|
|
985
|
-
}
|
|
986
|
-
... on Book {
|
|
987
|
-
__typename
|
|
988
|
-
isbn
|
|
989
|
-
}
|
|
990
|
-
} =>
|
|
991
|
-
{
|
|
992
|
-
... on Furniture {
|
|
993
|
-
name
|
|
994
|
-
price
|
|
995
|
-
details {
|
|
996
|
-
country
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
... on Book {
|
|
1000
|
-
price
|
|
1001
|
-
details {
|
|
1002
|
-
country
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
},
|
|
1007
|
-
},
|
|
1008
|
-
},
|
|
1009
|
-
},
|
|
1010
|
-
}
|
|
1011
|
-
`);
|
|
1012
|
-
});
|
|
1013
|
-
|
|
1014
|
-
it(`shouldn't generate fragments for selection sets of length 2 or less`, () => {
|
|
1015
|
-
const query = gql`
|
|
1016
|
-
query {
|
|
1017
|
-
topReviews {
|
|
1018
|
-
body
|
|
1019
|
-
author
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
`;
|
|
1023
|
-
|
|
1024
|
-
const queryPlan = buildQueryPlan(
|
|
1025
|
-
buildOperationContext(schema, query, undefined),
|
|
1026
|
-
{ autoFragmentization: true },
|
|
1027
|
-
);
|
|
1028
|
-
|
|
1029
|
-
expect(queryPlan).toMatchInlineSnapshot(`
|
|
1030
|
-
QueryPlan {
|
|
1031
|
-
Fetch(service: "reviews") {
|
|
1032
|
-
{
|
|
1033
|
-
topReviews {
|
|
1034
|
-
body
|
|
1035
|
-
author
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
},
|
|
1039
|
-
}
|
|
1040
|
-
`);
|
|
1041
|
-
});
|
|
1042
|
-
|
|
1043
|
-
it(`should generate fragments for selection sets of length 3 or greater`, () => {
|
|
1044
|
-
const query = gql`
|
|
1045
|
-
query {
|
|
1046
|
-
topReviews {
|
|
1047
|
-
id
|
|
1048
|
-
body
|
|
1049
|
-
author
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
`;
|
|
1053
|
-
|
|
1054
|
-
const queryPlan = buildQueryPlan(
|
|
1055
|
-
buildOperationContext(schema, query, undefined),
|
|
1056
|
-
{ autoFragmentization: true },
|
|
1057
|
-
);
|
|
1058
|
-
|
|
1059
|
-
expect(queryPlan).toMatchInlineSnapshot(`
|
|
1060
|
-
QueryPlan {
|
|
1061
|
-
Fetch(service: "reviews") {
|
|
1062
|
-
{
|
|
1063
|
-
topReviews {
|
|
1064
|
-
...__QueryPlanFragment_0__
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
fragment __QueryPlanFragment_0__ on Review {
|
|
1068
|
-
id
|
|
1069
|
-
body
|
|
1070
|
-
author
|
|
1071
|
-
}
|
|
1072
|
-
},
|
|
1073
|
-
}
|
|
1074
|
-
`);
|
|
1075
|
-
});
|
|
1076
|
-
|
|
1077
|
-
it(`should generate fragments correctly when aliases are used`, () => {
|
|
1078
|
-
const query = gql`
|
|
1079
|
-
query {
|
|
1080
|
-
reviews: topReviews {
|
|
1081
|
-
content: body
|
|
1082
|
-
author
|
|
1083
|
-
product {
|
|
1084
|
-
name
|
|
1085
|
-
cost: price
|
|
1086
|
-
details {
|
|
1087
|
-
origin: country
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
`;
|
|
1093
|
-
|
|
1094
|
-
const queryPlan = buildQueryPlan(
|
|
1095
|
-
buildOperationContext(schema, query, undefined),
|
|
1096
|
-
{ autoFragmentization: true },
|
|
1097
|
-
);
|
|
1098
|
-
|
|
1099
|
-
expect(queryPlan).toMatchInlineSnapshot(`
|
|
1100
|
-
QueryPlan {
|
|
1101
|
-
Sequence {
|
|
1102
|
-
Fetch(service: "reviews") {
|
|
1103
|
-
{
|
|
1104
|
-
reviews: topReviews {
|
|
1105
|
-
...__QueryPlanFragment_1__
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
fragment __QueryPlanFragment_1__ on Review {
|
|
1109
|
-
content: body
|
|
1110
|
-
author
|
|
1111
|
-
product {
|
|
1112
|
-
...__QueryPlanFragment_0__
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
fragment __QueryPlanFragment_0__ on Product {
|
|
1116
|
-
__typename
|
|
1117
|
-
... on Book {
|
|
1118
|
-
__typename
|
|
1119
|
-
isbn
|
|
1120
|
-
}
|
|
1121
|
-
... on Furniture {
|
|
1122
|
-
__typename
|
|
1123
|
-
upc
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
},
|
|
1127
|
-
Parallel {
|
|
1128
|
-
Sequence {
|
|
1129
|
-
Flatten(path: "reviews.@.product") {
|
|
1130
|
-
Fetch(service: "books") {
|
|
1131
|
-
{
|
|
1132
|
-
... on Book {
|
|
1133
|
-
__typename
|
|
1134
|
-
isbn
|
|
1135
|
-
}
|
|
1136
|
-
} =>
|
|
1137
|
-
{
|
|
1138
|
-
... on Book {
|
|
1139
|
-
__typename
|
|
1140
|
-
isbn
|
|
1141
|
-
title
|
|
1142
|
-
year
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
},
|
|
1146
|
-
},
|
|
1147
|
-
Flatten(path: "reviews.@.product") {
|
|
1148
|
-
Fetch(service: "product") {
|
|
1149
|
-
{
|
|
1150
|
-
... on Book {
|
|
1151
|
-
__typename
|
|
1152
|
-
isbn
|
|
1153
|
-
title
|
|
1154
|
-
year
|
|
1155
|
-
}
|
|
1156
|
-
} =>
|
|
1157
|
-
{
|
|
1158
|
-
... on Book {
|
|
1159
|
-
name
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
},
|
|
1163
|
-
},
|
|
1164
|
-
},
|
|
1165
|
-
Flatten(path: "reviews.@.product") {
|
|
1166
|
-
Fetch(service: "product") {
|
|
1167
|
-
{
|
|
1168
|
-
... on Furniture {
|
|
1169
|
-
__typename
|
|
1170
|
-
upc
|
|
1171
|
-
}
|
|
1172
|
-
... on Book {
|
|
1173
|
-
__typename
|
|
1174
|
-
isbn
|
|
1175
|
-
}
|
|
1176
|
-
} =>
|
|
1177
|
-
{
|
|
1178
|
-
... on Furniture {
|
|
1179
|
-
name
|
|
1180
|
-
cost: price
|
|
1181
|
-
details {
|
|
1182
|
-
origin: country
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
... on Book {
|
|
1186
|
-
cost: price
|
|
1187
|
-
details {
|
|
1188
|
-
origin: country
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
},
|
|
1193
|
-
},
|
|
1194
|
-
},
|
|
1195
|
-
},
|
|
1196
|
-
}
|
|
1197
|
-
`);
|
|
1198
|
-
});
|
|
1199
|
-
});
|
|
1200
|
-
|
|
1201
1037
|
it(`should properly expand nested unions with inline fragments`, () => {
|
|
1202
|
-
const
|
|
1038
|
+
const operationString = `#graphql
|
|
1203
1039
|
query {
|
|
1204
1040
|
body {
|
|
1205
1041
|
... on Image {
|
|
@@ -1226,9 +1062,7 @@ describe('buildQueryPlan', () => {
|
|
|
1226
1062
|
}
|
|
1227
1063
|
`;
|
|
1228
1064
|
|
|
1229
|
-
const queryPlan =
|
|
1230
|
-
buildOperationContext(schema, query, undefined),
|
|
1231
|
-
);
|
|
1065
|
+
const queryPlan = buildPlan(operationString);
|
|
1232
1066
|
|
|
1233
1067
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
1234
1068
|
QueryPlan {
|
|
@@ -1255,16 +1089,9 @@ describe('buildQueryPlan', () => {
|
|
|
1255
1089
|
|
|
1256
1090
|
describe('deduplicates fields / selections regardless of adjacency and type condition nesting', () => {
|
|
1257
1091
|
it('for inline fragments', () => {
|
|
1258
|
-
const
|
|
1092
|
+
const operationString = `#graphql
|
|
1259
1093
|
query {
|
|
1260
1094
|
body {
|
|
1261
|
-
... on Image {
|
|
1262
|
-
... on Text {
|
|
1263
|
-
attributes {
|
|
1264
|
-
bold
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
1095
|
... on Body {
|
|
1269
1096
|
... on Text {
|
|
1270
1097
|
attributes {
|
|
@@ -1283,9 +1110,7 @@ describe('buildQueryPlan', () => {
|
|
|
1283
1110
|
}
|
|
1284
1111
|
`;
|
|
1285
1112
|
|
|
1286
|
-
const queryPlan =
|
|
1287
|
-
buildOperationContext(schema, query, undefined),
|
|
1288
|
-
);
|
|
1113
|
+
const queryPlan = buildPlan(operationString);
|
|
1289
1114
|
|
|
1290
1115
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
1291
1116
|
QueryPlan {
|
|
@@ -1307,7 +1132,7 @@ describe('buildQueryPlan', () => {
|
|
|
1307
1132
|
});
|
|
1308
1133
|
|
|
1309
1134
|
it('for named fragment spreads', () => {
|
|
1310
|
-
const
|
|
1135
|
+
const operationString = `#graphql
|
|
1311
1136
|
fragment TextFragment on Text {
|
|
1312
1137
|
attributes {
|
|
1313
1138
|
bold
|
|
@@ -1317,9 +1142,6 @@ describe('buildQueryPlan', () => {
|
|
|
1317
1142
|
|
|
1318
1143
|
query {
|
|
1319
1144
|
body {
|
|
1320
|
-
... on Image {
|
|
1321
|
-
...TextFragment
|
|
1322
|
-
}
|
|
1323
1145
|
... on Body {
|
|
1324
1146
|
...TextFragment
|
|
1325
1147
|
}
|
|
@@ -1328,9 +1150,7 @@ describe('buildQueryPlan', () => {
|
|
|
1328
1150
|
}
|
|
1329
1151
|
`;
|
|
1330
1152
|
|
|
1331
|
-
const queryPlan =
|
|
1332
|
-
buildOperationContext(schema, query, undefined),
|
|
1333
|
-
);
|
|
1153
|
+
const queryPlan = buildPlan(operationString);
|
|
1334
1154
|
|
|
1335
1155
|
expect(queryPlan).toMatchInlineSnapshot(`
|
|
1336
1156
|
QueryPlan {
|