@apollo/gateway 2.0.0-alpha.0 → 2.0.0-alpha.4

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 (154) hide show
  1. package/README.md +1 -1
  2. package/dist/__generated__/graphqlTypes.d.ts +13 -11
  3. package/dist/__generated__/graphqlTypes.d.ts.map +1 -1
  4. package/dist/__generated__/graphqlTypes.js.map +1 -1
  5. package/dist/config.d.ts +45 -24
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +30 -31
  8. package/dist/config.js.map +1 -1
  9. package/dist/datasources/LocalGraphQLDataSource.js.map +1 -1
  10. package/dist/datasources/RemoteGraphQLDataSource.d.ts.map +1 -1
  11. package/dist/datasources/RemoteGraphQLDataSource.js +4 -1
  12. package/dist/datasources/RemoteGraphQLDataSource.js.map +1 -1
  13. package/dist/datasources/types.d.ts +1 -1
  14. package/dist/datasources/types.d.ts.map +1 -1
  15. package/dist/executeQueryPlan.d.ts.map +1 -1
  16. package/dist/executeQueryPlan.js +6 -6
  17. package/dist/executeQueryPlan.js.map +1 -1
  18. package/dist/index.d.ts +36 -23
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +197 -297
  21. package/dist/index.js.map +1 -1
  22. package/dist/operationContext.js +0 -1
  23. package/dist/operationContext.js.map +1 -1
  24. package/dist/schema-helper/addResolversToSchema.d.ts +4 -0
  25. package/dist/schema-helper/addResolversToSchema.d.ts.map +1 -0
  26. package/dist/schema-helper/addResolversToSchema.js +62 -0
  27. package/dist/schema-helper/addResolversToSchema.js.map +1 -0
  28. package/dist/schema-helper/error.d.ts +6 -0
  29. package/dist/schema-helper/error.d.ts.map +1 -0
  30. package/dist/schema-helper/error.js +14 -0
  31. package/dist/schema-helper/error.js.map +1 -0
  32. package/dist/schema-helper/index.d.ts +4 -0
  33. package/dist/schema-helper/index.d.ts.map +1 -0
  34. package/dist/schema-helper/index.js +16 -0
  35. package/dist/schema-helper/index.js.map +1 -0
  36. package/dist/schema-helper/resolverMap.d.ts +16 -0
  37. package/dist/schema-helper/resolverMap.d.ts.map +1 -0
  38. package/dist/schema-helper/resolverMap.js +3 -0
  39. package/dist/schema-helper/resolverMap.js.map +1 -0
  40. package/dist/supergraphManagers/IntrospectAndCompose/index.d.ts +31 -0
  41. package/dist/supergraphManagers/IntrospectAndCompose/index.d.ts.map +1 -0
  42. package/dist/supergraphManagers/IntrospectAndCompose/index.js +112 -0
  43. package/dist/supergraphManagers/IntrospectAndCompose/index.js.map +1 -0
  44. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts +12 -0
  45. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts.map +1 -0
  46. package/dist/{loadServicesFromRemoteEndpoint.js → supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js} +6 -6
  47. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js.map +1 -0
  48. package/dist/supergraphManagers/LegacyFetcher/index.d.ts +33 -0
  49. package/dist/supergraphManagers/LegacyFetcher/index.d.ts.map +1 -0
  50. package/dist/supergraphManagers/LegacyFetcher/index.js +149 -0
  51. package/dist/supergraphManagers/LegacyFetcher/index.js.map +1 -0
  52. package/dist/supergraphManagers/LocalCompose/index.d.ts +19 -0
  53. package/dist/supergraphManagers/LocalCompose/index.d.ts.map +1 -0
  54. package/dist/supergraphManagers/LocalCompose/index.js +55 -0
  55. package/dist/supergraphManagers/LocalCompose/index.js.map +1 -0
  56. package/dist/supergraphManagers/UplinkFetcher/index.d.ts +32 -0
  57. package/dist/supergraphManagers/UplinkFetcher/index.d.ts.map +1 -0
  58. package/dist/supergraphManagers/UplinkFetcher/index.js +96 -0
  59. package/dist/supergraphManagers/UplinkFetcher/index.js.map +1 -0
  60. package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.d.ts +21 -0
  61. package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.d.ts.map +1 -0
  62. package/dist/{loadSupergraphSdlFromStorage.js → supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.js} +41 -10
  63. package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.js.map +1 -0
  64. package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.d.ts +13 -0
  65. package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.d.ts.map +1 -0
  66. package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.js +85 -0
  67. package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.js.map +1 -0
  68. package/dist/supergraphManagers/index.d.ts +5 -0
  69. package/dist/supergraphManagers/index.d.ts.map +1 -0
  70. package/dist/supergraphManagers/index.js +12 -0
  71. package/dist/supergraphManagers/index.js.map +1 -0
  72. package/dist/utilities/array.js +1 -1
  73. package/dist/utilities/array.js.map +1 -1
  74. package/dist/utilities/createHash.d.ts +2 -0
  75. package/dist/utilities/createHash.d.ts.map +1 -0
  76. package/dist/utilities/createHash.js +15 -0
  77. package/dist/utilities/createHash.js.map +1 -0
  78. package/dist/utilities/isNodeLike.d.ts +3 -0
  79. package/dist/utilities/isNodeLike.d.ts.map +1 -0
  80. package/dist/utilities/isNodeLike.js +8 -0
  81. package/dist/utilities/isNodeLike.js.map +1 -0
  82. package/package.json +9 -9
  83. package/src/__generated__/graphqlTypes.ts +13 -11
  84. package/src/__mocks__/make-fetch-happen-fetcher.ts +3 -1
  85. package/src/__tests__/buildQueryPlan.test.ts +1 -1
  86. package/src/__tests__/executeQueryPlan.test.ts +1171 -77
  87. package/src/__tests__/execution-utils.ts +5 -7
  88. package/src/__tests__/gateway/buildService.test.ts +3 -3
  89. package/src/__tests__/gateway/endToEnd.test.ts +1 -1
  90. package/src/__tests__/gateway/executor.test.ts +3 -1
  91. package/src/__tests__/gateway/lifecycle-hooks.test.ts +59 -121
  92. package/src/__tests__/gateway/opentelemetry.test.ts +8 -3
  93. package/src/__tests__/gateway/queryPlanCache.test.ts +25 -9
  94. package/src/__tests__/gateway/reporting.test.ts +42 -13
  95. package/src/__tests__/gateway/supergraphSdl.test.ts +397 -0
  96. package/src/__tests__/integration/aliases.test.ts +9 -3
  97. package/src/__tests__/integration/configuration.test.ts +140 -21
  98. package/src/__tests__/integration/logger.test.ts +2 -2
  99. package/src/__tests__/integration/networkRequests.test.ts +126 -149
  100. package/src/__tests__/integration/nockMocks.ts +57 -16
  101. package/src/__tests__/nockAssertions.ts +20 -0
  102. package/src/config.ts +153 -77
  103. package/src/core/__tests__/core.test.ts +6 -6
  104. package/src/datasources/LocalGraphQLDataSource.ts +1 -1
  105. package/src/datasources/RemoteGraphQLDataSource.ts +8 -2
  106. package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +1 -1
  107. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +4 -4
  108. package/src/datasources/types.ts +1 -1
  109. package/src/executeQueryPlan.ts +18 -9
  110. package/src/index.ts +323 -481
  111. package/src/make-fetch-happen.d.ts +1 -1
  112. package/src/operationContext.ts +2 -2
  113. package/src/schema-helper/addResolversToSchema.ts +83 -0
  114. package/src/schema-helper/error.ts +11 -0
  115. package/src/schema-helper/index.ts +3 -0
  116. package/src/schema-helper/resolverMap.ts +23 -0
  117. package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +370 -0
  118. package/src/{__tests__ → supergraphManagers/IntrospectAndCompose/__tests__}/loadServicesFromRemoteEndpoint.test.ts +7 -7
  119. package/src/supergraphManagers/IntrospectAndCompose/__tests__/tsconfig.json +8 -0
  120. package/src/supergraphManagers/IntrospectAndCompose/index.ts +160 -0
  121. package/src/{loadServicesFromRemoteEndpoint.ts → supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.ts} +7 -7
  122. package/src/supergraphManagers/LegacyFetcher/index.ts +226 -0
  123. package/src/supergraphManagers/LocalCompose/index.ts +79 -0
  124. package/src/supergraphManagers/UplinkFetcher/__tests__/loadSupergraphSdlFromStorage.test.ts +343 -0
  125. package/src/supergraphManagers/UplinkFetcher/__tests__/tsconfig.json +8 -0
  126. package/src/supergraphManagers/UplinkFetcher/index.ts +128 -0
  127. package/src/{loadSupergraphSdlFromStorage.ts → supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.ts} +63 -14
  128. package/src/supergraphManagers/UplinkFetcher/outOfBandReporter.ts +126 -0
  129. package/src/supergraphManagers/index.ts +4 -0
  130. package/src/utilities/__tests__/cleanErrorOfInaccessibleElements.test.ts +13 -10
  131. package/src/utilities/array.ts +1 -1
  132. package/src/utilities/createHash.ts +10 -0
  133. package/src/utilities/isNodeLike.ts +11 -0
  134. package/CHANGELOG.md +0 -452
  135. package/dist/legacyLoadServicesFromStorage.d.ts +0 -20
  136. package/dist/legacyLoadServicesFromStorage.d.ts.map +0 -1
  137. package/dist/legacyLoadServicesFromStorage.js +0 -62
  138. package/dist/legacyLoadServicesFromStorage.js.map +0 -1
  139. package/dist/loadServicesFromRemoteEndpoint.d.ts +0 -13
  140. package/dist/loadServicesFromRemoteEndpoint.d.ts.map +0 -1
  141. package/dist/loadServicesFromRemoteEndpoint.js.map +0 -1
  142. package/dist/loadSupergraphSdlFromStorage.d.ts +0 -12
  143. package/dist/loadSupergraphSdlFromStorage.d.ts.map +0 -1
  144. package/dist/loadSupergraphSdlFromStorage.js.map +0 -1
  145. package/dist/outOfBandReporter.d.ts +0 -15
  146. package/dist/outOfBandReporter.d.ts.map +0 -1
  147. package/dist/outOfBandReporter.js +0 -88
  148. package/dist/outOfBandReporter.js.map +0 -1
  149. package/src/__tests__/gateway/composedSdl.test.ts +0 -44
  150. package/src/__tests__/integration/legacyNetworkRequests.test.ts +0 -279
  151. package/src/__tests__/integration/legacyNockMocks.ts +0 -113
  152. package/src/__tests__/loadSupergraphSdlFromStorage.test.ts +0 -664
  153. package/src/legacyLoadServicesFromStorage.ts +0 -170
  154. package/src/outOfBandReporter.ts +0 -128
