@apollo/gateway 0.44.0 → 0.45.0

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 (39) hide show
  1. package/CHANGELOG.md +14 -3
  2. package/dist/__generated__/graphqlTypes.d.ts +13 -12
  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 +3 -8
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +6 -17
  8. package/dist/config.js.map +1 -1
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +30 -37
  12. package/dist/index.js.map +1 -1
  13. package/dist/loadSupergraphSdlFromStorage.d.ts +13 -5
  14. package/dist/loadSupergraphSdlFromStorage.d.ts.map +1 -1
  15. package/dist/loadSupergraphSdlFromStorage.js +34 -7
  16. package/dist/loadSupergraphSdlFromStorage.js.map +1 -1
  17. package/dist/outOfBandReporter.d.ts +10 -12
  18. package/dist/outOfBandReporter.d.ts.map +1 -1
  19. package/dist/outOfBandReporter.js +70 -73
  20. package/dist/outOfBandReporter.js.map +1 -1
  21. package/package.json +9 -9
  22. package/src/__generated__/graphqlTypes.ts +13 -12
  23. package/src/__tests__/gateway/reporting.test.ts +5 -3
  24. package/src/__tests__/integration/configuration.test.ts +32 -11
  25. package/src/__tests__/integration/networkRequests.test.ts +22 -22
  26. package/src/__tests__/integration/nockMocks.ts +12 -6
  27. package/src/__tests__/loadSupergraphSdlFromStorage.test.ts +101 -377
  28. package/src/__tests__/nockAssertions.ts +20 -0
  29. package/src/config.ts +10 -43
  30. package/src/index.ts +36 -56
  31. package/src/loadSupergraphSdlFromStorage.ts +54 -8
  32. package/src/outOfBandReporter.ts +87 -89
  33. package/dist/legacyLoadServicesFromStorage.d.ts +0 -20
  34. package/dist/legacyLoadServicesFromStorage.d.ts.map +0 -1
  35. package/dist/legacyLoadServicesFromStorage.js +0 -62
  36. package/dist/legacyLoadServicesFromStorage.js.map +0 -1
  37. package/src/__tests__/integration/legacyNetworkRequests.test.ts +0 -279
  38. package/src/__tests__/integration/legacyNockMocks.ts +0 -113
  39. package/src/legacyLoadServicesFromStorage.ts +0 -170
package/src/config.ts CHANGED
@@ -135,31 +135,16 @@ export interface RemoteGatewayConfig extends GatewayConfigBase {
135
135
  | ((service: ServiceEndpointDefinition) => Promise<HeadersInit> | HeadersInit);
136
136
  }
137
137
 
