UNPKG

74.1 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5const graphql = require('graphql');
6const utils = require('@graphql-tools/utils');
7const execute_js = require('graphql/execution/execute.js');
8const valueOrPromise = require('value-or-promise');
9const batchExecute = require('@graphql-tools/batch-execute');
10
11function applySchemaTransforms(originalWrappingSchema, subschemaConfig, transformedSchema) {
12 const schemaTransforms = subschemaConfig.transforms;
13 if (schemaTransforms == null) {
14 return originalWrappingSchema;
15 }
16 return schemaTransforms.reduce((schema, transform) => transform.transformSchema != null
17 ? transform.transformSchema(schema, subschemaConfig, transformedSchema)
18 : schema, originalWrappingSchema);
19}
20
21function isSubschema(value) {
22 return Boolean(value.transformedSchema);
23}
24class Subschema {
25 constructor(config) {
26 var _a;
27 this.schema = config.schema;
28 this.executor = config.executor;
29 this.batch = config.batch;
30 this.batchingOptions = config.batchingOptions;
31 this.createProxyingResolver = config.createProxyingResolver;
32 this.transforms = (_a = config.transforms) !== null && _a !== void 0 ? _a : [];
33 this.transformedSchema = applySchemaTransforms(this.schema, config);
34 this.merge = config.merge;
35 }
36}
37
38function memoizeInfoAnd2Objects(fn) {
39 let cache1;
40 function memoized(a1, a2, a3) {
41 if (!cache1) {
42 cache1 = new WeakMap();
43 const cache2 = new WeakMap();
44 cache1.set(a1.fieldNodes, cache2);
45 const cache3 = new WeakMap();
46 cache2.set(a2, cache3);
47 const newValue = fn(a1, a2, a3);
48 cache3.set(a3, newValue);
49 return newValue;
50 }
51 let cache2 = cache1.get(a1.fieldNodes);
52 if (!cache2) {
53 cache2 = new WeakMap();
54 cache1.set(a1.fieldNodes, cache2);
55 const cache3 = new WeakMap();
56 cache2.set(a2, cache3);
57 const newValue = fn(a1, a2, a3);
58 cache3.set(a3, newValue);
59 return newValue;
60 }
61 let cache3 = cache2.get(a2);
62 if (!cache3) {
63 cache3 = new WeakMap();
64 cache2.set(a2, cache3);
65 const newValue = fn(a1, a2, a3);
66 cache3.set(a3, newValue);
67 return newValue;
68 }
69 const cachedValue = cache3.get(a3);
70 if (cachedValue === undefined) {
71 const newValue = fn(a1, a2, a3);
72 cache3.set(a3, newValue);
73 return newValue;
74 }
75 return cachedValue;
76 }
77 return memoized;
78}
79function memoize4(fn) {
80 let cache1;
81 function memoized(a1, a2, a3, a4) {
82 if (!cache1) {
83 cache1 = new WeakMap();
84 const cache2 = new WeakMap();
85 cache1.set(a1, cache2);
86 const cache3 = new WeakMap();
87 cache2.set(a2, cache3);
88 const cache4 = new WeakMap();
89 cache3.set(a3, cache4);
90 const newValue = fn(a1, a2, a3, a4);
91 cache4.set(a4, newValue);
92 return newValue;
93 }
94 let cache2 = cache1.get(a1);
95 if (!cache2) {
96 cache2 = new WeakMap();
97 cache1.set(a1, cache2);
98 const cache3 = new WeakMap();
99 cache2.set(a2, cache3);
100 const cache4 = new WeakMap();
101 cache3.set(a3, cache4);
102 const newValue = fn(a1, a2, a3, a4);
103 cache4.set(a4, newValue);
104 return newValue;
105 }
106 let cache3 = cache2.get(a2);
107 if (!cache3) {
108 cache3 = new WeakMap();
109 cache2.set(a2, cache3);
110 const cache4 = new WeakMap();
111 cache3.set(a3, cache4);
112 const newValue = fn(a1, a2, a3, a4);
113 cache4.set(a4, newValue);
114 return newValue;
115 }
116 const cache4 = cache3.get(a3);
117 if (!cache4) {
118 const cache4 = new WeakMap();
119 cache3.set(a3, cache4);
120 const newValue = fn(a1, a2, a3, a4);
121 cache4.set(a4, newValue);
122 return newValue;
123 }
124 const cachedValue = cache4.get(a4);
125 if (cachedValue === undefined) {
126 const newValue = fn(a1, a2, a3, a4);
127 cache4.set(a4, newValue);
128 return newValue;
129 }
130 return cachedValue;
131 }
132 return memoized;
133}
134function memoize3(fn) {
135 let cache1;
136 function memoized(a1, a2, a3) {
137 if (!cache1) {
138 cache1 = new WeakMap();
139 const cache2 = new WeakMap();
140 cache1.set(a1, cache2);
141 const cache3 = new WeakMap();
142 cache2.set(a2, cache3);
143 const newValue = fn(a1, a2, a3);
144 cache3.set(a3, newValue);
145 return newValue;
146 }
147 let cache2 = cache1.get(a1);
148 if (!cache2) {
149 cache2 = new WeakMap();
150 cache1.set(a1, cache2);
151 const cache3 = new WeakMap();
152 cache2.set(a2, cache3);
153 const newValue = fn(a1, a2, a3);
154 cache3.set(a3, newValue);
155 return newValue;
156 }
157 let cache3 = cache2.get(a2);
158 if (!cache3) {
159 cache3 = new WeakMap();
160 cache2.set(a2, cache3);
161 const newValue = fn(a1, a2, a3);
162 cache3.set(a3, newValue);
163 return newValue;
164 }
165 const cachedValue = cache3.get(a3);
166 if (cachedValue === undefined) {
167 const newValue = fn(a1, a2, a3);
168 cache3.set(a3, newValue);
169 return newValue;
170 }
171 return cachedValue;
172 }
173 return memoized;
174}
175function memoize2(fn) {
176 let cache1;
177 function memoized(a1, a2) {
178 if (!cache1) {
179 cache1 = new WeakMap();
180 const cache2 = new WeakMap();
181 cache1.set(a1, cache2);
182 const newValue = fn(a1, a2);
183 cache2.set(a2, newValue);
184 return newValue;
185 }
186 let cache2 = cache1.get(a1);
187 if (!cache2) {
188 cache2 = new WeakMap();
189 cache1.set(a1, cache2);
190 const newValue = fn(a1, a2);
191 cache2.set(a2, newValue);
192 return newValue;
193 }
194 const cachedValue = cache2.get(a2);
195 if (cachedValue === undefined) {
196 const newValue = fn(a1, a2);
197 cache2.set(a2, newValue);
198 return newValue;
199 }
200 return cachedValue;
201 }
202 return memoized;
203}
204
205function getDocumentMetadata(document) {
206 const operations = [];
207 const fragments = [];
208 const fragmentNames = new Set();
209 for (let i = 0; i < document.definitions.length; i++) {
210 const def = document.definitions[i];
211 if (def.kind === graphql.Kind.FRAGMENT_DEFINITION) {
212 fragments.push(def);
213 fragmentNames.add(def.name.value);
214 }
215 else if (def.kind === graphql.Kind.OPERATION_DEFINITION) {
216 operations.push(def);
217 }
218 }
219 return {
220 operations,
221 fragments,
222 fragmentNames,
223 };
224}
225
226function prepareGatewayDocument(originalDocument, transformedSchema, returnType, infoSchema) {
227 const wrappedConcreteTypesDocument = wrapConcreteTypes(returnType, transformedSchema, originalDocument);
228 if (infoSchema == null) {
229 return wrappedConcreteTypesDocument;
230 }
231 const { possibleTypesMap, reversePossibleTypesMap, interfaceExtensionsMap, fieldNodesByType, fieldNodesByField, dynamicSelectionSetsByField, } = getSchemaMetaData(infoSchema, transformedSchema);
232 const { operations, fragments, fragmentNames } = getDocumentMetadata(wrappedConcreteTypesDocument);
233 const { expandedFragments, fragmentReplacements } = getExpandedFragments(fragments, fragmentNames, possibleTypesMap);
234 const typeInfo = new graphql.TypeInfo(transformedSchema);
235 const expandedDocument = {
236 kind: graphql.Kind.DOCUMENT,
237 definitions: [...operations, ...fragments, ...expandedFragments],
238 };
239 return graphql.visit(expandedDocument, graphql.visitWithTypeInfo(typeInfo, {
240 [graphql.Kind.SELECTION_SET]: node => visitSelectionSet(node, fragmentReplacements, transformedSchema, typeInfo, possibleTypesMap, reversePossibleTypesMap, interfaceExtensionsMap, fieldNodesByType, fieldNodesByField, dynamicSelectionSetsByField),
241 }),
242 // visitorKeys argument usage a la https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js
243 // empty keys cannot be removed only because of typescript errors
244 // will hopefully be fixed in future version of graphql-js to be optional
245 {
246 Name: [],
247 Document: ['definitions'],
248 OperationDefinition: ['selectionSet'],
249 VariableDefinition: [],
250 Variable: [],
251 SelectionSet: ['selections'],
252 Field: ['selectionSet'],
253 Argument: [],
254 FragmentSpread: [],
255 InlineFragment: ['selectionSet'],
256 FragmentDefinition: ['selectionSet'],
257 IntValue: [],
258 FloatValue: [],
259 StringValue: [],
260 BooleanValue: [],
261 NullValue: [],
262 EnumValue: [],
263 ListValue: [],
264 ObjectValue: [],
265 ObjectField: [],
266 Directive: [],
267 NamedType: [],
268 ListType: [],
269 NonNullType: [],
270 SchemaDefinition: [],
271 OperationTypeDefinition: [],
272 ScalarTypeDefinition: [],
273 ObjectTypeDefinition: [],
274 FieldDefinition: [],
275 InputValueDefinition: [],
276 InterfaceTypeDefinition: [],
277 UnionTypeDefinition: [],
278 EnumTypeDefinition: [],
279 EnumValueDefinition: [],
280 InputObjectTypeDefinition: [],
281 DirectiveDefinition: [],
282 SchemaExtension: [],
283 ScalarTypeExtension: [],
284 ObjectTypeExtension: [],
285 InterfaceTypeExtension: [],
286 UnionTypeExtension: [],
287 EnumTypeExtension: [],
288 InputObjectTypeExtension: [],
289 });
290}
291function visitSelectionSet(node, fragmentReplacements, schema, typeInfo, possibleTypesMap, reversePossibleTypesMap, interfaceExtensionsMap, fieldNodesByType, fieldNodesByField, dynamicSelectionSetsByField) {
292 var _a, _b;
293 const newSelections = new Set();
294 const maybeType = typeInfo.getParentType();
295 if (maybeType != null) {
296 const parentType = graphql.getNamedType(maybeType);
297 const parentTypeName = parentType.name;
298 const fieldNodes = fieldNodesByType[parentTypeName];
299 if (fieldNodes) {
300 for (const fieldNode of fieldNodes) {
301 newSelections.add(fieldNode);
302 }
303 }
304 const interfaceExtensions = interfaceExtensionsMap[parentType.name];
305 const interfaceExtensionFields = [];
306 for (const selection of node.selections) {
307 if (selection.kind === graphql.Kind.INLINE_FRAGMENT) {
308 if (selection.typeCondition != null) {
309 const possibleTypes = possibleTypesMap[selection.typeCondition.name.value];
310 if (possibleTypes == null) {
311 newSelections.add(selection);
312 continue;
313 }
314 for (const possibleTypeName of possibleTypes) {
315 const maybePossibleType = schema.getType(possibleTypeName);
316 if (maybePossibleType != null && utils.implementsAbstractType(schema, parentType, maybePossibleType)) {
317 newSelections.add(generateInlineFragment(possibleTypeName, selection.selectionSet));
318 }
319 }
320 }
321 }
322 else if (selection.kind === graphql.Kind.FRAGMENT_SPREAD) {
323 const fragmentName = selection.name.value;
324 if (!fragmentReplacements[fragmentName]) {
325 newSelections.add(selection);
326 continue;
327 }
328 for (const replacement of fragmentReplacements[fragmentName]) {
329 const typeName = replacement.typeName;
330 const maybeReplacementType = schema.getType(typeName);
331 if (maybeReplacementType != null && utils.implementsAbstractType(schema, parentType, maybeType)) {
332 newSelections.add({
333 kind: graphql.Kind.FRAGMENT_SPREAD,
334 name: {
335 kind: graphql.Kind.NAME,
336 value: replacement.fragmentName,
337 },
338 });
339 }
340 }
341 }
342 else {
343 const fieldName = selection.name.value;
344 const fieldNodes = (_a = fieldNodesByField[parentTypeName]) === null || _a === void 0 ? void 0 : _a[fieldName];
345 if (fieldNodes != null) {
346 for (const fieldNode of fieldNodes) {
347 newSelections.add(fieldNode);
348 }
349 }
350 const dynamicSelectionSets = (_b = dynamicSelectionSetsByField[parentTypeName]) === null || _b === void 0 ? void 0 : _b[fieldName];
351 if (dynamicSelectionSets != null) {
352 for (const selectionSetFn of dynamicSelectionSets) {
353 const selectionSet = selectionSetFn(selection);
354 if (selectionSet != null) {
355 for (const selection of selectionSet.selections) {
356 newSelections.add(selection);
357 }
358 }
359 }
360 }
361 if (interfaceExtensions === null || interfaceExtensions === void 0 ? void 0 : interfaceExtensions[fieldName]) {
362 interfaceExtensionFields.push(selection);
363 }
364 else {
365 newSelections.add(selection);
366 }
367 }
368 }
369 if (reversePossibleTypesMap[parentType.name]) {
370 newSelections.add({
371 kind: graphql.Kind.FIELD,
372 name: {
373 kind: graphql.Kind.NAME,
374 value: '__typename',
375 },
376 });
377 }
378 if (interfaceExtensionFields.length) {
379 const possibleTypes = possibleTypesMap[parentType.name];
380 if (possibleTypes != null) {
381 for (const possibleType of possibleTypes) {
382 newSelections.add(generateInlineFragment(possibleType, {
383 kind: graphql.Kind.SELECTION_SET,
384 selections: interfaceExtensionFields,
385 }));
386 }
387 }
388 }
389 return {
390 ...node,
391 selections: Array.from(newSelections),
392 };
393 }
394 return node;
395}
396function generateInlineFragment(typeName, selectionSet) {
397 return {
398 kind: graphql.Kind.INLINE_FRAGMENT,
399 typeCondition: {
400 kind: graphql.Kind.NAMED_TYPE,
401 name: {
402 kind: graphql.Kind.NAME,
403 value: typeName,
404 },
405 },
406 selectionSet,
407 };
408}
409const getSchemaMetaData = memoize2((sourceSchema, targetSchema) => {
410 var _a, _b, _c, _d, _e, _f, _g, _h, _j;
411 const typeMap = sourceSchema.getTypeMap();
412 const targetTypeMap = targetSchema.getTypeMap();
413 const possibleTypesMap = Object.create(null);
414 const interfaceExtensionsMap = Object.create(null);
415 for (const typeName in typeMap) {
416 const type = typeMap[typeName];
417 if (graphql.isAbstractType(type)) {
418 const targetType = targetTypeMap[typeName];
419 if (graphql.isInterfaceType(type) && graphql.isInterfaceType(targetType)) {
420 const targetTypeFields = targetType.getFields();
421 const sourceTypeFields = type.getFields();
422 const extensionFields = Object.create(null);
423 let isExtensionFieldsEmpty = true;
424 for (const fieldName in sourceTypeFields) {
425 if (!targetTypeFields[fieldName]) {
426 extensionFields[fieldName] = true;
427 isExtensionFieldsEmpty = false;
428 }
429 }
430 if (!isExtensionFieldsEmpty) {
431 interfaceExtensionsMap[typeName] = extensionFields;
432 }
433 }
434 if (interfaceExtensionsMap[typeName] || !graphql.isAbstractType(targetType)) {
435 const implementations = sourceSchema.getPossibleTypes(type);
436 possibleTypesMap[typeName] = [];
437 for (const impl of implementations) {
438 if (targetTypeMap[impl.name]) {
439 possibleTypesMap[typeName].push(impl.name);
440 }
441 }
442 }
443 }
444 }
445 return {
446 possibleTypesMap,
447 reversePossibleTypesMap: reversePossibleTypesMap(possibleTypesMap),
448 interfaceExtensionsMap,
449 fieldNodesByType: (_c = (_b = (_a = sourceSchema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo']) === null || _b === void 0 ? void 0 : _b.fieldNodesByType) !== null && _c !== void 0 ? _c : {},
450 fieldNodesByField: (_f = (_e = (_d = sourceSchema.extensions) === null || _d === void 0 ? void 0 : _d['stitchingInfo']) === null || _e === void 0 ? void 0 : _e.fieldNodesByField) !== null && _f !== void 0 ? _f : {},
451 dynamicSelectionSetsByField: (_j = (_h = (_g = sourceSchema.extensions) === null || _g === void 0 ? void 0 : _g['stitchingInfo']) === null || _h === void 0 ? void 0 : _h.dynamicSelectionSetsByField) !== null && _j !== void 0 ? _j : {},
452 };
453});
454function reversePossibleTypesMap(possibleTypesMap) {
455 const result = Object.create(null);
456 for (const typeName in possibleTypesMap) {
457 const toTypeNames = possibleTypesMap[typeName];
458 for (const toTypeName of toTypeNames) {
459 if (!result[toTypeName]) {
460 result[toTypeName] = [];
461 }
462 result[toTypeName].push(typeName);
463 }
464 }
465 return result;
466}
467function getExpandedFragments(fragments, fragmentNames, possibleTypesMap) {
468 let fragmentCounter = 0;
469 function generateFragmentName(typeName) {
470 let fragmentName;
471 do {
472 fragmentName = `_${typeName}_Fragment${fragmentCounter.toString()}`;
473 fragmentCounter++;
474 } while (fragmentNames.has(fragmentName));
475 return fragmentName;
476 }
477 const expandedFragments = [];
478 const fragmentReplacements = Object.create(null);
479 for (const fragment of fragments) {
480 const possibleTypes = possibleTypesMap[fragment.typeCondition.name.value];
481 if (possibleTypes != null) {
482 const fragmentName = fragment.name.value;
483 fragmentReplacements[fragmentName] = [];
484 for (const possibleTypeName of possibleTypes) {
485 const name = generateFragmentName(possibleTypeName);
486 fragmentNames.add(name);
487 expandedFragments.push({
488 kind: graphql.Kind.FRAGMENT_DEFINITION,
489 name: {
490 kind: graphql.Kind.NAME,
491 value: name,
492 },
493 typeCondition: {
494 kind: graphql.Kind.NAMED_TYPE,
495 name: {
496 kind: graphql.Kind.NAME,
497 value: possibleTypeName,
498 },
499 },
500 selectionSet: fragment.selectionSet,
501 });
502 fragmentReplacements[fragmentName].push({
503 fragmentName: name,
504 typeName: possibleTypeName,
505 });
506 }
507 }
508 }
509 return {
510 expandedFragments,
511 fragmentReplacements,
512 };
513}
514function wrapConcreteTypes(returnType, targetSchema, document) {
515 const namedType = graphql.getNamedType(returnType);
516 if (!graphql.isObjectType(namedType)) {
517 return document;
518 }
519 const rootTypeNames = utils.getRootTypeNames(targetSchema);
520 const typeInfo = new graphql.TypeInfo(targetSchema);
521 return graphql.visit(document, graphql.visitWithTypeInfo(typeInfo, {
522 [graphql.Kind.FRAGMENT_DEFINITION]: (node) => {
523 const typeName = node.typeCondition.name.value;
524 if (!rootTypeNames.has(typeName)) {
525 return false;
526 }
527 },
528 [graphql.Kind.FIELD]: (node) => {
529 const type = typeInfo.getType();
530 if (type != null && graphql.isAbstractType(graphql.getNamedType(type))) {
531 return {
532 ...node,
533 selectionSet: {
534 kind: graphql.Kind.SELECTION_SET,
535 selections: [
536 {
537 kind: graphql.Kind.INLINE_FRAGMENT,
538 typeCondition: {
539 kind: graphql.Kind.NAMED_TYPE,
540 name: {
541 kind: graphql.Kind.NAME,
542 value: namedType.name,
543 },
544 },
545 selectionSet: node.selectionSet,
546 },
547 ],
548 },
549 };
550 }
551 },
552 }),
553 // visitorKeys argument usage a la https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js
554 // empty keys cannot be removed only because of typescript errors
555 // will hopefully be fixed in future version of graphql-js to be optional
556 {
557 Name: [],
558 Document: ['definitions'],
559 OperationDefinition: ['selectionSet'],
560 VariableDefinition: [],
561 Variable: [],
562 SelectionSet: ['selections'],
563 Field: [],
564 Argument: [],
565 FragmentSpread: [],
566 InlineFragment: ['selectionSet'],
567 FragmentDefinition: ['selectionSet'],
568 IntValue: [],
569 FloatValue: [],
570 StringValue: [],
571 BooleanValue: [],
572 NullValue: [],
573 EnumValue: [],
574 ListValue: [],
575 ObjectValue: [],
576 ObjectField: [],
577 Directive: [],
578 NamedType: [],
579 ListType: [],
580 NonNullType: [],
581 SchemaDefinition: [],
582 OperationTypeDefinition: [],
583 ScalarTypeDefinition: [],
584 ObjectTypeDefinition: [],
585 FieldDefinition: [],
586 InputValueDefinition: [],
587 InterfaceTypeDefinition: [],
588 UnionTypeDefinition: [],
589 EnumTypeDefinition: [],
590 EnumValueDefinition: [],
591 InputObjectTypeDefinition: [],
592 DirectiveDefinition: [],
593 SchemaExtension: [],
594 ScalarTypeExtension: [],
595 ObjectTypeExtension: [],
596 InterfaceTypeExtension: [],
597 UnionTypeExtension: [],
598 EnumTypeExtension: [],
599 InputObjectTypeExtension: [],
600 });
601}
602
603function finalizeGatewayDocument(targetSchema, fragments, operations) {
604 var _a;
605 let usedVariables = [];
606 let usedFragments = [];
607 const newOperations = [];
608 let newFragments = [];
609 const validFragments = [];
610 const validFragmentsWithType = Object.create(null);
611 for (const fragment of fragments) {
612 const typeName = fragment.typeCondition.name.value;
613 const type = targetSchema.getType(typeName);
614 if (type != null) {
615 validFragments.push(fragment);
616 validFragmentsWithType[fragment.name.value] = type;
617 }
618 }
619 let fragmentSet = Object.create(null);
620 for (const operation of operations) {
621 const type = utils.getDefinedRootType(targetSchema, operation.operation);
622 const { selectionSet, usedFragments: operationUsedFragments, usedVariables: operationUsedVariables, } = finalizeSelectionSet(targetSchema, type, validFragmentsWithType, operation.selectionSet);
623 usedFragments = union(usedFragments, operationUsedFragments);
624 const { usedVariables: collectedUsedVariables, newFragments: collectedNewFragments, fragmentSet: collectedFragmentSet, } = collectFragmentVariables(targetSchema, fragmentSet, validFragments, validFragmentsWithType, usedFragments);
625 const operationOrFragmentVariables = union(operationUsedVariables, collectedUsedVariables);
626 usedVariables = union(usedVariables, operationOrFragmentVariables);
627 newFragments = collectedNewFragments;
628 fragmentSet = collectedFragmentSet;
629 const variableDefinitions = ((_a = operation.variableDefinitions) !== null && _a !== void 0 ? _a : []).filter((variable) => operationOrFragmentVariables.indexOf(variable.variable.name.value) !== -1);
630 newOperations.push({
631 kind: graphql.Kind.OPERATION_DEFINITION,
632 operation: operation.operation,
633 name: operation.name,
634 directives: operation.directives,
635 variableDefinitions,
636 selectionSet,
637 });
638 }
639 return {
640 usedVariables,
641 newDocument: {
642 kind: graphql.Kind.DOCUMENT,
643 definitions: [...newOperations, ...newFragments],
644 },
645 };
646}
647function finalizeGatewayRequest(originalRequest, delegationContext) {
648 let { document, variables } = originalRequest;
649 let { operations, fragments } = getDocumentMetadata(document);
650 const { targetSchema, args } = delegationContext;
651 if (args) {
652 const requestWithNewVariables = addVariablesToRootFields(targetSchema, operations, args);
653 operations = requestWithNewVariables.newOperations;
654 variables = Object.assign({}, variables !== null && variables !== void 0 ? variables : {}, requestWithNewVariables.newVariables);
655 }
656 const { usedVariables, newDocument } = finalizeGatewayDocument(targetSchema, fragments, operations);
657 const newVariables = {};
658 if (variables != null) {
659 for (const variableName of usedVariables) {
660 const variableValue = variables[variableName];
661 if (variableValue !== undefined) {
662 newVariables[variableName] = variableValue;
663 }
664 }
665 }
666 return {
667 ...originalRequest,
668 document: newDocument,
669 variables: newVariables,
670 };
671}
672function addVariablesToRootFields(targetSchema, operations, args) {
673 const newVariables = Object.create(null);
674 const newOperations = operations.map((operation) => {
675 var _a, _b;
676 const variableDefinitionMap = ((_a = operation.variableDefinitions) !== null && _a !== void 0 ? _a : []).reduce((prev, def) => ({
677 ...prev,
678 [def.variable.name.value]: def,
679 }), {});
680 const type = utils.getDefinedRootType(targetSchema, operation.operation);
681 const newSelectionSet = [];
682 for (const selection of operation.selectionSet.selections) {
683 if (selection.kind === graphql.Kind.FIELD) {
684 const argumentNodes = (_b = selection.arguments) !== null && _b !== void 0 ? _b : [];
685 const argumentNodeMap = argumentNodes.reduce((prev, argument) => ({
686 ...prev,
687 [argument.name.value]: argument,
688 }), {});
689 const targetField = type.getFields()[selection.name.value];
690 // excludes __typename
691 if (targetField != null) {
692 updateArguments(targetField, argumentNodeMap, variableDefinitionMap, newVariables, args);
693 }
694 newSelectionSet.push({
695 ...selection,
696 arguments: Object.values(argumentNodeMap),
697 });
698 }
699 else {
700 newSelectionSet.push(selection);
701 }
702 }
703 return {
704 ...operation,
705 variableDefinitions: Object.values(variableDefinitionMap),
706 selectionSet: {
707 kind: graphql.Kind.SELECTION_SET,
708 selections: newSelectionSet,
709 },
710 };
711 });
712 return {
713 newOperations,
714 newVariables,
715 };
716}
717function updateArguments(targetField, argumentNodeMap, variableDefinitionMap, variableValues, newArgs) {
718 const generateVariableName = utils.createVariableNameGenerator(variableDefinitionMap);
719 for (const argument of targetField.args) {
720 const argName = argument.name;
721 const argType = argument.type;
722 if (argName in newArgs) {
723 utils.updateArgument(argumentNodeMap, variableDefinitionMap, variableValues, argName, generateVariableName(argName), argType, utils.serializeInputValue(argType, newArgs[argName]));
724 }
725 }
726}
727function collectFragmentVariables(targetSchema, fragmentSet, validFragments, validFragmentsWithType, usedFragments) {
728 let remainingFragments = usedFragments.slice();
729 let usedVariables = [];
730 const newFragments = [];
731 while (remainingFragments.length !== 0) {
732 const nextFragmentName = remainingFragments.pop();
733 const fragment = validFragments.find(fr => fr.name.value === nextFragmentName);
734 if (fragment != null) {
735 const name = nextFragmentName;
736 const typeName = fragment.typeCondition.name.value;
737 const type = targetSchema.getType(typeName);
738 if (type == null) {
739 throw new Error(`Fragment reference type "${typeName}", but the type is not contained within the target schema.`);
740 }
741 const { selectionSet, usedFragments: fragmentUsedFragments, usedVariables: fragmentUsedVariables, } = finalizeSelectionSet(targetSchema, type, validFragmentsWithType, fragment.selectionSet);
742 remainingFragments = union(remainingFragments, fragmentUsedFragments);
743 usedVariables = union(usedVariables, fragmentUsedVariables);
744 if (name && !(name in fragmentSet)) {
745 fragmentSet[name] = true;
746 newFragments.push({
747 kind: graphql.Kind.FRAGMENT_DEFINITION,
748 name: {
749 kind: graphql.Kind.NAME,
750 value: name,
751 },
752 typeCondition: fragment.typeCondition,
753 selectionSet,
754 });
755 }
756 }
757 }
758 return {
759 usedVariables,
760 newFragments,
761 fragmentSet,
762 };
763}
764const filteredSelectionSetVisitorKeys = {
765 SelectionSet: ['selections'],
766 Field: ['selectionSet'],
767 InlineFragment: ['selectionSet'],
768 FragmentDefinition: ['selectionSet'],
769};
770const variablesVisitorKeys = {
771 SelectionSet: ['selections'],
772 Field: ['arguments', 'directives', 'selectionSet'],
773 Argument: ['value'],
774 InlineFragment: ['directives', 'selectionSet'],
775 FragmentDefinition: ['directives', 'selectionSet'],
776 ObjectValue: ['fields'],
777 ObjectField: ['name', 'value'],
778 Directive: ['arguments'],
779};
780function finalizeSelectionSet(schema, type, validFragments, selectionSet) {
781 const usedFragments = [];
782 const usedVariables = [];
783 const typeInfo = new graphql.TypeInfo(schema, undefined, type);
784 const filteredSelectionSet = graphql.visit(selectionSet, graphql.visitWithTypeInfo(typeInfo, {
785 [graphql.Kind.FIELD]: {
786 enter: node => {
787 const parentType = typeInfo.getParentType();
788 if (graphql.isObjectType(parentType) || graphql.isInterfaceType(parentType)) {
789 const fields = parentType.getFields();
790 const field = node.name.value === '__typename' ? graphql.TypeNameMetaFieldDef : fields[node.name.value];
791 if (!field) {
792 return null;
793 }
794 const args = field.args != null ? field.args : [];
795 const argsMap = Object.create(null);
796 for (const arg of args) {
797 argsMap[arg.name] = arg;
798 }
799 if (node.arguments != null) {
800 const newArgs = [];
801 for (const arg of node.arguments) {
802 if (arg.name.value in argsMap) {
803 newArgs.push(arg);
804 }
805 }
806 if (newArgs.length !== node.arguments.length) {
807 return {
808 ...node,
809 arguments: newArgs,
810 };
811 }
812 }
813 }
814 },
815 leave: node => {
816 const type = typeInfo.getType();
817 if (type == null) {
818 throw new Error(`No type was found for field node ${node}.`);
819 }
820 const namedType = graphql.getNamedType(type);
821 if (!schema.getType(namedType.name) == null) {
822 return null;
823 }
824 if (graphql.isObjectType(namedType) || graphql.isInterfaceType(namedType)) {
825 const selections = node.selectionSet != null ? node.selectionSet.selections : null;
826 if (selections == null || selections.length === 0) {
827 return null;
828 }
829 }
830 },
831 },
832 [graphql.Kind.FRAGMENT_SPREAD]: {
833 enter: node => {
834 if (!(node.name.value in validFragments)) {
835 return null;
836 }
837 const parentType = typeInfo.getParentType();
838 const innerType = validFragments[node.name.value];
839 if (!utils.implementsAbstractType(schema, parentType, innerType)) {
840 return null;
841 }
842 usedFragments.push(node.name.value);
843 },
844 },
845 [graphql.Kind.INLINE_FRAGMENT]: {
846 enter: node => {
847 if (node.typeCondition != null) {
848 const parentType = typeInfo.getParentType();
849 const innerType = schema.getType(node.typeCondition.name.value);
850 if (!utils.implementsAbstractType(schema, parentType, innerType)) {
851 return null;
852 }
853 }
854 },
855 },
856 [graphql.Kind.SELECTION_SET]: {
857 leave: node => {
858 const parentType = typeInfo.getParentType();
859 if (parentType != null && graphql.isAbstractType(parentType)) {
860 const selections = node.selections.concat([
861 {
862 kind: graphql.Kind.FIELD,
863 name: {
864 kind: graphql.Kind.NAME,
865 value: '__typename',
866 },
867 },
868 ]);
869 return {
870 ...node,
871 selections,
872 };
873 }
874 },
875 },
876 }),
877 // visitorKeys argument usage a la https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js
878 // empty keys cannot be removed only because of typescript errors
879 // will hopefully be fixed in future version of graphql-js to be optional
880 filteredSelectionSetVisitorKeys);
881 graphql.visit(filteredSelectionSet, {
882 [graphql.Kind.VARIABLE]: variableNode => {
883 usedVariables.push(variableNode.name.value);
884 },
885 },
886 // visitorKeys argument usage a la https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js
887 // empty keys cannot be removed only because of typescript errors
888 // will hopefully be fixed in future version of graphql-js to be optional
889 variablesVisitorKeys);
890 return {
891 selectionSet: filteredSelectionSet,
892 usedFragments,
893 usedVariables,
894 };
895}
896function union(...arrays) {
897 const cache = Object.create(null);
898 const result = [];
899 for (const array of arrays) {
900 for (const item of array) {
901 if (!(item in cache)) {
902 cache[item] = true;
903 result.push(item);
904 }
905 }
906 }
907 return result;
908}
909
910const UNPATHED_ERRORS_SYMBOL = Symbol('subschemaErrors');
911const OBJECT_SUBSCHEMA_SYMBOL = Symbol('initialSubschema');
912const FIELD_SUBSCHEMA_MAP_SYMBOL = Symbol('subschemaMap');
913
914const sortSubschemasByProxiability = memoize4(function sortSubschemasByProxiability(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, targetSubschemas, fieldNodes) {
915 // 1. calculate if possible to delegate to given subschema
916 const proxiableSubschemas = [];
917 const nonProxiableSubschemas = [];
918 for (const t of targetSubschemas) {
919 const selectionSet = mergedTypeInfo.selectionSets.get(t);
920 const fieldSelectionSets = mergedTypeInfo.fieldSelectionSets.get(t);
921 if (selectionSet != null &&
922 !subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, selectionSet)) {
923 nonProxiableSubschemas.push(t);
924 }
925 else {
926 if (fieldSelectionSets == null ||
927 fieldNodes.every(fieldNode => {
928 const fieldName = fieldNode.name.value;
929 const fieldSelectionSet = fieldSelectionSets[fieldName];
930 return (fieldSelectionSet == null ||
931 subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, fieldSelectionSet));
932 })) {
933 proxiableSubschemas.push(t);
934 }
935 else {
936 nonProxiableSubschemas.push(t);
937 }
938 }
939 }
940 return {
941 proxiableSubschemas,
942 nonProxiableSubschemas,
943 };
944});
945const buildDelegationPlan = memoize3(function buildDelegationPlan(mergedTypeInfo, fieldNodes, proxiableSubschemas) {
946 var _a;
947 const { uniqueFields, nonUniqueFields } = mergedTypeInfo;
948 const unproxiableFieldNodes = [];
949 // 2. for each selection:
950 const delegationMap = new Map();
951 for (const fieldNode of fieldNodes) {
952 if (fieldNode.name.value === '__typename') {
953 continue;
954 }
955 // 2a. use uniqueFields map to assign fields to subschema if one of possible subschemas
956 const uniqueSubschema = uniqueFields[fieldNode.name.value];
957 if (uniqueSubschema != null) {
958 if (!proxiableSubschemas.includes(uniqueSubschema)) {
959 unproxiableFieldNodes.push(fieldNode);
960 continue;
961 }
962 const existingSubschema = (_a = delegationMap.get(uniqueSubschema)) === null || _a === void 0 ? void 0 : _a.selections;
963 if (existingSubschema != null) {
964 existingSubschema.push(fieldNode);
965 }
966 else {
967 delegationMap.set(uniqueSubschema, {
968 kind: graphql.Kind.SELECTION_SET,
969 selections: [fieldNode],
970 });
971 }
972 continue;
973 }
974 // 2b. use nonUniqueFields to assign to a possible subschema,
975 // preferring one of the subschemas already targets of delegation
976 let nonUniqueSubschemas = nonUniqueFields[fieldNode.name.value];
977 if (nonUniqueSubschemas == null) {
978 unproxiableFieldNodes.push(fieldNode);
979 continue;
980 }
981 nonUniqueSubschemas = nonUniqueSubschemas.filter(s => proxiableSubschemas.includes(s));
982 if (!nonUniqueSubschemas.length) {
983 unproxiableFieldNodes.push(fieldNode);
984 continue;
985 }
986 const existingSubschema = nonUniqueSubschemas.find(s => delegationMap.has(s));
987 if (existingSubschema != null) {
988 // It is okay we previously explicitly check whether the map has the element.
989 delegationMap.get(existingSubschema).selections.push(fieldNode);
990 }
991 else {
992 delegationMap.set(nonUniqueSubschemas[0], {
993 kind: graphql.Kind.SELECTION_SET,
994 selections: [fieldNode],
995 });
996 }
997 }
998 return {
999 delegationMap,
1000 unproxiableFieldNodes,
1001 };
1002});
1003const combineSubschemas = memoize2(function combineSubschemas(subschemaOrSubschemas, additionalSubschemas) {
1004 return Array.isArray(subschemaOrSubschemas)
1005 ? subschemaOrSubschemas.concat(additionalSubschemas)
1006 : [subschemaOrSubschemas].concat(additionalSubschemas);
1007});
1008function isExternalObject(data) {
1009 return data[UNPATHED_ERRORS_SYMBOL] !== undefined;
1010}
1011function annotateExternalObject(object, errors, subschema) {
1012 Object.defineProperties(object, {
1013 [OBJECT_SUBSCHEMA_SYMBOL]: { value: subschema },
1014 [FIELD_SUBSCHEMA_MAP_SYMBOL]: { value: Object.create(null) },
1015 [UNPATHED_ERRORS_SYMBOL]: { value: errors },
1016 });
1017 return object;
1018}
1019function getSubschema(object, responseKey) {
1020 var _a;
1021 return (_a = object[FIELD_SUBSCHEMA_MAP_SYMBOL][responseKey]) !== null && _a !== void 0 ? _a : object[OBJECT_SUBSCHEMA_SYMBOL];
1022}
1023function getUnpathedErrors(object) {
1024 return object[UNPATHED_ERRORS_SYMBOL];
1025}
1026async function mergeFields(mergedTypeInfo, typeName, object, fieldNodes, sourceSubschemaOrSourceSubschemas, targetSubschemas, context, info) {
1027 var _a;
1028 if (!fieldNodes.length) {
1029 return object;
1030 }
1031 const { proxiableSubschemas, nonProxiableSubschemas } = sortSubschemasByProxiability(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, targetSubschemas, fieldNodes);
1032 const { delegationMap, unproxiableFieldNodes } = buildDelegationPlan(mergedTypeInfo, fieldNodes, proxiableSubschemas);
1033 if (!delegationMap.size) {
1034 return object;
1035 }
1036 const combinedErrors = object[UNPATHED_ERRORS_SYMBOL] || [];
1037 const path = graphql.responsePathAsArray(info.path);
1038 const newFieldSubschemaMap = (_a = object[FIELD_SUBSCHEMA_MAP_SYMBOL]) !== null && _a !== void 0 ? _a : Object.create(null);
1039 const type = info.schema.getType(object.__typename);
1040 const results = await Promise.all([...delegationMap.entries()].map(async ([s, selectionSet]) => {
1041 var _a;
1042 const resolver = mergedTypeInfo.resolvers.get(s);
1043 if (resolver) {
1044 let source;
1045 try {
1046 source = await resolver(object, context, info, s, selectionSet);
1047 }
1048 catch (error) {
1049 source = error;
1050 }
1051 if (source instanceof Error || source === null) {
1052 const fieldNodes = execute_js.collectFields({
1053 schema: info.schema,
1054 variableValues: {},
1055 fragments: {},
1056 }, type, selectionSet, Object.create(null), Object.create(null));
1057 const nullResult = {};
1058 for (const responseKey in fieldNodes) {
1059 const combinedPath = [...path, responseKey];
1060 if (source instanceof graphql.GraphQLError) {
1061 nullResult[responseKey] = utils.relocatedError(source, combinedPath);
1062 }
1063 else if (source instanceof Error) {
1064 nullResult[responseKey] = graphql.locatedError(source, fieldNodes[responseKey], combinedPath);
1065 }
1066 else {
1067 nullResult[responseKey] = null;
1068 }
1069 }
1070 source = nullResult;
1071 }
1072 else {
1073 if (source[UNPATHED_ERRORS_SYMBOL]) {
1074 combinedErrors.push(...source[UNPATHED_ERRORS_SYMBOL]);
1075 }
1076 }
1077 const objectSubschema = source[OBJECT_SUBSCHEMA_SYMBOL];
1078 const fieldSubschemaMap = source[FIELD_SUBSCHEMA_MAP_SYMBOL];
1079 for (const responseKey in source) {
1080 newFieldSubschemaMap[responseKey] = (_a = fieldSubschemaMap === null || fieldSubschemaMap === void 0 ? void 0 : fieldSubschemaMap[responseKey]) !== null && _a !== void 0 ? _a : objectSubschema;
1081 }
1082 return source;
1083 }
1084 }));
1085 const combinedResult = Object.assign({}, object, ...results);
1086 combinedResult[FIELD_SUBSCHEMA_MAP_SYMBOL] = newFieldSubschemaMap;
1087 combinedResult[OBJECT_SUBSCHEMA_SYMBOL] = object[OBJECT_SUBSCHEMA_SYMBOL];
1088 combinedResult[UNPATHED_ERRORS_SYMBOL] = combinedErrors;
1089 return mergeFields(mergedTypeInfo, typeName, combinedResult, unproxiableFieldNodes, combineSubschemas(sourceSubschemaOrSourceSubschemas, proxiableSubschemas), nonProxiableSubschemas, context, info);
1090}
1091const subschemaTypesContainSelectionSet = memoize3(function subschemaTypesContainSelectionSetMemoized(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, selectionSet) {
1092 if (Array.isArray(sourceSubschemaOrSourceSubschemas)) {
1093 return typesContainSelectionSet(sourceSubschemaOrSourceSubschemas.map(sourceSubschema => sourceSubschema.transformedSchema.getType(mergedTypeInfo.typeName)), selectionSet);
1094 }
1095 return typesContainSelectionSet([sourceSubschemaOrSourceSubschemas.transformedSchema.getType(mergedTypeInfo.typeName)], selectionSet);
1096});
1097function typesContainSelectionSet(types, selectionSet) {
1098 var _a;
1099 const fieldMaps = types.map(type => type.getFields());
1100 for (const selection of selectionSet.selections) {
1101 if (selection.kind === graphql.Kind.FIELD) {
1102 const fields = fieldMaps.map(fieldMap => fieldMap[selection.name.value]).filter(field => field != null);
1103 if (!fields.length) {
1104 return false;
1105 }
1106 if (selection.selectionSet != null) {
1107 return typesContainSelectionSet(fields.map(field => graphql.getNamedType(field.type)), selection.selectionSet);
1108 }
1109 }
1110 else if (selection.kind === graphql.Kind.INLINE_FRAGMENT && ((_a = selection.typeCondition) === null || _a === void 0 ? void 0 : _a.name.value) === types[0].name) {
1111 return typesContainSelectionSet(types, selection.selectionSet);
1112 }
1113 }
1114 return true;
1115}
1116
1117function isSubschemaConfig(value) {
1118 return Boolean(value === null || value === void 0 ? void 0 : value.schema);
1119}
1120function cloneSubschemaConfig(subschemaConfig) {
1121 var _a, _b;
1122 const newSubschemaConfig = {
1123 ...subschemaConfig,
1124 transforms: subschemaConfig.transforms != null ? [...subschemaConfig.transforms] : undefined,
1125 };
1126 if (newSubschemaConfig.merge != null) {
1127 newSubschemaConfig.merge = { ...subschemaConfig.merge };
1128 for (const typeName in newSubschemaConfig.merge) {
1129 const mergedTypeConfig = (newSubschemaConfig.merge[typeName] = { ...((_b = (_a = subschemaConfig.merge) === null || _a === void 0 ? void 0 : _a[typeName]) !== null && _b !== void 0 ? _b : {}) });
1130 if (mergedTypeConfig.entryPoints != null) {
1131 mergedTypeConfig.entryPoints = mergedTypeConfig.entryPoints.map(entryPoint => ({ ...entryPoint }));
1132 }
1133 if (mergedTypeConfig.fields != null) {
1134 const fields = (mergedTypeConfig.fields = { ...mergedTypeConfig.fields });
1135 for (const fieldName in fields) {
1136 fields[fieldName] = { ...fields[fieldName] };
1137 }
1138 }
1139 }
1140 }
1141 return newSubschemaConfig;
1142}
1143
1144function collectSubFields(info, typeName) {
1145 let subFieldNodes = Object.create(null);
1146 const visitedFragmentNames = Object.create(null);
1147 const type = info.schema.getType(typeName);
1148 const partialExecutionContext = {
1149 schema: info.schema,
1150 variableValues: info.variableValues,
1151 fragments: info.fragments,
1152 };
1153 for (const fieldNode of info.fieldNodes) {
1154 if (fieldNode.selectionSet) {
1155 subFieldNodes = execute_js.collectFields(partialExecutionContext, type, fieldNode.selectionSet, subFieldNodes, visitedFragmentNames);
1156 }
1157 }
1158 return subFieldNodes;
1159}
1160const getFieldsNotInSubschema = memoizeInfoAnd2Objects(function getFieldsNotInSubschemaMemoized(info, subschema, mergedTypeInfo) {
1161 var _a, _b;
1162 const typeMap = isSubschemaConfig(subschema) ? mergedTypeInfo.typeMaps.get(subschema) : subschema.getTypeMap();
1163 if (!typeMap) {
1164 return [];
1165 }
1166 const typeName = mergedTypeInfo.typeName;
1167 const fields = typeMap[typeName].getFields();
1168 const subFieldNodes = collectSubFields(info, typeName);
1169 // TODO: Verify whether it is safe that extensions always exists.
1170 const stitchingInfo = (_a = info.schema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
1171 const fieldNodesByField = stitchingInfo === null || stitchingInfo === void 0 ? void 0 : stitchingInfo.fieldNodesByField;
1172 const fieldsNotInSchema = new Set();
1173 for (const responseKey in subFieldNodes) {
1174 const subFieldNodesForResponseKey = subFieldNodes[responseKey];
1175 const fieldName = subFieldNodesForResponseKey[0].name.value;
1176 if (!fields[fieldName]) {
1177 for (const subFieldNodeForResponseKey of subFieldNodesForResponseKey) {
1178 fieldsNotInSchema.add(subFieldNodeForResponseKey);
1179 }
1180 }
1181 const fieldNodesForField = (_b = fieldNodesByField === null || fieldNodesByField === void 0 ? void 0 : fieldNodesByField[typeName]) === null || _b === void 0 ? void 0 : _b[fieldName];
1182 if (fieldNodesForField) {
1183 for (const fieldNode of fieldNodesForField) {
1184 if (!fields[fieldNode.name.value]) {
1185 fieldsNotInSchema.add(fieldNode);
1186 }
1187 }
1188 }
1189 }
1190 return Array.from(fieldsNotInSchema);
1191});
1192
1193function resolveExternalValue(result, unpathedErrors, subschema, context, info, returnType = getReturnType(info), skipTypeMerging) {
1194 const type = graphql.getNullableType(returnType);
1195 if (result instanceof Error) {
1196 return result;
1197 }
1198 if (result == null) {
1199 return reportUnpathedErrorsViaNull(unpathedErrors);
1200 }
1201 if ('parseValue' in type) {
1202 return type.parseValue(result);
1203 }
1204 else if (graphql.isCompositeType(type)) {
1205 return resolveExternalObject(type, result, unpathedErrors, subschema, context, info, skipTypeMerging);
1206 }
1207 else if (graphql.isListType(type)) {
1208 return resolveExternalList(type, result, unpathedErrors, subschema, context, info, skipTypeMerging);
1209 }
1210}
1211function resolveExternalObject(type, object, unpathedErrors, subschema, context, info, skipTypeMerging) {
1212 var _a;
1213 // if we have already resolved this object, for example, when the identical object appears twice
1214 // in a list, see https://github.com/ardatan/graphql-tools/issues/2304
1215 if (isExternalObject(object)) {
1216 return object;
1217 }
1218 annotateExternalObject(object, unpathedErrors, subschema);
1219 if (skipTypeMerging || info == null) {
1220 return object;
1221 }
1222 const stitchingInfo = (_a = info.schema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
1223 if (stitchingInfo == null) {
1224 return object;
1225 }
1226 let typeName;
1227 if (graphql.isAbstractType(type)) {
1228 const resolvedType = info.schema.getType(object.__typename);
1229 if (resolvedType == null) {
1230 throw new Error(`Unable to resolve type '${object.__typename}'. Did you forget to include a transform that renames types? Did you delegate to the original subschema rather that the subschema config object containing the transform?`);
1231 }
1232 typeName = resolvedType.name;
1233 }
1234 else {
1235 typeName = type.name;
1236 }
1237 const mergedTypeInfo = stitchingInfo.mergedTypes[typeName];
1238 let targetSubschemas;
1239 // Within the stitching context, delegation to a stitched GraphQLSchema or SubschemaConfig
1240 // will be redirected to the appropriate Subschema object, from which merge targets can be queried.
1241 if (mergedTypeInfo != null) {
1242 targetSubschemas = mergedTypeInfo.targetSubschemas.get(subschema);
1243 }
1244 // If there are no merge targets from the subschema, return.
1245 if (!targetSubschemas) {
1246 return object;
1247 }
1248 const fieldNodes = getFieldsNotInSubschema(info, subschema, mergedTypeInfo);
1249 return mergeFields(mergedTypeInfo, typeName, object, fieldNodes, subschema, targetSubschemas, context, info);
1250}
1251function resolveExternalList(type, list, unpathedErrors, subschema, context, info, skipTypeMerging) {
1252 return list.map(listMember => resolveExternalListMember(graphql.getNullableType(type.ofType), listMember, unpathedErrors, subschema, context, info, skipTypeMerging));
1253}
1254function resolveExternalListMember(type, listMember, unpathedErrors, subschema, context, info, skipTypeMerging) {
1255 if (listMember instanceof Error) {
1256 return listMember;
1257 }
1258 if (listMember == null) {
1259 return reportUnpathedErrorsViaNull(unpathedErrors);
1260 }
1261 if (graphql.isLeafType(type)) {
1262 return type.parseValue(listMember);
1263 }
1264 else if (graphql.isCompositeType(type)) {
1265 return resolveExternalObject(type, listMember, unpathedErrors, subschema, context, info, skipTypeMerging);
1266 }
1267 else if (graphql.isListType(type)) {
1268 return resolveExternalList(type, listMember, unpathedErrors, subschema, context, info, skipTypeMerging);
1269 }
1270}
1271const reportedErrors = new WeakMap();
1272function reportUnpathedErrorsViaNull(unpathedErrors) {
1273 if (unpathedErrors.length) {
1274 const unreportedErrors = [];
1275 for (const error of unpathedErrors) {
1276 if (!reportedErrors.has(error)) {
1277 unreportedErrors.push(error);
1278 reportedErrors.set(error, true);
1279 }
1280 }
1281 if (unreportedErrors.length) {
1282 if (unreportedErrors.length === 1) {
1283 return unreportedErrors[0];
1284 }
1285 const combinedError = new utils.AggregateError(unreportedErrors);
1286 // We cast path as any for GraphQL.js 14 compat
1287 // locatedError path argument must be defined, but it is just forwarded to a constructor that allows a undefined value
1288 // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/locatedError.js#L25
1289 // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/GraphQLError.js#L19
1290 return graphql.locatedError(combinedError, undefined, unreportedErrors[0].path);
1291 }
1292 }
1293 return null;
1294}
1295function getReturnType(info) {
1296 if (info == null) {
1297 throw new Error(`Return type cannot be inferred without a source schema.`);
1298 }
1299 return info.returnType;
1300}
1301
1302function checkResultAndHandleErrors(result, delegationContext) {
1303 const { context, info, fieldName: responseKey = getResponseKey(info), subschema, returnType = getReturnType$1(info), skipTypeMerging, onLocatedError, } = delegationContext;
1304 const { data, unpathedErrors } = mergeDataAndErrors(result.data == null ? undefined : result.data[responseKey], result.errors == null ? [] : result.errors, info != null && info.path ? graphql.responsePathAsArray(info.path) : undefined, onLocatedError);
1305 return resolveExternalValue(data, unpathedErrors, subschema, context, info, returnType, skipTypeMerging);
1306}
1307function mergeDataAndErrors(data, errors, path, onLocatedError, index = 1) {
1308 var _a;
1309 if (data == null) {
1310 if (!errors.length) {
1311 return { data: null, unpathedErrors: [] };
1312 }
1313 if (errors.length === 1) {
1314 const error = onLocatedError ? onLocatedError(errors[0]) : errors[0];
1315 const newPath = path === undefined ? error.path : error.path === undefined ? path : path.concat(error.path.slice(1));
1316 return { data: utils.relocatedError(errors[0], newPath), unpathedErrors: [] };
1317 }
1318 // We cast path as any for GraphQL.js 14 compat
1319 // locatedError path argument must be defined, but it is just forwarded to a constructor that allows a undefined value
1320 // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/locatedError.js#L25
1321 // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/GraphQLError.js#L19
1322 const newError = graphql.locatedError(new utils.AggregateError(errors), undefined, path);
1323 return { data: newError, unpathedErrors: [] };
1324 }
1325 if (!errors.length) {
1326 return { data, unpathedErrors: [] };
1327 }
1328 const unpathedErrors = [];
1329 const errorMap = new Map();
1330 for (const error of errors) {
1331 const pathSegment = (_a = error.path) === null || _a === void 0 ? void 0 : _a[index];
1332 if (pathSegment != null) {
1333 let pathSegmentErrors = errorMap.get(pathSegment);
1334 if (pathSegmentErrors === undefined) {
1335 pathSegmentErrors = [error];
1336 errorMap.set(pathSegment, pathSegmentErrors);
1337 }
1338 else {
1339 pathSegmentErrors.push(error);
1340 }
1341 }
1342 else {
1343 unpathedErrors.push(error);
1344 }
1345 }
1346 for (const [pathSegment, pathSegmentErrors] of errorMap) {
1347 if (data[pathSegment] !== undefined) {
1348 const { data: newData, unpathedErrors: newErrors } = mergeDataAndErrors(data[pathSegment], pathSegmentErrors, path, onLocatedError, index + 1);
1349 data[pathSegment] = newData;
1350 unpathedErrors.push(...newErrors);
1351 }
1352 else {
1353 unpathedErrors.push(...pathSegmentErrors);
1354 }
1355 }
1356 return { data, unpathedErrors };
1357}
1358function getResponseKey(info) {
1359 if (info == null) {
1360 throw new Error(`Data cannot be extracted from result without an explicit key or source schema.`);
1361 }
1362 return utils.getResponseKeyFromInfo(info);
1363}
1364function getReturnType$1(info) {
1365 if (info == null) {
1366 throw new Error(`Return type cannot be inferred without a source schema.`);
1367 }
1368 return info.returnType;
1369}
1370
1371class Transformer {
1372 constructor(context) {
1373 this.transformations = [];
1374 this.delegationContext = context;
1375 const transforms = context.transforms;
1376 const delegationTransforms = transforms.slice().reverse();
1377 for (const transform of delegationTransforms) {
1378 this.addTransform(transform, {});
1379 }
1380 }
1381 addTransform(transform, context = {}) {
1382 this.transformations.push({ transform, context });
1383 }
1384 transformRequest(originalRequest) {
1385 var _a;
1386 let request = {
1387 ...originalRequest,
1388 document: prepareGatewayDocument(originalRequest.document, this.delegationContext.transformedSchema, this.delegationContext.returnType, (_a = this.delegationContext.info) === null || _a === void 0 ? void 0 : _a.schema),
1389 };
1390 for (const transformation of this.transformations) {
1391 if (transformation.transform.transformRequest) {
1392 request = transformation.transform.transformRequest(request, this.delegationContext, transformation.context);
1393 }
1394 }
1395 return finalizeGatewayRequest(request, this.delegationContext);
1396 }
1397 transformResult(originalResult) {
1398 let result = originalResult;
1399 // from rigth to left
1400 for (let i = this.transformations.length - 1; i >= 0; i--) {
1401 const transformation = this.transformations[i];
1402 if (transformation.transform.transformResult) {
1403 result = transformation.transform.transformResult(result, this.delegationContext, transformation.context);
1404 }
1405 }
1406 return checkResultAndHandleErrors(result, this.delegationContext);
1407 }
1408}
1409
1410function getDelegatingOperation(parentType, schema) {
1411 if (parentType === schema.getMutationType()) {
1412 return 'mutation';
1413 }
1414 else if (parentType === schema.getSubscriptionType()) {
1415 return 'subscription';
1416 }
1417 return 'query';
1418}
1419function createRequestFromInfo({ info, rootValue, operationName, operation = getDelegatingOperation(info.parentType, info.schema), fieldName = info.fieldName, selectionSet, fieldNodes = info.fieldNodes, context, }) {
1420 return createRequest({
1421 sourceSchema: info.schema,
1422 sourceParentType: info.parentType,
1423 sourceFieldName: info.fieldName,
1424 fragments: info.fragments,
1425 variableDefinitions: info.operation.variableDefinitions,
1426 variableValues: info.variableValues,
1427 targetRootValue: rootValue,
1428 targetOperationName: operationName,
1429 targetOperation: operation,
1430 targetFieldName: fieldName,
1431 selectionSet,
1432 fieldNodes,
1433 context,
1434 info,
1435 });
1436}
1437function createRequest({ sourceSchema, sourceParentType, sourceFieldName, fragments, variableDefinitions, variableValues, targetRootValue, targetOperationName, targetOperation, targetFieldName, selectionSet, fieldNodes, context, info, }) {
1438 var _a, _b;
1439 let newSelectionSet;
1440 const argumentNodeMap = Object.create(null);
1441 if (selectionSet != null) {
1442 newSelectionSet = selectionSet;
1443 }
1444 else {
1445 const selections = [];
1446 for (const fieldNode of fieldNodes || []) {
1447 if (fieldNode.selectionSet) {
1448 for (const selection of fieldNode.selectionSet.selections) {
1449 selections.push(selection);
1450 }
1451 }
1452 }
1453 newSelectionSet = selections.length
1454 ? {
1455 kind: graphql.Kind.SELECTION_SET,
1456 selections,
1457 }
1458 : undefined;
1459 const args = (_a = fieldNodes === null || fieldNodes === void 0 ? void 0 : fieldNodes[0]) === null || _a === void 0 ? void 0 : _a.arguments;
1460 if (args) {
1461 for (const argNode of args) {
1462 argumentNodeMap[argNode.name.value] = argNode;
1463 }
1464 }
1465 }
1466 const newVariables = Object.create(null);
1467 const variableDefinitionMap = Object.create(null);
1468 if (sourceSchema != null && variableDefinitions != null) {
1469 for (const def of variableDefinitions) {
1470 const varName = def.variable.name.value;
1471 variableDefinitionMap[varName] = def;
1472 const varType = graphql.typeFromAST(sourceSchema, def.type);
1473 const serializedValue = utils.serializeInputValue(varType, variableValues === null || variableValues === void 0 ? void 0 : variableValues[varName]);
1474 if (serializedValue !== undefined) {
1475 newVariables[varName] = serializedValue;
1476 }
1477 }
1478 }
1479 if (sourceParentType != null && sourceFieldName != null) {
1480 updateArgumentsWithDefaults(sourceParentType, sourceFieldName, argumentNodeMap, variableDefinitionMap, newVariables);
1481 }
1482 const rootFieldName = targetFieldName !== null && targetFieldName !== void 0 ? targetFieldName : (_b = fieldNodes === null || fieldNodes === void 0 ? void 0 : fieldNodes[0]) === null || _b === void 0 ? void 0 : _b.name.value;
1483 if (rootFieldName === undefined) {
1484 throw new Error(`Either "targetFieldName" or a non empty "fieldNodes" array must be provided.`);
1485 }
1486 const rootfieldNode = {
1487 kind: graphql.Kind.FIELD,
1488 arguments: Object.values(argumentNodeMap),
1489 name: {
1490 kind: graphql.Kind.NAME,
1491 value: rootFieldName,
1492 },
1493 selectionSet: newSelectionSet,
1494 };
1495 const operationName = targetOperationName
1496 ? {
1497 kind: graphql.Kind.NAME,
1498 value: targetOperationName,
1499 }
1500 : undefined;
1501 const operationDefinition = {
1502 kind: graphql.Kind.OPERATION_DEFINITION,
1503 name: operationName,
1504 operation: targetOperation,
1505 variableDefinitions: Object.values(variableDefinitionMap),
1506 selectionSet: {
1507 kind: graphql.Kind.SELECTION_SET,
1508 selections: [rootfieldNode],
1509 },
1510 };
1511 const definitions = [operationDefinition];
1512 if (fragments != null) {
1513 for (const fragmentName in fragments) {
1514 const fragment = fragments[fragmentName];
1515 definitions.push(fragment);
1516 }
1517 }
1518 const document = {
1519 kind: graphql.Kind.DOCUMENT,
1520 definitions,
1521 };
1522 return {
1523 document,
1524 variables: newVariables,
1525 rootValue: targetRootValue,
1526 operationName: targetOperationName,
1527 operationType: targetOperation,
1528 context,
1529 info,
1530 };
1531}
1532function updateArgumentsWithDefaults(sourceParentType, sourceFieldName, argumentNodeMap, variableDefinitionMap, variableValues) {
1533 const generateVariableName = utils.createVariableNameGenerator(variableDefinitionMap);
1534 const sourceField = sourceParentType.getFields()[sourceFieldName];
1535 for (const argument of sourceField.args) {
1536 const argName = argument.name;
1537 const sourceArgType = argument.type;
1538 if (argumentNodeMap[argName] === undefined) {
1539 const defaultValue = argument.defaultValue;
1540 if (defaultValue !== undefined) {
1541 utils.updateArgument(argumentNodeMap, variableDefinitionMap, variableValues, argName, generateVariableName(argName), sourceArgType, utils.serializeInputValue(sourceArgType, defaultValue));
1542 }
1543 }
1544 }
1545}
1546
1547/**
1548 * Resolver that knows how to:
1549 * a) handle aliases for proxied schemas
1550 * b) handle errors from proxied schemas
1551 * c) handle external to internal enum conversion
1552 */
1553function defaultMergedResolver(parent, args, context, info) {
1554 if (!parent) {
1555 return null;
1556 }
1557 const responseKey = utils.getResponseKeyFromInfo(info);
1558 // check to see if parent is not a proxied result, i.e. if parent resolver was manually overwritten
1559 // See https://github.com/apollographql/graphql-tools/issues/967
1560 if (!isExternalObject(parent)) {
1561 return graphql.defaultFieldResolver(parent, args, context, info);
1562 }
1563 const data = parent[responseKey];
1564 const unpathedErrors = getUnpathedErrors(parent);
1565 const subschema = getSubschema(parent, responseKey);
1566 return resolveExternalValue(data, unpathedErrors, subschema, context, info);
1567}
1568
1569function delegateToSchema(options) {
1570 const { info, schema, rootValue, operationName, operation = getDelegatingOperation(info.parentType, info.schema), fieldName = info.fieldName, selectionSet, fieldNodes, context, } = options;
1571 const request = createRequestFromInfo({
1572 info,
1573 operation,
1574 fieldName,
1575 selectionSet,
1576 fieldNodes,
1577 rootValue: rootValue !== null && rootValue !== void 0 ? rootValue : schema.rootValue,
1578 operationName,
1579 context,
1580 });
1581 return delegateRequest({
1582 ...options,
1583 request,
1584 });
1585}
1586function getDelegationReturnType(targetSchema, operation, fieldName) {
1587 const rootType = utils.getDefinedRootType(targetSchema, operation);
1588 return rootType.getFields()[fieldName].type;
1589}
1590function delegateRequest(options) {
1591 const delegationContext = getDelegationContext(options);
1592 const transformer = new Transformer(delegationContext);
1593 const processedRequest = transformer.transformRequest(options.request);
1594 if (options.validateRequest) {
1595 validateRequest(delegationContext, processedRequest.document);
1596 }
1597 const executor = getExecutor(delegationContext);
1598 return new valueOrPromise.ValueOrPromise(() => executor(processedRequest))
1599 .then(originalResult => {
1600 if (utils.isAsyncIterable(originalResult)) {
1601 // "subscribe" to the subscription result and map the result through the transforms
1602 return utils.mapAsyncIterator(originalResult, result => transformer.transformResult(result));
1603 }
1604 return transformer.transformResult(originalResult);
1605 })
1606 .resolve();
1607}
1608function getDelegationContext({ request, schema, fieldName, returnType, args, info, transforms = [], transformedSchema, skipTypeMerging = false, }) {
1609 var _a, _b, _c, _d;
1610 const { operationType: operation, context, operationName, document } = request;
1611 let operationDefinition;
1612 let targetFieldName;
1613 if (fieldName == null) {
1614 operationDefinition = graphql.getOperationAST(document, operationName);
1615 if (operationDefinition == null) {
1616 throw new Error('Cannot infer main operation from the provided document.');
1617 }
1618 targetFieldName = (operationDefinition === null || operationDefinition === void 0 ? void 0 : operationDefinition.selectionSet.selections[0]).name.value;
1619 }
1620 else {
1621 targetFieldName = fieldName;
1622 }
1623 const stitchingInfo = (_a = info === null || info === void 0 ? void 0 : info.schema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
1624 const subschemaOrSubschemaConfig = (_b = stitchingInfo === null || stitchingInfo === void 0 ? void 0 : stitchingInfo.subschemaMap.get(schema)) !== null && _b !== void 0 ? _b : schema;
1625 if (isSubschemaConfig(subschemaOrSubschemaConfig)) {
1626 const targetSchema = subschemaOrSubschemaConfig.schema;
1627 return {
1628 subschema: schema,
1629 subschemaConfig: subschemaOrSubschemaConfig,
1630 targetSchema,
1631 operation,
1632 fieldName: targetFieldName,
1633 args,
1634 context,
1635 info,
1636 returnType: (_c = returnType !== null && returnType !== void 0 ? returnType : info === null || info === void 0 ? void 0 : info.returnType) !== null && _c !== void 0 ? _c : getDelegationReturnType(targetSchema, operation, targetFieldName),
1637 transforms: subschemaOrSubschemaConfig.transforms != null
1638 ? subschemaOrSubschemaConfig.transforms.concat(transforms)
1639 : transforms,
1640 transformedSchema: transformedSchema !== null && transformedSchema !== void 0 ? transformedSchema : (subschemaOrSubschemaConfig instanceof Subschema ? subschemaOrSubschemaConfig.transformedSchema : targetSchema),
1641 skipTypeMerging,
1642 };
1643 }
1644 return {
1645 subschema: schema,
1646 subschemaConfig: undefined,
1647 targetSchema: subschemaOrSubschemaConfig,
1648 operation,
1649 fieldName: targetFieldName,
1650 args,
1651 context,
1652 info,
1653 returnType: (_d = returnType !== null && returnType !== void 0 ? returnType : info === null || info === void 0 ? void 0 : info.returnType) !== null && _d !== void 0 ? _d : getDelegationReturnType(subschemaOrSubschemaConfig, operation, targetFieldName),
1654 transforms,
1655 transformedSchema: transformedSchema !== null && transformedSchema !== void 0 ? transformedSchema : subschemaOrSubschemaConfig,
1656 skipTypeMerging,
1657 };
1658}
1659function validateRequest(delegationContext, document) {
1660 const errors = graphql.validate(delegationContext.targetSchema, document);
1661 if (errors.length > 0) {
1662 if (errors.length > 1) {
1663 const combinedError = new utils.AggregateError(errors);
1664 throw combinedError;
1665 }
1666 const error = errors[0];
1667 throw error.originalError || error;
1668 }
1669}
1670function getExecutor(delegationContext) {
1671 var _a, _b;
1672 const { subschemaConfig, targetSchema, context } = delegationContext;
1673 let executor = (subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.executor) || createDefaultExecutor(targetSchema);
1674 if (subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.batch) {
1675 const batchingOptions = subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.batchingOptions;
1676 executor = batchExecute.getBatchingExecutor((_b = (_a = context !== null && context !== void 0 ? context : globalThis) !== null && _a !== void 0 ? _a : window) !== null && _b !== void 0 ? _b : global, executor, batchingOptions === null || batchingOptions === void 0 ? void 0 : batchingOptions.dataLoaderOptions, batchingOptions === null || batchingOptions === void 0 ? void 0 : batchingOptions.extensionsReducer);
1677 }
1678 return executor;
1679}
1680const defaultExecutorCache = new WeakMap();
1681function createDefaultExecutor(schema) {
1682 let defaultExecutor = defaultExecutorCache.get(schema);
1683 if (!defaultExecutor) {
1684 defaultExecutor = function defaultExecutor({ document, context, variables, rootValue, operationName, operationType, }) {
1685 const executionArgs = {
1686 schema,
1687 document,
1688 contextValue: context,
1689 variableValues: variables,
1690 rootValue,
1691 operationName,
1692 };
1693 if (operationType === 'subscription') {
1694 return graphql.subscribe(executionArgs);
1695 }
1696 return graphql.execute(executionArgs);
1697 };
1698 defaultExecutorCache.set(schema, defaultExecutor);
1699 }
1700 return defaultExecutor;
1701}
1702
1703exports.Subschema = Subschema;
1704exports.Transformer = Transformer;
1705exports.annotateExternalObject = annotateExternalObject;
1706exports.applySchemaTransforms = applySchemaTransforms;
1707exports.cloneSubschemaConfig = cloneSubschemaConfig;
1708exports.createDefaultExecutor = createDefaultExecutor;
1709exports.createRequest = createRequest;
1710exports.createRequestFromInfo = createRequestFromInfo;
1711exports.defaultMergedResolver = defaultMergedResolver;
1712exports.delegateRequest = delegateRequest;
1713exports.delegateToSchema = delegateToSchema;
1714exports.getDelegatingOperation = getDelegatingOperation;
1715exports.getSubschema = getSubschema;
1716exports.getUnpathedErrors = getUnpathedErrors;
1717exports.isExternalObject = isExternalObject;
1718exports.isSubschema = isSubschema;
1719exports.isSubschemaConfig = isSubschemaConfig;
1720exports.mergeFields = mergeFields;
1721exports.resolveExternalValue = resolveExternalValue;