@apollo/gateway 2.4.4 → 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 (176) hide show
  1. package/dist/__generated__/graphqlTypes.d.ts +178 -0
  2. package/dist/__generated__/graphqlTypes.d.ts.map +1 -0
  3. package/dist/__generated__/graphqlTypes.js +31 -0
  4. package/dist/__generated__/graphqlTypes.js.map +1 -0
  5. package/dist/config.d.ts +138 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +60 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/dataRewrites.d.ts +5 -0
  10. package/dist/dataRewrites.d.ts.map +1 -0
  11. package/dist/dataRewrites.js +103 -0
  12. package/dist/dataRewrites.js.map +1 -0
  13. package/dist/datasources/LocalGraphQLDataSource.d.ts +10 -0
  14. package/dist/datasources/LocalGraphQLDataSource.d.ts.map +1 -0
  15. package/dist/datasources/LocalGraphQLDataSource.js +31 -0
  16. package/dist/datasources/LocalGraphQLDataSource.js.map +1 -0
  17. package/dist/datasources/RemoteGraphQLDataSource.d.ts +24 -0
  18. package/dist/datasources/RemoteGraphQLDataSource.d.ts.map +1 -0
  19. package/dist/datasources/RemoteGraphQLDataSource.js +180 -0
  20. package/dist/datasources/RemoteGraphQLDataSource.js.map +1 -0
  21. package/dist/datasources/index.d.ts +4 -0
  22. package/dist/datasources/index.d.ts.map +1 -0
  23. package/dist/datasources/index.js +8 -0
  24. package/dist/datasources/index.js.map +1 -0
  25. package/dist/datasources/parseCacheControlHeader.d.ts +2 -0
  26. package/dist/datasources/parseCacheControlHeader.d.ts.map +1 -0
  27. package/dist/datasources/parseCacheControlHeader.js +16 -0
  28. package/dist/datasources/parseCacheControlHeader.js.map +1 -0
  29. package/dist/datasources/types.d.ts +23 -0
  30. package/dist/datasources/types.d.ts.map +1 -0
  31. package/dist/datasources/types.js +10 -0
  32. package/dist/datasources/types.js.map +1 -0
  33. package/dist/executeQueryPlan.d.ts +15 -0
  34. package/dist/executeQueryPlan.d.ts.map +1 -0
  35. package/dist/executeQueryPlan.js +539 -0
  36. package/dist/executeQueryPlan.js.map +1 -0
  37. package/dist/index.d.ts +113 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +590 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/logger.d.ts +3 -0
  42. package/dist/logger.d.ts.map +1 -0
  43. package/dist/logger.js +15 -0
  44. package/dist/logger.js.map +1 -0
  45. package/dist/operationContext.d.ts +17 -0
  46. package/dist/operationContext.d.ts.map +1 -0
  47. package/dist/operationContext.js +38 -0
  48. package/dist/operationContext.js.map +1 -0
  49. package/dist/resultShaping.d.ts +12 -0
  50. package/dist/resultShaping.d.ts.map +1 -0
  51. package/dist/resultShaping.js +229 -0
  52. package/dist/resultShaping.js.map +1 -0
  53. package/dist/schema-helper/addExtensions.d.ts +3 -0
  54. package/dist/schema-helper/addExtensions.d.ts.map +1 -0
  55. package/dist/schema-helper/addExtensions.js +23 -0
  56. package/dist/schema-helper/addExtensions.js.map +1 -0
  57. package/dist/supergraphManagers/IntrospectAndCompose/index.d.ts +31 -0
  58. package/dist/supergraphManagers/IntrospectAndCompose/index.d.ts.map +1 -0
  59. package/dist/supergraphManagers/IntrospectAndCompose/index.js +112 -0
  60. package/dist/supergraphManagers/IntrospectAndCompose/index.js.map +1 -0
  61. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts +12 -0
  62. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts.map +1 -0
  63. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js +57 -0
  64. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js.map +1 -0
  65. package/dist/supergraphManagers/LegacyFetcher/index.d.ts +33 -0
  66. package/dist/supergraphManagers/LegacyFetcher/index.d.ts.map +1 -0
  67. package/dist/supergraphManagers/LegacyFetcher/index.js +149 -0
  68. package/dist/supergraphManagers/LegacyFetcher/index.js.map +1 -0
  69. package/dist/supergraphManagers/LocalCompose/index.d.ts +19 -0
  70. package/dist/supergraphManagers/LocalCompose/index.d.ts.map +1 -0
  71. package/dist/supergraphManagers/LocalCompose/index.js +55 -0
  72. package/dist/supergraphManagers/LocalCompose/index.js.map +1 -0
  73. package/dist/supergraphManagers/UplinkSupergraphManager/index.d.ts +63 -0
  74. package/dist/supergraphManagers/UplinkSupergraphManager/index.d.ts.map +1 -0
  75. package/dist/supergraphManagers/UplinkSupergraphManager/index.js +210 -0
  76. package/dist/supergraphManagers/UplinkSupergraphManager/index.js.map +1 -0
  77. package/dist/supergraphManagers/UplinkSupergraphManager/loadSupergraphSdlFromStorage.d.ts +30 -0
  78. package/dist/supergraphManagers/UplinkSupergraphManager/loadSupergraphSdlFromStorage.d.ts.map +1 -0
  79. package/dist/supergraphManagers/UplinkSupergraphManager/loadSupergraphSdlFromStorage.js +145 -0
  80. package/dist/supergraphManagers/UplinkSupergraphManager/loadSupergraphSdlFromStorage.js.map +1 -0
  81. package/dist/supergraphManagers/UplinkSupergraphManager/outOfBandReporter.d.ts +14 -0
  82. package/dist/supergraphManagers/UplinkSupergraphManager/outOfBandReporter.d.ts.map +1 -0
  83. package/dist/supergraphManagers/UplinkSupergraphManager/outOfBandReporter.js +85 -0
  84. package/dist/supergraphManagers/UplinkSupergraphManager/outOfBandReporter.js.map +1 -0
  85. package/dist/supergraphManagers/index.d.ts +6 -0
  86. package/dist/supergraphManagers/index.d.ts.map +1 -0
  87. package/dist/supergraphManagers/index.js +27 -0
  88. package/dist/supergraphManagers/index.js.map +1 -0
  89. package/dist/typings/graphql.d.ts +11 -0
  90. package/dist/typings/graphql.d.ts.map +1 -0
  91. package/dist/typings/graphql.js +3 -0
  92. package/dist/typings/graphql.js.map +1 -0
  93. package/dist/utilities/array.d.ts +5 -0
  94. package/dist/utilities/array.d.ts.map +1 -0
  95. package/dist/utilities/array.js +46 -0
  96. package/dist/utilities/array.js.map +1 -0
  97. package/dist/utilities/assert.d.ts +2 -0
  98. package/dist/utilities/assert.d.ts.map +1 -0
  99. package/dist/utilities/assert.js +10 -0
  100. package/dist/utilities/assert.js.map +1 -0
  101. package/dist/utilities/deepMerge.d.ts +2 -0
  102. package/dist/utilities/deepMerge.d.ts.map +1 -0
  103. package/dist/utilities/deepMerge.js +34 -0
  104. package/dist/utilities/deepMerge.js.map +1 -0
  105. package/dist/utilities/graphql.d.ts +5 -0
  106. package/dist/utilities/graphql.d.ts.map +1 -0
  107. package/dist/utilities/graphql.js +28 -0
  108. package/dist/utilities/graphql.js.map +1 -0
  109. package/dist/utilities/opentelemetry.d.ts +10 -0
  110. package/dist/utilities/opentelemetry.d.ts.map +1 -0
  111. package/dist/utilities/opentelemetry.js +19 -0
  112. package/dist/utilities/opentelemetry.js.map +1 -0
  113. package/dist/utilities/predicates.d.ts +2 -0
  114. package/dist/utilities/predicates.d.ts.map +1 -0
  115. package/dist/utilities/predicates.js +11 -0
  116. package/dist/utilities/predicates.js.map +1 -0
  117. package/package.json +4 -4
  118. package/src/__generated__/graphqlTypes.ts +33 -2
  119. package/src/__mocks__/tsconfig.json +0 -7
  120. package/src/__tests__/.gitkeep +0 -0
  121. package/src/__tests__/CucumberREADME.md +0 -96
  122. package/src/__tests__/build-query-plan.feature +0 -1471
  123. package/src/__tests__/buildQueryPlan.test.ts +0 -1225
  124. package/src/__tests__/executeQueryPlan.conditions.test.ts +0 -1488
  125. package/src/__tests__/executeQueryPlan.introspection.test.ts +0 -140
  126. package/src/__tests__/executeQueryPlan.test.ts +0 -6140
  127. package/src/__tests__/execution-utils.ts +0 -124
  128. package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +0 -195
  129. package/src/__tests__/gateway/buildService.test.ts +0 -249
  130. package/src/__tests__/gateway/endToEnd.test.ts +0 -486
  131. package/src/__tests__/gateway/executor.test.ts +0 -96
  132. package/src/__tests__/gateway/extensions.test.ts +0 -37
  133. package/src/__tests__/gateway/lifecycle-hooks.test.ts +0 -239
  134. package/src/__tests__/gateway/opentelemetry.test.ts +0 -123
  135. package/src/__tests__/gateway/queryPlanCache.test.ts +0 -231
  136. package/src/__tests__/gateway/queryPlannerConfig.test.ts +0 -101
  137. package/src/__tests__/gateway/reporting.test.ts +0 -616
  138. package/src/__tests__/gateway/supergraphSdl.test.ts +0 -396
  139. package/src/__tests__/gateway/testUtils.ts +0 -89
  140. package/src/__tests__/integration/abstract-types.test.ts +0 -1861
  141. package/src/__tests__/integration/aliases.test.ts +0 -180
  142. package/src/__tests__/integration/boolean.test.ts +0 -279
  143. package/src/__tests__/integration/complex-key.test.ts +0 -197
  144. package/src/__tests__/integration/configuration.test.ts +0 -404
  145. package/src/__tests__/integration/custom-directives.test.ts +0 -174
  146. package/src/__tests__/integration/execution-style.test.ts +0 -35
  147. package/src/__tests__/integration/fragments.test.ts +0 -237
  148. package/src/__tests__/integration/list-key.test.ts +0 -128
  149. package/src/__tests__/integration/logger.test.ts +0 -122
  150. package/src/__tests__/integration/managed.test.ts +0 -319
  151. package/src/__tests__/integration/merge-arrays.test.ts +0 -34
  152. package/src/__tests__/integration/multiple-key.test.ts +0 -327
  153. package/src/__tests__/integration/mutations.test.ts +0 -287
  154. package/src/__tests__/integration/networkRequests.test.ts +0 -542
  155. package/src/__tests__/integration/nockMocks.ts +0 -157
  156. package/src/__tests__/integration/provides.test.ts +0 -77
  157. package/src/__tests__/integration/requires.test.ts +0 -359
  158. package/src/__tests__/integration/scope.test.ts +0 -557
  159. package/src/__tests__/integration/single-service.test.ts +0 -119
  160. package/src/__tests__/integration/unions.test.ts +0 -79
  161. package/src/__tests__/integration/value-types.test.ts +0 -382
  162. package/src/__tests__/integration/variables.test.ts +0 -120
  163. package/src/__tests__/nockAssertions.ts +0 -20
  164. package/src/__tests__/queryPlanCucumber.test.ts +0 -55
  165. package/src/__tests__/resultShaping.test.ts +0 -605
  166. package/src/__tests__/testSetup.ts +0 -1
  167. package/src/__tests__/tsconfig.json +0 -8
  168. package/src/core/__tests__/core.test.ts +0 -412
  169. package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +0 -51
  170. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +0 -574
  171. package/src/schema-helper/__tests__/addExtensions.test.ts +0 -70
  172. package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +0 -364
  173. package/src/supergraphManagers/IntrospectAndCompose/__tests__/loadServicesFromRemoteEndpoint.test.ts +0 -40
  174. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/UplinkSupergraphManager.test.ts +0 -65
  175. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/loadSupergraphSdlFromStorage.test.ts +0 -511
  176. package/src/utilities/__tests__/deepMerge.test.ts +0 -77