138
- // TODO(trevor:cloudconfig): This type goes away
139
- export interface LegacyManagedGatewayConfig extends GatewayConfigBase {
140
- federationVersion?: number;
141
- /**
142
- * Setting this to null will cause the gateway to use the old mechanism for
143
- * managed federation via GCS + composition.
144
- */
145
- schemaConfigDeliveryEndpoint: null;
146
- }
147
-
148
- // TODO(trevor:cloudconfig): This type becomes the only managed config
149
- export interface PrecomposedManagedGatewayConfig extends GatewayConfigBase {
138
+ export interface ManagedGatewayConfig extends GatewayConfigBase {
150
139
  /**
151
140
  * This configuration option shouldn't be used unless by recommendation from
152
- * Apollo staff. This can also be set to `null` (see above) in order to revert
153
- * to the previous mechanism for managed federation.
141
+ * Apollo staff.
154
142
  */
155
- schemaConfigDeliveryEndpoint?: string;
143
+ schemaConfigDeliveryEndpoint?: string; // deprecated
144
+ uplinkEndpoints?: string[];
145
+ uplinkMaxRetries?: number;
156
146
  }
157
147
 
158
- // TODO(trevor:cloudconfig): This union is no longer needed
159
- export type ManagedGatewayConfig =
160
- | LegacyManagedGatewayConfig
161
- | PrecomposedManagedGatewayConfig;
162
-
163
148
  interface ManuallyManagedServiceDefsGatewayConfig extends GatewayConfigBase {
164
149
  experimental_updateServiceDefinitions: Experimental_UpdateServiceDefinitions;
165
150
  }
@@ -216,30 +201,12 @@ export function isManuallyManagedConfig(
216
201
  export function isManagedConfig(
217
202
  config: GatewayConfig,
218
203
  ): config is ManagedGatewayConfig {
219
- return isPrecomposedManagedConfig(config) || isLegacyManagedConfig(config);
220
- }
221
-
222
- // TODO(trevor:cloudconfig): This merges with `isManagedConfig`
223
- export function isPrecomposedManagedConfig(
224
- config: GatewayConfig,
225
- ): config is PrecomposedManagedGatewayConfig {
226
- return (
227
- !isLegacyManagedConfig(config) &&
228
- (('schemaConfigDeliveryEndpoint' in config &&
229
- typeof config.schemaConfigDeliveryEndpoint === 'string') ||
230
- (!isRemoteConfig(config) &&
231
- !isLocalConfig(config) &&
232
- !isSupergraphSdlConfig(config) &&
233
- !isManuallyManagedConfig(config)))
234
- );
235
- }
236
-
237
- export function isLegacyManagedConfig(
238
- config: GatewayConfig,
239
- ): config is LegacyManagedGatewayConfig {
240
204
  return (
241
- 'schemaConfigDeliveryEndpoint' in config &&
242
- config.schemaConfigDeliveryEndpoint === null
205
+ 'schemaConfigDeliveryEndpoint' in config ||
206
+ (!isRemoteConfig(config) &&
207
+ !isLocalConfig(config) &&
208
+ !isSupergraphSdlConfig(config) &&
209
+ !isManuallyManagedConfig(config))
243
210
  );
244
211
  }
245
212
 
package/src/index.ts CHANGED
@@ -66,12 +66,9 @@ import {
66
66
  ServiceDefinitionUpdate,
67
67
  SupergraphSdlUpdate,
68
68
  CompositionUpdate,
69
- isPrecomposedManagedConfig,
70
- isLegacyManagedConfig,
71
69
  } from './config';
72
- import { loadSupergraphSdlFromStorage } from './loadSupergraphSdlFromStorage';
73
- import { getServiceDefinitionsFromStorage } from './legacyLoadServicesFromStorage';
74
70
  import { buildComposedSchema } from '@apollo/query-planner';
71
+ import { loadSupergraphSdlFromUplinks } from './loadSupergraphSdlFromStorage';
75
72
  import { SpanStatusCode } from '@opentelemetry/api';
76
73
  import { OpenTelemetrySpanNames, tracer } from './utilities/opentelemetry';
77
74
  import { CoreSchema } from '@apollo/core-schema';
@@ -114,20 +111,6 @@ export function getDefaultFetcher() {
114
111
  });
115
112
  }
116
113
 
117
- /**
118
- * TODO(trevor:cloudconfig): Stop exporting this
119
- * @deprecated This will be removed in a future version of @apollo/gateway
120
- */
121
- export const getDefaultGcsFetcher = deprecate(
122
- getDefaultFetcher,
123
- `'getDefaultGcsFetcher' is deprecated. Use 'getDefaultFetcher' instead.`,
124
- );
125
- /**
126
- * TODO(trevor:cloudconfig): Stop exporting this
127
- * @deprecated This will be removed in a future version of @apollo/gateway
128
- */
129
- export const GCS_RETRY_COUNT = 5;
130
-
131
114
  export const HEALTH_CHECK_QUERY =
132
115
  'query __ApolloServiceHealthCheck__ { __typename }';
133
116
  export const SERVICE_DEFINITION_QUERY =
