@apollo/gateway 0.45.0-alpha.1 → 0.46.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 (99) hide show
  1. package/dist/config.d.ts +42 -16
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +28 -18
  4. package/dist/config.js.map +1 -1
  5. package/dist/datasources/RemoteGraphQLDataSource.d.ts.map +1 -1
  6. package/dist/datasources/RemoteGraphQLDataSource.js +4 -1
  7. package/dist/datasources/RemoteGraphQLDataSource.js.map +1 -1
  8. package/dist/executeQueryPlan.d.ts.map +1 -1
  9. package/dist/executeQueryPlan.js +1 -1
  10. package/dist/executeQueryPlan.js.map +1 -1
  11. package/dist/index.d.ts +35 -23
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +205 -308
  14. package/dist/index.js.map +1 -1
  15. package/dist/supergraphManagers/IntrospectAndCompose/index.d.ts +31 -0
  16. package/dist/supergraphManagers/IntrospectAndCompose/index.d.ts.map +1 -0
  17. package/dist/supergraphManagers/IntrospectAndCompose/index.js +112 -0
  18. package/dist/supergraphManagers/IntrospectAndCompose/index.js.map +1 -0
  19. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts +12 -0
  20. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts.map +1 -0
  21. package/dist/{loadServicesFromRemoteEndpoint.js → supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js} +6 -6
  22. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js.map +1 -0
  23. package/dist/supergraphManagers/LegacyFetcher/index.d.ts +33 -0
  24. package/dist/supergraphManagers/LegacyFetcher/index.d.ts.map +1 -0
  25. package/dist/supergraphManagers/LegacyFetcher/index.js +149 -0
  26. package/dist/supergraphManagers/LegacyFetcher/index.js.map +1 -0
  27. package/dist/supergraphManagers/LocalCompose/index.d.ts +19 -0
  28. package/dist/supergraphManagers/LocalCompose/index.d.ts.map +1 -0
  29. package/dist/supergraphManagers/LocalCompose/index.js +55 -0
  30. package/dist/supergraphManagers/LocalCompose/index.js.map +1 -0
  31. package/dist/supergraphManagers/UplinkFetcher/index.d.ts +32 -0
  32. package/dist/supergraphManagers/UplinkFetcher/index.d.ts.map +1 -0
  33. package/dist/supergraphManagers/UplinkFetcher/index.js +96 -0
  34. package/dist/supergraphManagers/UplinkFetcher/index.js.map +1 -0
  35. package/dist/{loadSupergraphSdlFromStorage.d.ts → supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.d.ts} +1 -1
  36. package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.d.ts.map +1 -0
  37. package/dist/{loadSupergraphSdlFromStorage.js → supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.js} +1 -1
  38. package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.js.map +1 -0
  39. package/dist/{outOfBandReporter.d.ts → supergraphManagers/UplinkFetcher/outOfBandReporter.d.ts} +0 -0
  40. package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.d.ts.map +1 -0
  41. package/dist/{outOfBandReporter.js → supergraphManagers/UplinkFetcher/outOfBandReporter.js} +2 -2
  42. package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.js.map +1 -0
  43. package/dist/supergraphManagers/index.d.ts +5 -0
  44. package/dist/supergraphManagers/index.d.ts.map +1 -0
  45. package/dist/supergraphManagers/index.js +12 -0
  46. package/dist/supergraphManagers/index.js.map +1 -0
  47. package/dist/utilities/createHash.d.ts +2 -0
  48. package/dist/utilities/createHash.d.ts.map +1 -0
  49. package/dist/utilities/createHash.js +15 -0
  50. package/dist/utilities/createHash.js.map +1 -0
  51. package/dist/utilities/isNodeLike.d.ts +3 -0
  52. package/dist/utilities/isNodeLike.d.ts.map +1 -0
  53. package/dist/utilities/isNodeLike.js +8 -0
  54. package/dist/utilities/isNodeLike.js.map +1 -0
  55. package/package.json +10 -8
  56. package/src/__mocks__/make-fetch-happen-fetcher.ts +3 -1
  57. package/src/__tests__/executeQueryPlan.test.ts +636 -0
  58. package/src/__tests__/execution-utils.ts +2 -2
  59. package/src/__tests__/gateway/buildService.test.ts +3 -3
  60. package/src/__tests__/gateway/executor.test.ts +1 -1
  61. package/src/__tests__/gateway/lifecycle-hooks.test.ts +58 -99
  62. package/src/__tests__/gateway/opentelemetry.test.ts +8 -3
  63. package/src/__tests__/gateway/queryPlanCache.test.ts +25 -9
  64. package/src/__tests__/gateway/reporting.test.ts +33 -7
  65. package/src/__tests__/gateway/supergraphSdl.test.ts +394 -0
  66. package/src/__tests__/integration/aliases.test.ts +9 -3
  67. package/src/__tests__/integration/configuration.test.ts +109 -12
  68. package/src/__tests__/integration/logger.test.ts +1 -1
  69. package/src/__tests__/integration/networkRequests.test.ts +81 -118
  70. package/src/__tests__/integration/nockMocks.ts +15 -8
  71. package/src/config.ts +149 -40
  72. package/src/datasources/RemoteGraphQLDataSource.ts +8 -2
  73. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +4 -4
  74. package/src/executeQueryPlan.ts +11 -1
  75. package/src/index.ts +314 -485
  76. package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +370 -0
  77. package/src/{__tests__ → supergraphManagers/IntrospectAndCompose/__tests__}/loadServicesFromRemoteEndpoint.test.ts +5 -5
  78. package/src/supergraphManagers/IntrospectAndCompose/__tests__/tsconfig.json +8 -0
  79. package/src/supergraphManagers/IntrospectAndCompose/index.ts +163 -0
  80. package/src/{loadServicesFromRemoteEndpoint.ts → supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.ts} +6 -6
  81. package/src/supergraphManagers/LegacyFetcher/index.ts +229 -0
  82. package/src/supergraphManagers/LocalCompose/index.ts +83 -0
  83. package/src/{__tests__ → supergraphManagers/UplinkFetcher/__tests__}/loadSupergraphSdlFromStorage.test.ts +4 -4
  84. package/src/supergraphManagers/UplinkFetcher/__tests__/tsconfig.json +8 -0
  85. package/src/supergraphManagers/UplinkFetcher/index.ts +128 -0
  86. package/src/{loadSupergraphSdlFromStorage.ts → supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.ts} +3 -3
  87. package/src/{outOfBandReporter.ts → supergraphManagers/UplinkFetcher/outOfBandReporter.ts} +2 -2
  88. package/src/supergraphManagers/index.ts +4 -0
  89. package/src/utilities/createHash.ts +10 -0
  90. package/src/utilities/isNodeLike.ts +11 -0
  91. package/CHANGELOG.md +0 -466
  92. package/dist/loadServicesFromRemoteEndpoint.d.ts +0 -13
  93. package/dist/loadServicesFromRemoteEndpoint.d.ts.map +0 -1
  94. package/dist/loadServicesFromRemoteEndpoint.js.map +0 -1
  95. package/dist/loadSupergraphSdlFromStorage.d.ts.map +0 -1
  96. package/dist/loadSupergraphSdlFromStorage.js.map +0 -1
  97. package/dist/outOfBandReporter.d.ts.map +0 -1
  98. package/dist/outOfBandReporter.js.map +0 -1
  99. package/src/__tests__/gateway/composedSdl.test.ts +0 -44