@@ -1,396 +0,0 @@
1
- import {
2
- ApolloGateway,
3
- RemoteGraphQLDataSource,
4
- SubgraphHealthCheckFunction,
5
- SupergraphSdlUpdateFunction,
6
- } from '@apollo/gateway';
7
- import { accounts, fixturesWithUpdate } from 'apollo-federation-integration-testsuite';
8
- import { createHash } from '@apollo/utils.createhash';
9
- import { ApolloServer } from '@apollo/server';
10
- import { startStandaloneServer } from '@apollo/server/standalone';
11
- import type { Logger } from '@apollo/utils.logger';
12
- import { getTestingSupergraphSdl } from '../execution-utils';
13
- import { mockAllServicesHealthCheckSuccess } from '../integration/nockMocks';
14
- import resolvable from '@josephg/resolvable';
15
- import { nockAfterEach, nockBeforeEach } from '../nockAssertions';
16
- import nock from 'nock';
17
- import { unwrapSingleResultKind } from '../gateway/testUtils';
18
-
19
- async function getSupergraphSdlGatewayServer() {
20
- const server = new ApolloServer({
21
- gateway: new ApolloGateway({
22
- supergraphSdl: getTestingSupergraphSdl(),
23
- buildService({ url }) {
24
- return new RemoteGraphQLDataSource({
25
- url,
26
- });
27
- },
28
- }),
29
- });
30
-
31
- await startStandaloneServer(server, { listen: { port: 0 } });
32
- return server;
33
- }
34
-
35
- let logger: Logger;
36
- let gateway: ApolloGateway | null;
37
- beforeEach(() => {
38
- nockBeforeEach();
39
-
40
- logger = {
41
- debug: jest.fn(),
42
- info: jest.fn(),
43
- warn: jest.fn(),
44
- error: jest.fn(),
45
- };
46
- });
47
-
48
- afterEach(async () => {
49
- nockAfterEach();
50
-
51
- if (gateway) {
52
- await gateway.stop();
53
- gateway = null;
54
- }
55
- });
56
-
57
- const testingFixturesDefaultCompositionId = createHash('sha256').update(getTestingSupergraphSdl()).digest('hex');
58
-
59
- describe('Using supergraphSdl static configuration', () => {
60
- it('successfully starts and serves requests to the proper services', async () => {
61
- const server = await getSupergraphSdlGatewayServer();
62
-
63
- nock(accounts.url)
64
- .post('/', { query: '{me{username}}', variables: {} })
65
- .reply(200, { data: { me: { username: '@apollo-user' } } });
66
-
67
-
68
- const result = await server.executeOperation({
69
- query: '{ me { username } }',
70
- });
71
-
72
- expect(unwrapSingleResultKind(result).data).toMatchInlineSnapshot(`
73
- Object {
74
- "me": Object {
75
- "username": "@apollo-user",
76
- },
77
- }
78
- `);
79
-
80
- await server.stop();
81
- });
82
- });
83
-
84
- describe('Using supergraphSdl dynamic configuration', () => {
85
- it('calls the user provided function after `gateway.load()` is called', async () => {
86
- const callbackSpy = jest.fn(async () => ({
87
- supergraphSdl: getTestingSupergraphSdl(),
88
- }));
89
-
90
- gateway = new ApolloGateway({
91
- supergraphSdl: callbackSpy,
92
- });
93
-
94
- expect(callbackSpy).not.toHaveBeenCalled();
95
- await gateway.load();
96
- expect(callbackSpy).toHaveBeenCalled();
97
- });
98
-
99
- it('starts and remains in `initialized` state until `supergraphSdl` Promise resolves', async () => {
100
- const promiseGuaranteeingWeAreInTheCallback = resolvable();
101
- const promiseGuaranteeingWeStayInTheCallback = resolvable();
102
-
103
- gateway = new ApolloGateway({
104
- async supergraphSdl() {
105
- promiseGuaranteeingWeAreInTheCallback.resolve();
106
- await promiseGuaranteeingWeStayInTheCallback;
107
- return {
108
- supergraphSdl: getTestingSupergraphSdl(),
109
- };
110
- },
111
- });
112
-
113
- expect(gateway.__testing().state.phase).toEqual('initialized');
114
-
115
- const gatewayLoaded = gateway.load();
116
- await promiseGuaranteeingWeAreInTheCallback;
117
- expect(gateway.__testing().state.phase).toEqual('initialized');
118
-
119
- promiseGuaranteeingWeStayInTheCallback.resolve();
120
- await gatewayLoaded;
121
- expect(gateway.__testing().state.phase).toEqual('loaded');
122
- });
123
-
124
- it('moves from `initialized` to `loaded` state after calling `load()` and after user Promise resolves', async () => {
125
- const userPromise = resolvable<{ supergraphSdl: string }>();
126
-
127
- gateway = new ApolloGateway({
128
- async supergraphSdl() {
129
- return userPromise;
130
- },
131
- });
132
-
133
- const loadPromise = gateway.load();
134
- expect(gateway.__testing().state.phase).toEqual('initialized');
135
-
136
- const supergraphSdl = getTestingSupergraphSdl();
137
- const expectedCompositionId = createHash('sha256')
138
- .update(supergraphSdl)
139
- .digest('hex');
140
- userPromise.resolve({ supergraphSdl });
141
-
142
- await loadPromise;
143
- const { state, compositionId } = gateway.__testing();
144
- expect(state.phase).toEqual('loaded');
145
- expect(compositionId).toEqual(expectedCompositionId);
146
- });
147
-
148
- it('updates its supergraph after user calls update function', async () => {
149
- const userPromise = resolvable<{ supergraphSdl: string }>();
150
-
151
- let userUpdateFn: SupergraphSdlUpdateFunction;
152
- gateway = new ApolloGateway({
153
- async supergraphSdl({ update }) {
154
- userUpdateFn = update;
155
- return userPromise;
156
- },
157
- });
158
-
159
- const supergraphSdl = getTestingSupergraphSdl();
160
- const expectedId = createHash('sha256').update(supergraphSdl).digest('hex');
161
- userPromise.resolve({ supergraphSdl: getTestingSupergraphSdl() });
162
- await gateway.load();
163
- expect(gateway.__testing().compositionId).toEqual(expectedId);
164
-
165
- const updatedSupergraphSdl = getTestingSupergraphSdl(fixturesWithUpdate);
166
- const expectedUpdatedId = createHash('sha256')
167
- .update(updatedSupergraphSdl)
168
- .digest('hex');
169
-
170
- userUpdateFn!(updatedSupergraphSdl);
171
- expect(gateway.__testing().compositionId).toEqual(expectedUpdatedId);
172
- });
173
-
174
- it('calls user-provided `cleanup` function when stopped', async () => {
175
- const cleanup = jest.fn(() => Promise.resolve());
176
- gateway = new ApolloGateway({
177
- async supergraphSdl() {
178
- return {
179
- supergraphSdl: getTestingSupergraphSdl(),
180
- cleanup,
181
- };
182
- },
183
- });
184
-
185
- await gateway.load();
186
- const { state, compositionId } = gateway.__testing();
187
- expect(state.phase).toEqual('loaded');
188
- expect(compositionId).toEqual(
189
- testingFixturesDefaultCompositionId,
190
- );
191
-
192
- await gateway.stop();
193
- expect(cleanup).toHaveBeenCalledTimes(1);
194
- });
195
-
196
- it('performs a successful health check on subgraphs', async () => {
197
- mockAllServicesHealthCheckSuccess();
198
-
199
- let healthCheckCallback: SubgraphHealthCheckFunction;
200
- const supergraphSdl = getTestingSupergraphSdl();
201
- gateway = new ApolloGateway({
202
- async supergraphSdl({ healthCheck }) {
203
- healthCheckCallback = healthCheck;
204
- return {
205
- supergraphSdl,
206
- };
207
- },
208
- });
209
-
210
- await gateway.load();
211
- const { state, compositionId } = gateway.__testing();
212
- expect(state.phase).toEqual('loaded');
213
- expect(compositionId).toEqual(
214
- testingFixturesDefaultCompositionId,
215
- );
216
-
217
- await expect(healthCheckCallback!(supergraphSdl)).resolves.toBeUndefined();
218
- });
219
-
220
- it('calls `initialize` on an object provided to `supergraphSdl`', async () => {
221
- const MockSdlUpdatingClass = {
222
- initialize() {
223
- return Promise.resolve({
224
- supergraphSdl: getTestingSupergraphSdl(),
225
- });
226
- },
227
- };
228
- const initializeSpy = jest.spyOn(MockSdlUpdatingClass, 'initialize');
229
-
230
- gateway = new ApolloGateway({
231
- supergraphSdl: MockSdlUpdatingClass,
232
- });
233
-
234
- expect(initializeSpy).not.toHaveBeenCalled();
235
- await gateway.load();
236
- expect(initializeSpy).toHaveBeenCalled();
237
- });
238
-
239
- describe('errors', () => {
240
- it('fails to load if `SupergraphManager` throws on initialization', async () => {
241
- const failureMessage = 'Error from supergraphSdl function';
242
- gateway = new ApolloGateway({
243
- async supergraphSdl() {
244
- throw new Error(failureMessage);
245
- },
246
- logger,
247
- });
248
-
249
- await expect(gateway.load()).rejects.toThrowError(failureMessage);
250
-
251
- expect(gateway.__testing().state.phase).toEqual('failed to load');
252
- // we don't want the `afterEach` to call `gateway.stop()` in this case
253
- // since it would throw an error due to the gateway's failed to load state
254
- gateway = null;
255
- });
256
-
257
- it('gracefully handles Promise rejections from user `cleanup` function', async () => {
258
- const rejectionMessage = 'thrown from cleanup function';
259
- const cleanup = jest.fn(() => Promise.reject(rejectionMessage));
260
- gateway = new ApolloGateway({
261
- async supergraphSdl() {
262
- return {
263
- supergraphSdl: getTestingSupergraphSdl(),
264
- cleanup,
265
- };
266
- },
267
- logger,
268
- });
269
-
270
- await gateway.load();
271
- await expect(gateway.stop()).resolves.toBeUndefined();
272
- expect(cleanup).toHaveBeenCalledTimes(1);
273
- expect(logger.error).toHaveBeenCalledWith(
274
- 'Error occured while calling user provided `cleanup` function: ' +
275
- rejectionMessage,
276
- );
277
- });
278
-
279
- it('throws an error when `healthCheck` rejects', async () => {
280
- // no mocks, so nock will reject
281
- let healthCheckCallback: SubgraphHealthCheckFunction;
282
- const supergraphSdl = getTestingSupergraphSdl();
283
- gateway = new ApolloGateway({
284
- async supergraphSdl({ healthCheck }) {
285
- healthCheckCallback = healthCheck;
286
- return {
287
- supergraphSdl,
288
- };
289
- },
290
- });
291
-
292
- await gateway.load();
293
- const { state, compositionId } = gateway.__testing();
294
- expect(state.phase).toEqual('loaded');
295
- expect(compositionId).toEqual(
296
- testingFixturesDefaultCompositionId
297
- );
298
-
299
- await expect(healthCheckCallback!(supergraphSdl)).rejects.toThrowError(
300
- /The gateway subgraphs health check failed\. Updating to the provided `supergraphSdl` will likely result in future request failures to subgraphs\. The following error occurred during the health check/,
301
- );
302
- });
303
-
304
- it('throws an error when `update` is called after gateway fails to load', async () => {
305
- let updateCallback: SupergraphSdlUpdateFunction;
306
- const supergraphSdl = getTestingSupergraphSdl();
307
- gateway = new ApolloGateway({
308
- async supergraphSdl({ update }) {
309
- updateCallback = update;
310
- return {
311
- supergraphSdl: 'invalid SDL',
312
- };
313
- },
314
- });
315
-
316
- try {
317
- await gateway.load();
318
- } catch {}
319
-
320
- expect(() =>
321
- updateCallback!(supergraphSdl),
322
- ).toThrowErrorMatchingInlineSnapshot(
323
- `"Can't call \`update\` callback after gateway failed to load."`,
324
- );
325
-
326
- // gateway failed to load, so we don't want the `afterEach` to call `gateway.stop()`
327
- gateway = null;
328
- });
329
-
330
- it('throws an error when `update` is called while an update is in progress', async () => {
331
- let updateCallback: SupergraphSdlUpdateFunction;
332
- const supergraphSdl = getTestingSupergraphSdl();
333
- gateway = new ApolloGateway({
334
- async supergraphSdl({ update }) {
335
- updateCallback = update;
336
- return {
337
- supergraphSdl,
338
- };
339
- },
340
- experimental_didUpdateSupergraph() {
341
- updateCallback(getTestingSupergraphSdl(fixturesWithUpdate));
342
- },
343
- });
344
-
345
- await expect(gateway.load()).rejects.toThrowErrorMatchingInlineSnapshot(
346
- `"Can't call \`update\` callback while supergraph update is in progress."`,
347
- );
348
-
349
- // gateway failed to load, so we don't want the `afterEach` to call `gateway.stop()`
350
- gateway = null;
351
- });
352
-
353
- it('throws an error when `update` is called after gateway is stopped', async () => {
354
- let updateCallback: SupergraphSdlUpdateFunction;
355
- const supergraphSdl = getTestingSupergraphSdl();
356
- gateway = new ApolloGateway({
357
- async supergraphSdl({ update }) {
358
- updateCallback = update;
359
- return {
360
- supergraphSdl,
361
- };
362
- },
363
- });
364
-
365
- await gateway.load();
366
- await gateway.stop();
367
-
368
- expect(() =>
369
- updateCallback!(getTestingSupergraphSdl(fixturesWithUpdate)),
370
- ).toThrowErrorMatchingInlineSnapshot(
371
- `"Can't call \`update\` callback after gateway has been stopped."`,
372
- );
373
- });
374
-
375
- it('throws an error when `update` is called with an invalid supergraph', async () => {
376
- let updateCallback: SupergraphSdlUpdateFunction;
377
- const supergraphSdl = getTestingSupergraphSdl();
378
- gateway = new ApolloGateway({
379
- async supergraphSdl({ update }) {
380
- updateCallback = update;
381
- return {
382
- supergraphSdl,
383
- };
384
- },
385
- });
386
-
387
- await gateway.load();
388
-
389
- expect(() =>
390
- updateCallback!('invalid SDL'),
391
- ).toThrowErrorMatchingInlineSnapshot(
392
- `"Syntax Error: Unexpected Name \\"invalid\\"."`,
393
- );
394
- });
395
- });
396
- });
@@ -1,89 +0,0 @@
1
- import { buildSubgraphSchema } from '@apollo/subgraph';
2
- import {
3
- ApolloServer,
4
- ApolloServerOptionsWithGateway,
5
- BaseContext,
6
- GraphQLResponse,
7
- } from '@apollo/server';
8
- import { startStandaloneServer } from '@apollo/server/standalone';
9
- import { ApolloServerPluginInlineTrace } from '@apollo/server/plugin/inlineTrace';
10
- import { GraphQLSchemaModule } from '@apollo/subgraph/src/schema-helper';
11
- import { ApolloGateway, GatewayConfig } from '../..';
12
- import { ServiceDefinition } from '@apollo/federation-internals';
13
- import fetch, { Response } from 'node-fetch';
14
- import { assert } from '@apollo/federation-internals';
15
-
16
- export class Services {
17
- constructor(
18
- readonly subgraphServers: ApolloServer[],
19
- readonly gateway: ApolloGateway,
20
- readonly gatewayServer: ApolloServer,
21
- readonly gatewayUrl: string,
22
- ) {
23
- }
24
-
25
- async queryGateway(query: string): Promise<Response> {
26
- return fetch(this.gatewayUrl, {
27
- method: 'POST',
28
- headers: {
29
- 'Content-Type': 'application/json',
30
- },
31
- body: JSON.stringify({ query }),
32
- });
33
- }
34
-
35
- async stop() {
36
- for (const server of this.subgraphServers) {
37
- await server.stop();
38
- }
39
- await this.gatewayServer.stop();
40
- }
41
- }
42
-
43
- async function startFederatedServer(modules: GraphQLSchemaModule[]) {
44
- const schema = buildSubgraphSchema(modules);
45
- const server = new ApolloServer({
46
- schema,
47
- // Manually installing the inline trace plugin means it doesn't log a message.
48
- plugins: [ApolloServerPluginInlineTrace()],
49
- });
50
- const { url } = await startStandaloneServer(server, { listen: { port: 0 } });
51
- return { url, server };
52
- }
53
-
54
- export async function startSubgraphsAndGateway(
55
- servicesDefs: ServiceDefinition[],
56
- config?: {
57
- gatewayConfig?: GatewayConfig;
58
- gatewayServerConfig?: Partial<ApolloServerOptionsWithGateway<BaseContext>>;
59
- },
60
- ): Promise<Services> {
61
- const backendServers = [];
62
- const serviceList = [];
63
- for (const serviceDef of servicesDefs) {
64
- const { server, url } = await startFederatedServer([serviceDef]);
65
- backendServers.push(server);
66
- serviceList.push({ name: serviceDef.name, url });
67
- }
68
-
69
- const gateway = new ApolloGateway({
70
- serviceList,
71
- ...config?.gatewayConfig,
72
- });
73
- const gatewayServer = new ApolloServer({
74
- gateway,
75
- ...config?.gatewayServerConfig,
76
- });
77
- const { url: gatewayUrl } = await startStandaloneServer(gatewayServer, {
78
- listen: { port: 0 },
79
- });
80
- return new Services(backendServers, gateway, gatewayServer, gatewayUrl);
81
- }
82
-
83
- export function unwrapSingleResultKind(response: GraphQLResponse) {
84
- assert(
85
- response.body.kind === 'single',
86
- `Expected single result, got ${response.body.kind}`,
87
- );
88
- return response.body.singleResult;
89
- }