@@ -198,6 +181,8 @@ export class ApolloGateway implements GraphQLService {
198
181
  private fetcher: typeof fetch;
199
182
  private compositionId?: string;
200
183
  private state: GatewayState;
184
+ private errorReportingEndpoint: string | undefined =
185
+ process.env.APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT ?? undefined;
201
186
 
202
187
  // Observe query plan, service info, and operation info prior to execution.
203
188
  // The information made available here will give insight into the resulting
@@ -215,12 +200,11 @@ export class ApolloGateway implements GraphQLService {
215
200
  private updateServiceDefinitions: Experimental_UpdateComposition;
216
201
  // how often service defs should be loaded/updated (in ms)
217
202
  private experimental_pollInterval?: number;
218
- // Configure the endpoint by which gateway will access its precomposed schema.
219
- // * `string` means use that endpoint
220
- // * `null` will revert the gateway to legacy mode (polling GCS and composing the schema itself).
203
+ // Configure the endpoints by which gateway will access its precomposed schema.
204
+ // * An array of URLs means use these endpoints to obtain schema, if one is unavailable then try the next.
221
205
  // * `undefined` means the gateway is not using managed federation
222
- // TODO(trevor:cloudconfig): `null` should be disallowed in the future.
223
- private schemaConfigDeliveryEndpoint?: string | null;
206
+ private uplinkEndpoints?: string[];
207
+ private uplinkMaxRetries?: number;
224
208
 
225
209
  constructor(config?: GatewayConfig) {
226
210
  this.config = {
@@ -248,19 +232,23 @@ export class ApolloGateway implements GraphQLService {
248
232
  this.experimental_pollInterval = config?.experimental_pollInterval;
249
233
 
250
234
  // 1. If config is set to a `string`, use it
251
- // 2. If config is explicitly set to `null`, fallback to GCS
252
- // 3. If the env var is set, use that
253
- // 4. If config is `undefined`, use the default uplink URL
254
-
255
- // This if case unobviously handles 1, 2, and 4.
256
- if (isPrecomposedManagedConfig(this.config)) {
257
- const envEndpoint = process.env.APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT;
258
- this.schemaConfigDeliveryEndpoint =
259
- this.config.schemaConfigDeliveryEndpoint ??
260
- envEndpoint ??
261
- 'https://uplink.api.apollographql.com/';
262
- } else if (isLegacyManagedConfig(this.config)) {
263
- this.schemaConfigDeliveryEndpoint = null;
235
+ // 2. If the env var is set, use that
236
+ // 3. If config is `undefined`, use the default uplink URLs
237
+ if (isManagedConfig(this.config)) {
238
+ const rawEndpointsString = process.env.APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT;
239
+ const envEndpoints = rawEndpointsString?.split(",") ?? null;
240
+
241
+ if (this.config.schemaConfigDeliveryEndpoint && !this.config.uplinkEndpoints) {
242
+ this.uplinkEndpoints = [this.config.schemaConfigDeliveryEndpoint];
243
+ } else {
244
+ this.uplinkEndpoints = this.config.uplinkEndpoints ??
245
+ envEndpoints ?? [
246
+ 'https://uplink.api.apollographql.com/',
247
+ 'https://aws.uplink.api.apollographql.com/'
248
+ ];
249
+ }
250
+
251
+ this.uplinkMaxRetries = this.config.uplinkMaxRetries ?? this.uplinkEndpoints.length * 3;
264
252
  }
265
253
 
266
254
  if (isManuallyManagedConfig(this.config)) {
@@ -980,30 +968,22 @@ export class ApolloGateway implements GraphQLService {
980
968
  );
981
969
  }
982
970
 
983
- // TODO(trevor:cloudconfig): This condition goes away completely
984
- if (isPrecomposedManagedConfig(config)) {
985
- const result = await loadSupergraphSdlFromStorage({
986
- graphRef: this.apolloConfig!.graphRef!,
987
- apiKey: this.apolloConfig!.key!,
988
- endpoint: this.schemaConfigDeliveryEndpoint!,
989
- fetcher: this.fetcher,
990
- compositionId: this.compositionId ?? null,
991
- });
971
+ const result = await loadSupergraphSdlFromUplinks({
972
+ graphRef: this.apolloConfig!.graphRef!,
973
+ apiKey: this.apolloConfig!.key!,
974
+ endpoints: this.uplinkEndpoints!,
975
+ errorReportingEndpoint: this.errorReportingEndpoint,
976
+ fetcher: this.fetcher,
977
+ compositionId: this.compositionId ?? null,
978
+ maxRetries: this.uplinkMaxRetries!,
979
+ });
992
980
 
993
- return result ?? {
981
+ return (
982
+ result ?? {
994
983
  id: this.compositionId!,
995
984
  supergraphSdl: this.supergraphSdl!,
996
985
  }
997
- } else if (isLegacyManagedConfig(config)) {
998
- return getServiceDefinitionsFromStorage({
999
- graphRef: this.apolloConfig!.graphRef!,
1000
- apiKeyHash: this.apolloConfig!.keyHash!,
1001
- federationVersion: config.federationVersion || 1,
1002
- fetcher: this.fetcher,
1003
- });
1004
- } else {
1005
- throw new Error('Programming error: unhandled configuration');
1006
- }
986
+ );
1007
987
  }
1008
988
 
1009
989
  private maybeWarnOnConflictingConfig() {
@@ -1,6 +1,7 @@
1
1
  import { fetch, Response, Request } from 'apollo-server-env';
2
2
  import { GraphQLError } from 'graphql';
3
- import { OutOfBandReporter } from './outOfBandReporter';
3
+ import { SupergraphSdlUpdate } from './config';
4
+ import { submitOutOfBandReportIfConfigured } from './outOfBandReporter';
4
5
  import { SupergraphSdlQuery } from './__generated__/graphqlTypes';
5
6
 
6
7
  // Magic /* GraphQL */ comment below is for codegen, do not remove
@@ -38,19 +39,63 @@ const { name, version } = require('../package.json');
38
39
 
39
40
  const fetchErrorMsg = "An error occurred while fetching your schema from Apollo: ";
40
41
 
42
+ let fetchCounter = 0;
43
+
44
+ export async function loadSupergraphSdlFromUplinks({
45
+ graphRef,
46
+ apiKey,
47
+ endpoints,
48
+ errorReportingEndpoint,
49
+ fetcher,
50
+ compositionId,
51
+ maxRetries,
52
+ }: {
53
+ graphRef: string;
54
+ apiKey: string;
55
+ endpoints: string[];
56
+ errorReportingEndpoint: string | undefined,
57
+ fetcher: typeof fetch;
58
+ compositionId: string | null;
59
+ maxRetries: number
60
+ }) : Promise<SupergraphSdlUpdate | null> {
61
+ let retries = 0;
62
+ let lastException = null;
63
+ let result: SupergraphSdlUpdate | null = null;
64
+ while (retries++ <= maxRetries && result == null) {
65
+ try {
66
+ result = await loadSupergraphSdlFromStorage({
67
+ graphRef,
68
+ apiKey,
69
+ endpoint: endpoints[fetchCounter++ % endpoints.length],
70
+ errorReportingEndpoint,
71
+ fetcher,
72
+ compositionId
73
+ });
74
+ } catch (e) {
75
+ lastException = e;
76
+ }
77
+ }
78
+ if (result === null && lastException !== null) {
79
+ throw lastException;
80
+ }
81
+ return result;
82
+ }
83
+
41
84
  export async function loadSupergraphSdlFromStorage({
42
85
  graphRef,
43
86
  apiKey,
44
87
  endpoint,
88
+ errorReportingEndpoint,
45
89
  fetcher,
46
90
  compositionId,
47
91
  }: {
48
92
  graphRef: string;
49
93
  apiKey: string;
50
94
  endpoint: string;
95
+ errorReportingEndpoint?: string;
51
96
  fetcher: typeof fetch;
52
97
  compositionId: string | null;
53
- }) {
98
+ }) : Promise<SupergraphSdlUpdate | null> {
54
99
  let result: Response;
55
100
  const requestDetails = {
56
101
  method: 'POST',
@@ -72,19 +117,19 @@ export async function loadSupergraphSdlFromStorage({
72
117
 
73
118
  const request: Request = new Request(endpoint, requestDetails);
74
119
 
75
- const OOBReport = new OutOfBandReporter();
76
- const startTime = new Date()
120
+ const startTime = new Date();
77
121
  try {
78
122
  result = await fetcher(endpoint, requestDetails);
79
123
  } catch (e) {
80
124
  const endTime = new Date();
81
125
 
82
- await OOBReport.submitOutOfBandReportIfConfigured({
126
+ await submitOutOfBandReportIfConfigured({
83
127
  error: e,
84
128
  request,
129
+ endpoint: errorReportingEndpoint,
85
130
  startedAt: startTime,
86
131
  endedAt: endTime,
87
- fetcher
132
+ fetcher,
88
133
  });
89
134
 
90
135
  throw new Error(fetchErrorMsg + (e.message ?? e));
@@ -109,13 +154,14 @@ export async function loadSupergraphSdlFromStorage({
109
154
  );
110
155
  }
111
156
  } else {
112
- await OOBReport.submitOutOfBandReportIfConfigured({
157
+ await submitOutOfBandReportIfConfigured({
113
158
  error: new Error(fetchErrorMsg + result.status + ' ' + result.statusText),
114
159
  request,
160
+ endpoint: errorReportingEndpoint,
115
161
  response: result,
116
162
  startedAt: startTime,
117
163
  endedAt: endTime,
118
- fetcher
164
+ fetcher,
119
165
  });
120
166
  throw new Error(fetchErrorMsg + result.status + ' ' + result.statusText);
121
167
  }
@@ -27,102 +27,100 @@ interface OobReportMutationFailure {
27
27
  data?: OobReportMutation;
28
28
  errors: GraphQLError[];
29
29
  }
30
- export class OutOfBandReporter {
31
- static endpoint: string | null = process.env.APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT || null;
32
30
 
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
- }
31
+ export async function submitOutOfBandReportIfConfigured({
32
+ error,
33
+ request,
34
+ endpoint,
35
+ response,
36
+ startedAt,
37
+ endedAt,
38
+ tags,
39
+ fetcher,
40
+ }: {
41
+ error: Error;
42
+ request: Request;
43
+ endpoint: string | undefined;
44
+ response?: Response;
45
+ startedAt: Date;
46
+ endedAt: Date;
47
+ tags?: string[];
48
+ fetcher: typeof fetch;
49
+ }) {
50
+ // don't send report if the endpoint url is not configured
51
+ if (!endpoint) {
52
+ return;
53
+ }
55
54
 
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
- }
55
+ let errorCode: ErrorCode;
56
+ if (!response) {
57
+ errorCode = ErrorCode.ConnectionFailed;
58
+ } else {
59
+ // possible error situations to check against
60
+ switch (response.status) {
61
+ case 400:
62
+ case 413:
63
+ case 422:
64
+ errorCode = ErrorCode.InvalidBody;
65
+ break;
66
+ case 408:
67
+ case 504:
68
+ errorCode = ErrorCode.Timeout;
69
+ break;
70
+ case 502:
71
+ case 503:
72
+ errorCode = ErrorCode.ConnectionFailed;
73
+ break;
74
+ default:
75
+ errorCode = ErrorCode.Other;
78
76
  }
77
+ }
79
78
 
80
- const responseBody: string | undefined = await response?.text();
79
+ const responseBody: string | undefined = await response?.text();
81
80
 
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,
81
+ const variables: OobReportMutationVariables = {
82
+ input: {
83
+ error: {
84
+ code: errorCode,
85
+ message: error.message,
86
+ },
87
+ request: {
88
+ url: request.url,
89
+ body: await request.text(),
101
90
  },
102
- };
91
+ response: response
92
+ ? {
93
+ httpStatusCode: response.status,
94
+ body: responseBody,
95
+ }
96
+ : null,
97
+ startedAt: startedAt.toISOString(),
98
+ endedAt: endedAt.toISOString(),
99
+ tags: tags,
100
+ },
101
+ };
103
102
 
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}`);
103
+ try {
104
+ const oobResponse = await fetcher(endpoint, {
105
+ method: 'POST',
106
+ body: JSON.stringify({
107
+ query: OUT_OF_BAND_REPORTER_QUERY,
108
+ variables,
109
+ }),
110
+ headers: {
111
+ 'apollographql-client-name': name,
112
+ 'apollographql-client-version': version,
113
+ 'user-agent': `${name}/${version}`,
114
+ 'content-type': 'application/json',
115
+ },
116
+ });
117
+ const parsedResponse: OobReportMutationResult = await oobResponse.json();
118
+ if (!parsedResponse?.data?.reportError) {
119
+ throw new Error(
120
+ `Out-of-band error reporting failed: ${oobResponse.status} ${oobResponse.statusText}`,
121
+ );
126
122
  }
123
+ } catch (e) {
124
+ throw new Error(`Out-of-band error reporting failed: ${e.message ?? e}`);
127
125
  }
128
126
  }
@@ -1,20 +0,0 @@
1
- import { fetch } from 'apollo-server-env';
2
- import { ServiceDefinitionUpdate } from './config';
3
- interface ImplementingServiceLocation {
4
- name: string;
5
- path: string;
6
- }
7
- export interface CompositionMetadata {
8
- formatVersion: number;
9
- id: string;
10
- implementingServiceLocations: ImplementingServiceLocation[];
11
- schemaHash: string;
12
- }
13
- export declare function getServiceDefinitionsFromStorage({ graphRef, apiKeyHash, federationVersion, fetcher, }: {
14
- graphRef: string;
15
- apiKeyHash: string;
16
- federationVersion: number;
17
- fetcher: typeof fetch;
18
- }): Promise<ServiceDefinitionUpdate>;
19
- export {};
20
- //# sourceMappingURL=legacyLoadServicesFromStorage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"legacyLoadServicesFromStorage.d.ts","sourceRoot":"","sources":["../src/legacyLoadServicesFromStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAiBnD,UAAU,2BAA2B;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B,EAAE,2BAA2B,EAAE,CAAC;IAC5D,UAAU,EAAE,MAAM,CAAC;CACpB;AAsED,wBAAsB,gCAAgC,CAAC,EACrD,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,OAAO,KAAK,CAAC;CACvB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA4DnC"}
@@ -1,62 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getServiceDefinitionsFromStorage = void 0;
4
- const graphql_1 = require("graphql");
5
- const envOverridePartialSchemaBaseUrl = 'APOLLO_PARTIAL_SCHEMA_BASE_URL';
6
- const envOverrideStorageSecretBaseUrl = 'APOLLO_STORAGE_SECRET_BASE_URL';
7
- const urlFromEnvOrDefault = (envKey, fallback) => (process.env[envKey] || fallback).replace(/\/$/, '');
8
- const urlPartialSchemaBase = urlFromEnvOrDefault(envOverridePartialSchemaBaseUrl, 'https://federation.api.apollographql.com/');
9
- const urlStorageSecretBase = urlFromEnvOrDefault(envOverrideStorageSecretBaseUrl, 'https://storage-secrets.api.apollographql.com/');
10
- function getStorageSecretUrl(graphId, apiKeyHash) {
11
- return `${urlStorageSecretBase}/${graphId}/storage-secret/${apiKeyHash}.json`;
12
- }
13
- function fetchApolloGcs(fetcher, ...args) {
14
- const [input, init] = args;
15
- const url = (typeof input === 'object' && input.url) || input;
16
- return fetcher(input, init)
17
- .catch((fetchError) => {
18
- throw new Error('Cannot access Apollo storage: ' + fetchError);
19
- })
20
- .then(async (response) => {
21
- if (response.ok || response.status === 304) {
22
- return response;
23
- }
24
- const body = await response.text();
25
- if (response.status === 403 && body.includes('AccessDenied')) {
26
- throw new Error('Unable to authenticate with Apollo storage ' +
27
- 'while fetching ' +
28
- url +
29
- '. Ensure that the API key is ' +
30
- 'configured properly and that a federated service has been ' +
31
- 'pushed. For details, see ' +
32
- 'https://go.apollo.dev/g/resolve-access-denied.');
33
- }
34
- throw new Error('Could not communicate with Apollo storage: ' + body);
35
- });
36
- }
37
- async function getServiceDefinitionsFromStorage({ graphRef, apiKeyHash, federationVersion, fetcher, }) {
38
- const at = graphRef.indexOf('@');
39
- const graphId = at === -1 ? graphRef : graphRef.substring(0, at);
40
- const graphVariant = at === -1 ? 'current' : graphRef.substring(at + 1);
41
- const storageSecretUrl = getStorageSecretUrl(graphId, apiKeyHash);
42
- const secret = await fetchApolloGcs(fetcher, storageSecretUrl).then((res) => res.json());
43
- const baseUrl = `${urlPartialSchemaBase}/${secret}/${graphVariant}/v${federationVersion}`;
44
- const compositionConfigResponse = await fetchApolloGcs(fetcher, `${baseUrl}/composition-config-link`);
45
- if (compositionConfigResponse.status === 304) {
46
- return { isNewSchema: false };
47
- }
48
- const linkFileResult = await compositionConfigResponse.json();
49
- const compositionMetadata = await fetchApolloGcs(fetcher, `${urlPartialSchemaBase}/${linkFileResult.configPath}`).then((res) => res.json());
50
- const serviceDefinitions = await Promise.all(compositionMetadata.implementingServiceLocations.map(async ({ name, path }) => {
51
- const { url, partialSchemaPath } = await fetcher(`${urlPartialSchemaBase}/${path}`).then((response) => response.json());
52
- const sdl = await fetcher(`${urlPartialSchemaBase}/${partialSchemaPath}`).then((response) => response.text());
53
- return { name, url, typeDefs: (0, graphql_1.parse)(sdl) };
54
- }));
55
- return {
56
- serviceDefinitions,
57
- compositionMetadata,
58
- isNewSchema: true,
59
- };
60
- }
61
- exports.getServiceDefinitionsFromStorage = getServiceDefinitionsFromStorage;
62
- //# sourceMappingURL=legacyLoadServicesFromStorage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"legacyLoadServicesFromStorage.js","sourceRoot":"","sources":["../src/legacyLoadServicesFromStorage.ts"],"names":[],"mappings":"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"}