@@ -1,170 +0,0 @@
1
- import { fetch } from 'apollo-server-env';
2
- import { parse } from 'graphql';
3
- import { ServiceDefinitionUpdate } from './config';
4
-
5
- interface LinkFileResult {
6
- configPath: string;
7
- formatVersion: number;
8
- }
9
-
10
- interface ImplementingService {
11
- formatVersion: number;
12
- graphID: string;
13
- graphVariant: string;
14
- name: string;
15
- revision: string;
16
- url: string;
17
- partialSchemaPath: string;
18
- }
19
-
20
- interface ImplementingServiceLocation {
21
- name: string;
22
- path: string;
23
- }
24
-
25
- export interface CompositionMetadata {
26
- formatVersion: number;
27
- id: string;
28
- implementingServiceLocations: ImplementingServiceLocation[];
29
- schemaHash: string;
30
- }
31
-
32
- const envOverridePartialSchemaBaseUrl = 'APOLLO_PARTIAL_SCHEMA_BASE_URL';
33
- const envOverrideStorageSecretBaseUrl = 'APOLLO_STORAGE_SECRET_BASE_URL';
34
-
35
- const urlFromEnvOrDefault = (envKey: string, fallback: string) =>
36
- (process.env[envKey] || fallback).replace(/\/$/, '');
37
-
38
- // Generate and cache our desired operation manifest URL.
39
- const urlPartialSchemaBase = urlFromEnvOrDefault(
40
- envOverridePartialSchemaBaseUrl,
41
- 'https://federation.api.apollographql.com/',
42
- );
43
-
44
- const urlStorageSecretBase: string = urlFromEnvOrDefault(
45
- envOverrideStorageSecretBaseUrl,
46
- 'https://storage-secrets.api.apollographql.com/',
47
- );
48
-
49
- function getStorageSecretUrl(graphId: string, apiKeyHash: string): string {
50
- return `${urlStorageSecretBase}/${graphId}/storage-secret/${apiKeyHash}.json`;
51
- }
52
-
53
- function fetchApolloGcs(
54
- fetcher: typeof fetch,
55
- ...args: Parameters<typeof fetch>
56
- ): ReturnType<typeof fetch> {
57
- const [input, init] = args;
58
-
59
- // Used in logging.
60
- const url = (typeof input === 'object' && input.url) || input;
61
-
62
- return fetcher(input, init)
63
- .catch((fetchError) => {
64
- throw new Error('Cannot access Apollo storage: ' + fetchError);
65
- })
66
- .then(async (response) => {
67
- // If the fetcher has a cache and has implemented ETag validation, then
68
- // a 304 response may be returned. Either way, we will return the
69
- // non-JSON-parsed version and let the caller decide if that's important
70
- // to their needs.
71
- if (response.ok || response.status === 304) {
72
- return response;
73
- }
74
-
75
- // We won't make any assumptions that the body is anything but text, to
76
- // avoid parsing errors in this unknown condition.
77
- const body = await response.text();
78
-
79
- // Google Cloud Storage returns an `application/xml` error under error
80
- // conditions. We'll special-case our known errors, and resort to
81
- // printing the body for others.
82
- if (response.status === 403 && body.includes('AccessDenied')) {
83
- throw new Error(
84
- 'Unable to authenticate with Apollo storage ' +
85
- 'while fetching ' +
86
- url +
87
- '. Ensure that the API key is ' +
88
- 'configured properly and that a federated service has been ' +
89
- 'pushed. For details, see ' +
90
- 'https://go.apollo.dev/g/resolve-access-denied.',
91
- );
92
- }
93
-
94
- // Normally, we'll try to keep the logs clean with errors we expect.
95
- // If it's not a known error, reveal the full body for debugging.
96
- throw new Error('Could not communicate with Apollo storage: ' + body);
97
- });
98
- }
99
-
100
- export async function getServiceDefinitionsFromStorage({
101
- graphRef,
102
- apiKeyHash,
103
- federationVersion,
104
- fetcher,
105
- }: {
106
- graphRef: string;
107
- apiKeyHash: string;
108
- federationVersion: number;
109
- fetcher: typeof fetch;
110
- }): Promise<ServiceDefinitionUpdate> {
111
- // The protocol for talking to GCS requires us to split the graph ref
112
- // into ID and variant; sigh.
113
- const at = graphRef.indexOf('@');
114
- const graphId = at === -1 ? graphRef : graphRef.substring(0, at);
115
- const graphVariant = at === -1 ? 'current' : graphRef.substring(at + 1);
116
-
117
- // fetch the storage secret
118
- const storageSecretUrl = getStorageSecretUrl(graphId, apiKeyHash);
119
-
120
- // The storage secret is a JSON string (e.g. `"secret"`).
121
- const secret: string = await fetchApolloGcs(
122
- fetcher,
123
- storageSecretUrl,
124
- ).then((res) => res.json());
125
-
126
- const baseUrl = `${urlPartialSchemaBase}/${secret}/${graphVariant}/v${federationVersion}`;
127
-
128
- const compositionConfigResponse = await fetchApolloGcs(
129
- fetcher,
130
- `${baseUrl}/composition-config-link`,
131
- );
132
-
133
- if (compositionConfigResponse.status === 304) {
134
- return { isNewSchema: false };
135
- }
136
-
137
- const linkFileResult: LinkFileResult = await compositionConfigResponse.json();
138
-
139
- const compositionMetadata: CompositionMetadata = await fetchApolloGcs(
140
- fetcher,
141
- `${urlPartialSchemaBase}/${linkFileResult.configPath}`,
142
- ).then((res) => res.json());
143
-
144
- // It's important to maintain the original order here
145
- const serviceDefinitions = await Promise.all(
146
- compositionMetadata.implementingServiceLocations.map(
147
- async ({ name, path }) => {
148
- const { url, partialSchemaPath }: ImplementingService = await fetcher(
149
- `${urlPartialSchemaBase}/${path}`,
150
- ).then((response) => response.json());
151
-
152
- const sdl = await fetcher(
153
- `${urlPartialSchemaBase}/${partialSchemaPath}`,
154
- ).then((response) => response.text());
155
-
156
- return { name, url, typeDefs: parse(sdl) };
157
- },
158
- ),
159
- );
160
-
161
- // explicity return that this is a new schema, as the link file has changed.
162
- // we can't use the hit property of the fetchPartialSchemaFiles, as the partial
163
- // schema may all be cache hits with the final schema still being new
164
- // (for instance if a partial schema is removed or a partial schema is rolled back to a prior version, which is still in cache)
165
- return {
166
- serviceDefinitions,
167
- compositionMetadata,
168
- isNewSchema: true,
169
- };
170
- }
@@ -1,128 +0,0 @@
1
- import { fetch, Response, Request } from 'apollo-server-env';
2
- import { GraphQLError } from 'graphql';
3
- import {
4
- ErrorCode,
5
- OobReportMutation,
6
- OobReportMutationVariables,
7
- } from './__generated__/graphqlTypes';
8
-
9
- // Magic /* GraphQL */ comment below is for codegen, do not remove
10
- export const OUT_OF_BAND_REPORTER_QUERY = /* GraphQL */`#graphql
11
- mutation OOBReport($input: APIMonitoringReport) {
12
- reportError(report: $input)
13
- }
14
- `;
15
-
16
- const { name, version } = require('../package.json');
17
-
18
- type OobReportMutationResult =
19
- | OobReportMutationSuccess
20
- | OobReportMutationFailure;
21
-
22
- interface OobReportMutationSuccess {
23
- data: OobReportMutation;
24
- }
25
-
26
- interface OobReportMutationFailure {
27
- data?: OobReportMutation;
28
- errors: GraphQLError[];
29
- }
30
- export class OutOfBandReporter {
31
- static endpoint: string | null = process.env.APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT || null;
32
-
33
- async submitOutOfBandReportIfConfigured({
34
- error,
35
- request,
36
- response,
37
- startedAt,
38
- endedAt,
39
- tags,
40
- fetcher,
41
- }: {
42
- error: Error;
43
- request: Request;
44
- response?: Response;
45
- startedAt: Date;
46
- endedAt: Date;
47
- tags?: string[];
48
- fetcher: typeof fetch;
49
- }) {
50
-
51
- // don't send report if the endpoint url is not configured
52
- if (!OutOfBandReporter.endpoint) {
53
- return;
54
- }
55
-
56
- let errorCode: ErrorCode;
57
- if (!response) {
58
- errorCode = ErrorCode.ConnectionFailed;
59
- } else {
60
- // possible error situations to check against
61
- switch (response.status) {
62
- case 400:
63
- case 413:
64
- case 422:
65
- errorCode = ErrorCode.InvalidBody;
66
- break;
67
- case 408:
68
- case 504:
69
- errorCode = ErrorCode.Timeout;
70
- break;
71
- case 502:
72
- case 503:
73
- errorCode = ErrorCode.ConnectionFailed;
74
- break;
75
- default:
76
- errorCode = ErrorCode.Other;
77
- }
78
- }
79
-
80
- const responseBody: string | undefined = await response?.text();
81
-
82
- const variables: OobReportMutationVariables = {
83
- input: {
84
- error: {
85
- code: errorCode,
86
- message: error.message,
87
- },
88
- request: {
89
- url: request.url,
90
- body: await request.text(),
91
- },
92
- response: response
93
- ? {
94
- httpStatusCode: response.status,
95
- body: responseBody,
96
- }
97
- : null,
98
- startedAt: startedAt.toISOString(),
99
- endedAt: endedAt.toISOString(),
100
- tags: tags,
101
- },
102
- };
103
-
104
- try {
105
- const oobResponse = await fetcher(OutOfBandReporter.endpoint, {
106
- method: 'POST',
107
- body: JSON.stringify({
108
- query: OUT_OF_BAND_REPORTER_QUERY,
109
- variables,
110
- }),
111
- headers: {
112
- 'apollographql-client-name': name,
113
- 'apollographql-client-version': version,
114
- 'user-agent': `${name}/${version}`,
115
- 'content-type': 'application/json',
116
- },
117
- });
118
- const parsedResponse: OobReportMutationResult = await oobResponse.json();
119
- if (!parsedResponse?.data?.reportError) {
120
- throw new Error(
121
- `Out-of-band error reporting failed: ${oobResponse.status} ${oobResponse.statusText}`,
122
- );
123
- }
124
- } catch (e) {
125
- throw new Error(`Out-of-band error reporting failed: ${e.message ?? e}`);
126
- }
127
- }
128
- }