package/src/config.ts CHANGED
@@ -1,8 +1,11 @@
1
- import { GraphQLError, GraphQLSchema } from "graphql";
2
- import { HeadersInit } from "node-fetch";
1
+ import { GraphQLError, GraphQLSchema } from 'graphql';
2
+ import { HeadersInit } from 'node-fetch';
3
3
  import { fetch } from 'apollo-server-env';
4
- import { GraphQLRequestContextExecutionDidStart, Logger } from "apollo-server-types";
5
- import { ServiceDefinition } from "@apollo/federation";
4
+ import {
5
+ GraphQLRequestContextExecutionDidStart,
6
+ Logger,
7
+ } from 'apollo-server-types';
8
+ import { ServiceDefinition } from '@apollo/federation';
6
9
  import { GraphQLDataSource } from './datasources/types';
7
10
  import { QueryPlan } from '@apollo/query-planner';
8
11
  import { OperationContext } from './operationContext';
@@ -62,7 +65,7 @@ export type CompositionInfo =
62
65
  | ServiceDefinitionCompositionInfo
63
66
  | SupergraphSdlCompositionInfo;
64
67
 
65
- export type Experimental_DidUpdateCompositionCallback = (
68
+ export type Experimental_DidUpdateSupergraphCallback = (
66
69
  currentConfig: CompositionInfo,
67
70
  previousConfig?: CompositionInfo,
68
71
  ) => void;
@@ -80,7 +83,9 @@ export interface SupergraphSdlUpdate {
80
83
  supergraphSdl: string;
81
84
  }
82
85
 
83
- export function isSupergraphSdlUpdate(update: CompositionUpdate): update is SupergraphSdlUpdate {
86
+ export function isSupergraphSdlUpdate(
87
+ update: CompositionUpdate,
88
+ ): update is SupergraphSdlUpdate {
84
89
  return 'supergraphSdl' in update;
85
90
  }
86
91
 
@@ -119,71 +124,181 @@ interface GatewayConfigBase {
119
124
 
120
125
  // experimental observability callbacks
121
126
  experimental_didResolveQueryPlan?: Experimental_DidResolveQueryPlanCallback;
122
- experimental_didFailComposition?: Experimental_DidFailCompositionCallback;
123
- experimental_didUpdateComposition?: Experimental_DidUpdateCompositionCallback;
127
+ experimental_didUpdateSupergraph?: Experimental_DidUpdateSupergraphCallback;
128
+ /**
129
+ * @deprecated use `pollIntervalInMs` instead
130
+ */
124
131
  experimental_pollInterval?: number;
132
+ pollIntervalInMs?: number;
125
133
  experimental_approximateQueryPlanStoreMiB?: number;
126
134
  experimental_autoFragmentization?: boolean;
127
135
  fetcher?: typeof fetch;
128
136
  serviceHealthCheck?: boolean;
129
137
  }
130
138
 
131
- export interface RemoteGatewayConfig extends GatewayConfigBase {
139
+ // TODO(trevor:removeServiceList)
140
+ export interface ServiceListGatewayConfig extends GatewayConfigBase {
141
+ /**
142
+ * @deprecated: use `supergraphSdl: new IntrospectAndCompose(...)` instead
143
+ */
132
144
  serviceList: ServiceEndpointDefinition[];
145
+ /**
146
+ * @deprecated: use `supergraphSdl: new IntrospectAndCompose(...)` instead
147
+ */
133
148
  introspectionHeaders?:
134
149
  | HeadersInit
135
- | ((service: ServiceEndpointDefinition) => Promise<HeadersInit> | HeadersInit);
150
+ | ((
151
+ service: ServiceEndpointDefinition,
152
+ ) => Promise<HeadersInit> | HeadersInit);
136
153
  }
137
154
 
138
155
  export interface ManagedGatewayConfig extends GatewayConfigBase {
139
156
  /**
140
157
  * This configuration option shouldn't be used unless by recommendation from
141
158
  * Apollo staff.
159
+ *
160
+ * @deprecated: use `uplinkEndpoints` instead
161
+ */
162
+ schemaConfigDeliveryEndpoint?: string;
163
+ /**
164
+ * This defaults to:
165
+ * ['https://uplink.api.apollographql.com/', 'https://aws.uplink.api.apollographql.com/']
166
+ * The first URL points to GCP, the second to AWS. This option should most likely
167
+ * be left to default unless you have a specific reason to change it.
142
168
  */
143
- schemaConfigDeliveryEndpoint?: string; // deprecated
144
169
  uplinkEndpoints?: string[];
145
170
  uplinkMaxRetries?: number;
146
171
  }
147
172
 
173
+ // TODO(trevor:removeServiceList): migrate users to `supergraphSdl` function option
148
174
  interface ManuallyManagedServiceDefsGatewayConfig extends GatewayConfigBase {
175
+ /**
176
+ * @deprecated: use `supergraphSdl` instead (either as a `SupergraphSdlHook` or `SupergraphManager`)
177
+ */
149
178
  experimental_updateServiceDefinitions: Experimental_UpdateServiceDefinitions;
150
179
  }
151
180
 
152
- interface ManuallyManagedSupergraphSdlGatewayConfig extends GatewayConfigBase {
153
- experimental_updateSupergraphSdl: Experimental_UpdateSupergraphSdl
181
+ // TODO(trevor:removeServiceList): migrate users to `supergraphSdl` function option
182
+ interface ExperimentalManuallyManagedSupergraphSdlGatewayConfig
183
+ extends GatewayConfigBase {
184
+ /**
185
+ * @deprecated: use `supergraphSdl` instead (either as a `SupergraphSdlHook` or `SupergraphManager`)
186
+ */
187
+ experimental_updateSupergraphSdl: Experimental_UpdateSupergraphSdl;
188
+ }
189
+
190
+ export function isManuallyManagedSupergraphSdlGatewayConfig(
191
+ config: GatewayConfig,
192
+ ): config is ManuallyManagedSupergraphSdlGatewayConfig {
193
+ return isSupergraphSdlHookConfig(config) || isSupergraphManagerConfig(config);
194
+ }
195
+
196
+ export type SupergraphSdlUpdateFunction = (
197
+ updatedSupergraphSdl: string,
198
+ ) => void;
199
+
200
+ export type SubgraphHealthCheckFunction = (
201
+ supergraphSdl: string,
202
+ ) => Promise<void>;
203
+
204
+ export type GetDataSourceFunction = ({
205
+ name,
206
+ url,
207
+ }: ServiceEndpointDefinition) => GraphQLDataSource;
208
+
209
+ export interface SupergraphSdlHookOptions {
210
+ update: SupergraphSdlUpdateFunction;
211
+ healthCheck: SubgraphHealthCheckFunction;
212
+ getDataSource: GetDataSourceFunction;
213
+ }
214
+ export interface SupergraphSdlHook {
215
+ (options: SupergraphSdlHookOptions): Promise<{
216
+ supergraphSdl: string;
217
+ cleanup?: () => Promise<void>;
218
+ }>;
219
+ }
220
+
221
+ export interface SupergraphManager {
222
+ initialize: SupergraphSdlHook;
223
+ }
224
+
225
+ type ManuallyManagedSupergraphSdlGatewayConfig =
226
+ | SupergraphSdlHookGatewayConfig
227
+ | SupergraphManagerGatewayConfig;
228
+
229
+ export interface SupergraphSdlHookGatewayConfig extends GatewayConfigBase {
230
+ supergraphSdl: SupergraphSdlHook;
231
+ }
232
+
233
+ export interface SupergraphManagerGatewayConfig extends GatewayConfigBase {
234
+ supergraphSdl: SupergraphManager;
154
235
  }
155
236
 
156
237
  type ManuallyManagedGatewayConfig =
157
238
  | ManuallyManagedServiceDefsGatewayConfig
158
- | ManuallyManagedSupergraphSdlGatewayConfig;
239
+ | ExperimentalManuallyManagedSupergraphSdlGatewayConfig
240
+ | ManuallyManagedSupergraphSdlGatewayConfig
241
+ // TODO(trevor:removeServiceList
242
+ | ServiceListGatewayConfig;
159
243
 
244
+ // TODO(trevor:removeServiceList)
160
245
  interface LocalGatewayConfig extends GatewayConfigBase {
246
+ /**
247
+ * @deprecated: use `supergraphSdl: new LocalCompose(...)` instead
248
+ */
161
249
  localServiceList: ServiceDefinition[];
162
250
  }
163
251
 
164
- interface SupergraphSdlGatewayConfig extends GatewayConfigBase {
252
+ interface StaticSupergraphSdlGatewayConfig extends GatewayConfigBase {
165
253
  supergraphSdl: string;
166
254
  }
167
255
 
168
- export type StaticGatewayConfig = LocalGatewayConfig | SupergraphSdlGatewayConfig;
256
+ export type StaticGatewayConfig =
257
+ | LocalGatewayConfig
258
+ | StaticSupergraphSdlGatewayConfig;
169
259
 
170
- type DynamicGatewayConfig =
171
- | ManagedGatewayConfig
172
- | RemoteGatewayConfig
173
- | ManuallyManagedGatewayConfig;
260
+ export type DynamicGatewayConfig =
261
+ | ManagedGatewayConfig
262
+ | ManuallyManagedGatewayConfig;
174
263
 
175
264
  export type GatewayConfig = StaticGatewayConfig | DynamicGatewayConfig;
176
265
 
177
- export function isLocalConfig(config: GatewayConfig): config is LocalGatewayConfig {
266
+ // TODO(trevor:removeServiceList)
267
+ export function isLocalConfig(
268
+ config: GatewayConfig,
269
+ ): config is LocalGatewayConfig {
178
270
  return 'localServiceList' in config;
179
271
  }
180
272
 
181
- export function isRemoteConfig(config: GatewayConfig): config is RemoteGatewayConfig {
273
+ // TODO(trevor:removeServiceList)
274
+ export function isServiceListConfig(
275
+ config: GatewayConfig,
276
+ ): config is ServiceListGatewayConfig {
182
277
  return 'serviceList' in config;
183
278
  }
184
279
 
185
- export function isSupergraphSdlConfig(config: GatewayConfig): config is SupergraphSdlGatewayConfig {
186
- return 'supergraphSdl' in config;
280
+ export function isStaticSupergraphSdlConfig(
281
+ config: GatewayConfig,
282
+ ): config is StaticSupergraphSdlGatewayConfig {
283
+ return 'supergraphSdl' in config && typeof config.supergraphSdl === 'string';
284
+ }
285
+
286
+ export function isSupergraphSdlHookConfig(
287
+ config: GatewayConfig,
288
+ ): config is SupergraphSdlHookGatewayConfig {
289
+ return (
290
+ 'supergraphSdl' in config && typeof config.supergraphSdl === 'function'
291
+ );
292
+ }
293
+
294
+ export function isSupergraphManagerConfig(
295
+ config: GatewayConfig,
296
+ ): config is SupergraphManagerGatewayConfig {
297
+ return (
298
+ 'supergraphSdl' in config &&
299
+ typeof config.supergraphSdl === 'object' &&
300
+ 'initialize' in config.supergraphSdl
301
+ );
187
302
  }
188
303
 
189
304
  // A manually managed config means the user has provided a function which
@@ -192,8 +307,11 @@ export function isManuallyManagedConfig(
192
307
  config: GatewayConfig,
193
308
  ): config is ManuallyManagedGatewayConfig {
194
309
  return (
310
+ isManuallyManagedSupergraphSdlGatewayConfig(config) ||
195
311
  'experimental_updateServiceDefinitions' in config ||
196
- 'experimental_updateSupergraphSdl' in config
312
+ 'experimental_updateSupergraphSdl' in config ||
313
+ // TODO(trevor:removeServiceList)
314
+ isServiceListConfig(config)
197
315
  );
198
316
  }
199
317
 
@@ -203,25 +321,16 @@ export function isManagedConfig(
203
321
  ): config is ManagedGatewayConfig {
204
322
  return (
205
323
  'schemaConfigDeliveryEndpoint' in config ||
206
- (!isRemoteConfig(config) &&
207
- !isLocalConfig(config) &&
208
- !isSupergraphSdlConfig(config) &&
324
+ 'uplinkEndpoints' in config ||
325
+ (!isLocalConfig(config) &&
326
+ !isStaticSupergraphSdlConfig(config) &&
209
327
  !isManuallyManagedConfig(config))
210
328
  );
211
329
  }
212
330
 
213
331
  // A static config is one which loads synchronously on start and never updates
214
- export function isStaticConfig(config: GatewayConfig): config is StaticGatewayConfig {
215
- return isLocalConfig(config) || isSupergraphSdlConfig(config);
216
- }
217
-
218
- // A dynamic config is one which loads asynchronously and (can) update via polling
219
- export function isDynamicConfig(
332
+ export function isStaticConfig(
220
333
  config: GatewayConfig,
221
- ): config is DynamicGatewayConfig {
222
- return (
223
- isRemoteConfig(config) ||
224
- isManagedConfig(config) ||
225
- isManuallyManagedConfig(config)
226
- );
334
+ ): config is StaticGatewayConfig {
335
+ return isLocalConfig(config) || isStaticSupergraphSdlConfig(config);
227
336
  }
@@ -17,18 +17,24 @@ import { isObject } from '../utilities/predicates';
17
17
  import { GraphQLDataSource, GraphQLDataSourceProcessOptions, GraphQLDataSourceRequestKind } from './types';
18
18
  import createSHA from 'apollo-server-core/dist/utils/createSHA';
19
19
  import { parseCacheControlHeader } from './parseCacheControlHeader';
20
-
20
+ import fetcher from 'make-fetch-happen';
21
21
  export class RemoteGraphQLDataSource<
22
22
  TContext extends Record<string, any> = Record<string, any>,
23
23
  > implements GraphQLDataSource<TContext>
24
24
  {
25
- fetcher: typeof fetch = fetch;
25
+ fetcher: typeof fetch;
26
26
 
27
27
  constructor(
28
28
  config?: Partial<RemoteGraphQLDataSource<TContext>> &
29
29
  object &
30
30
  ThisType<RemoteGraphQLDataSource<TContext>>,
31
31
  ) {
32
+ this.fetcher = fetcher.defaults({
33
+ // although this is the default, we want to take extra care and be very
34
+ // explicity to ensure that mutations cannot be retried. please leave this
35
+ // intact.
36
+ retry: false,
37
+ });
32
38
  if (config) {
33
39
  return Object.assign(this, config);
34
40
  }
@@ -1,5 +1,5 @@
1
- import { fetch } from '../../__mocks__/apollo-server-env';
2
- import { makeFetchHappenFetcher } from '../../__mocks__/make-fetch-happen-fetcher';
1
+ import { fetch as customFetcher } from '../../__mocks__/apollo-server-env';
2
+ import { fetch } from '../../__mocks__/make-fetch-happen-fetcher';
3
3
 
4
4
  import {
5
5
  ApolloError,
@@ -263,8 +263,8 @@ describe('fetcher', () => {
263
263
  expect(data).toEqual({ injected: true });
264
264
  });
265
265
 
266
- it('supports a custom fetcher, like `make-fetch-happen`', async () => {
267
- const injectedFetch = makeFetchHappenFetcher.mockJSONResponseOnce({
266
+ it('supports a custom fetcher, like `node-fetch`', async () => {
267
+ const injectedFetch = customFetcher.mockJSONResponseOnce({
268
268
  data: { me: 'james' },
269
269
  });
270
270
  const DataSource = new RemoteGraphQLDataSource({
@@ -523,7 +523,17 @@ function executeSelectionSet(
523
523
  const selections = (selection as QueryPlanFieldNode).selections;
524
524
 
525
525
  if (typeof source[responseName] === 'undefined') {
526
- throw new Error(`Field "${responseName}" was not found in response.`);
526
+ // This method is called to collect the inputs/requires of a fetch. So, assuming query plans are correct
527
+ // (and we have not reason to assume otherwise here), all inputs should be fetched beforehand and the
528
+ // only reason for not finding one of the inputs is that we had an error fetching it _and_ that field
529
+ // is non-nullable (it it was nullable, error fetching the input would have make that input `null`; not
530
+ // having the input means the field is non-nullable so the whole entity had to be nullified/ignored,
531
+ // leading use to not have the field at all).
532
+ // In any case, we don't have all the necessary inputs for this particular entity and should ignore it.
533
+ // Note that an error has already been logged for whichever issue happen while fetching the inputs we're
534
+ // missing here, and that error had much more context, so no reason to log a duplicate (less useful) error
535
+ // here.
536
+ return null;
527
537
  }
528
538
  if (Array.isArray(source[responseName])) {
529
539
  result[responseName] = source[responseName].map((value: any) =>