This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
admin-panel/graphql-types/node_modules/@graphql-tools/delegate/index.cjs.js

1755 lines
74 KiB
JavaScript

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
const utils = require('@graphql-tools/utils');
const graphql = require('graphql');
const AggregateError = _interopDefault(require('@ardatan/aggregate-error'));
const isPromise = _interopDefault(require('is-promise'));
const batchExecute = require('@graphql-tools/batch-execute');
function applySchemaTransforms(originalWrappingSchema, subschemaConfig, transformedSchema) {
const schemaTransforms = subschemaConfig.transforms;
if (schemaTransforms == null) {
return originalWrappingSchema;
}
return schemaTransforms.reduce((schema, transform) => transform.transformSchema != null
? transform.transformSchema(utils.cloneSchema(schema), subschemaConfig, transformedSchema)
: schema, originalWrappingSchema);
}
function isSubschema(value) {
return Boolean(value.transformedSchema);
}
class Subschema {
constructor(config) {
var _a;
this.schema = config.schema;
this.rootValue = config.rootValue;
this.executor = config.executor;
this.subscriber = config.subscriber;
this.batch = config.batch;
this.batchingOptions = config.batchingOptions;
this.createProxyingResolver = config.createProxyingResolver;
this.transforms = (_a = config.transforms) !== null && _a !== void 0 ? _a : [];
this.transformedSchema = applySchemaTransforms(this.schema, config);
this.merge = config.merge;
}
}
function getDelegatingOperation(parentType, schema) {
if (parentType === schema.getMutationType()) {
return 'mutation';
}
else if (parentType === schema.getSubscriptionType()) {
return 'subscription';
}
return 'query';
}
function createRequestFromInfo({ info, operationName, operation = getDelegatingOperation(info.parentType, info.schema), fieldName = info.fieldName, selectionSet, fieldNodes = info.fieldNodes, }) {
return createRequest({
sourceSchema: info.schema,
sourceParentType: info.parentType,
sourceFieldName: info.fieldName,
fragments: info.fragments,
variableDefinitions: info.operation.variableDefinitions,
variableValues: info.variableValues,
targetOperationName: operationName,
targetOperation: operation,
targetFieldName: fieldName,
selectionSet,
fieldNodes,
});
}
function createRequest({ sourceSchema, sourceParentType, sourceFieldName, fragments, variableDefinitions, variableValues, targetOperationName, targetOperation, targetFieldName, selectionSet, fieldNodes, }) {
var _a;
let newSelectionSet;
let argumentNodeMap;
if (selectionSet != null) {
newSelectionSet = selectionSet;
argumentNodeMap = Object.create(null);
}
else {
const selections = fieldNodes.reduce((acc, fieldNode) => (fieldNode.selectionSet != null ? acc.concat(fieldNode.selectionSet.selections) : acc), []);
newSelectionSet = selections.length
? {
kind: graphql.Kind.SELECTION_SET,
selections,
}
: undefined;
argumentNodeMap = {};
const args = (_a = fieldNodes[0]) === null || _a === void 0 ? void 0 : _a.arguments;
if (args) {
argumentNodeMap = args.reduce((prev, curr) => ({
...prev,
[curr.name.value]: curr,
}), argumentNodeMap);
}
}
const newVariables = Object.create(null);
const variableDefinitionMap = Object.create(null);
if (sourceSchema != null && variableDefinitions != null) {
variableDefinitions.forEach(def => {
const varName = def.variable.name.value;
variableDefinitionMap[varName] = def;
const varType = graphql.typeFromAST(sourceSchema, def.type);
const serializedValue = utils.serializeInputValue(varType, variableValues[varName]);
if (serializedValue !== undefined) {
newVariables[varName] = serializedValue;
}
});
}
if (sourceParentType != null) {
updateArgumentsWithDefaults(sourceParentType, sourceFieldName, argumentNodeMap, variableDefinitionMap, newVariables);
}
const rootfieldNode = {
kind: graphql.Kind.FIELD,
arguments: Object.keys(argumentNodeMap).map(argName => argumentNodeMap[argName]),
name: {
kind: graphql.Kind.NAME,
value: targetFieldName || fieldNodes[0].name.value,
},
selectionSet: newSelectionSet,
};
const operationName = targetOperationName
? {
kind: graphql.Kind.NAME,
value: targetOperationName,
}
: undefined;
const operationDefinition = {
kind: graphql.Kind.OPERATION_DEFINITION,
name: operationName,
operation: targetOperation,
variableDefinitions: Object.keys(variableDefinitionMap).map(varName => variableDefinitionMap[varName]),
selectionSet: {
kind: graphql.Kind.SELECTION_SET,
selections: [rootfieldNode],
},
};
let definitions = [operationDefinition];
if (fragments != null) {
definitions = definitions.concat(Object.keys(fragments).map(fragmentName => fragments[fragmentName]));
}
const document = {
kind: graphql.Kind.DOCUMENT,
definitions,
};
return {
document,
variables: newVariables,
};
}
function updateArgumentsWithDefaults(sourceParentType, sourceFieldName, argumentNodeMap, variableDefinitionMap, variableValues) {
const sourceField = sourceParentType.getFields()[sourceFieldName];
sourceField.args.forEach((argument) => {
const argName = argument.name;
const sourceArgType = argument.type;
if (argumentNodeMap[argName] === undefined) {
const defaultValue = argument.defaultValue;
if (defaultValue !== undefined) {
utils.updateArgument(argName, sourceArgType, argumentNodeMap, variableDefinitionMap, variableValues, utils.serializeInputValue(sourceArgType, defaultValue));
}
}
});
}
const UNPATHED_ERRORS_SYMBOL = Symbol('subschemaErrors');
const OBJECT_SUBSCHEMA_SYMBOL = Symbol('initialSubschema');
const FIELD_SUBSCHEMA_MAP_SYMBOL = Symbol('subschemaMap');
function isExternalObject(data) {
return data[UNPATHED_ERRORS_SYMBOL] !== undefined;
}
function annotateExternalObject(object, errors, subschema) {
Object.defineProperties(object, {
[OBJECT_SUBSCHEMA_SYMBOL]: { value: subschema },
[FIELD_SUBSCHEMA_MAP_SYMBOL]: { value: Object.create(null) },
[UNPATHED_ERRORS_SYMBOL]: { value: errors },
});
return object;
}
function getSubschema(object, responseKey) {
var _a;
return (_a = object[FIELD_SUBSCHEMA_MAP_SYMBOL][responseKey]) !== null && _a !== void 0 ? _a : object[OBJECT_SUBSCHEMA_SYMBOL];
}
function getUnpathedErrors(object) {
return object[UNPATHED_ERRORS_SYMBOL];
}
function mergeExternalObjects(schema, path, typeName, target, sources, selectionSets) {
var _a;
const results = [];
let errors = [];
sources.forEach((source, index) => {
if (source instanceof graphql.GraphQLError || source === null) {
const selectionSet = selectionSets[index];
const fieldNodes = utils.collectFields({
schema,
variableValues: {},
fragments: {},
}, schema.getType(typeName), selectionSet, Object.create(null), Object.create(null));
const nullResult = {};
Object.keys(fieldNodes).forEach(responseKey => {
nullResult[responseKey] =
source instanceof graphql.GraphQLError ? utils.relocatedError(source, path.concat([responseKey])) : null;
});
results.push(nullResult);
}
else {
errors = errors.concat(source[UNPATHED_ERRORS_SYMBOL]);
results.push(source);
}
});
const combinedResult = results.reduce(utils.mergeDeep, target);
const newFieldSubschemaMap = (_a = target[FIELD_SUBSCHEMA_MAP_SYMBOL]) !== null && _a !== void 0 ? _a : Object.create(null);
results.forEach((source) => {
const objectSubschema = source[OBJECT_SUBSCHEMA_SYMBOL];
const fieldSubschemaMap = source[FIELD_SUBSCHEMA_MAP_SYMBOL];
if (fieldSubschemaMap === undefined) {
Object.keys(source).forEach(responseKey => {
newFieldSubschemaMap[responseKey] = objectSubschema;
});
}
else {
Object.keys(source).forEach(responseKey => {
var _a;
newFieldSubschemaMap[responseKey] = (_a = fieldSubschemaMap[responseKey]) !== null && _a !== void 0 ? _a : objectSubschema;
});
}
});
combinedResult[FIELD_SUBSCHEMA_MAP_SYMBOL] = newFieldSubschemaMap;
combinedResult[OBJECT_SUBSCHEMA_SYMBOL] = target[OBJECT_SUBSCHEMA_SYMBOL];
combinedResult[UNPATHED_ERRORS_SYMBOL] = target[UNPATHED_ERRORS_SYMBOL].concat(errors);
return combinedResult;
}
function isSubschemaConfig(value) {
return Boolean(value === null || value === void 0 ? void 0 : value.schema);
}
function cloneSubschemaConfig(subschemaConfig) {
const newSubschemaConfig = {
...subschemaConfig,
transforms: subschemaConfig.transforms != null ? [...subschemaConfig.transforms] : undefined,
};
if (newSubschemaConfig.merge != null) {
newSubschemaConfig.merge = { ...subschemaConfig.merge };
Object.keys(newSubschemaConfig.merge).forEach(typeName => {
newSubschemaConfig.merge[typeName] = { ...subschemaConfig.merge[typeName] };
const fields = newSubschemaConfig.merge[typeName].fields;
if (fields != null) {
Object.keys(fields).forEach(fieldName => {
fields[fieldName] = { ...fields[fieldName] };
});
}
});
}
return newSubschemaConfig;
}
function memoizeInfoAnd2Objects(fn) {
let cache1;
function memoized(a1, a2, a3) {
if (!cache1) {
cache1 = new WeakMap();
const cache2 = new WeakMap();
cache1.set(a1.fieldNodes, cache2);
const cache3 = new WeakMap();
cache2.set(a2, cache3);
const newValue = fn(a1, a2, a3);
cache3.set(a3, newValue);
return newValue;
}
let cache2 = cache1.get(a1.fieldNodes);
if (!cache2) {
cache2 = new WeakMap();
cache1.set(a1.fieldNodes, cache2);
const cache3 = new WeakMap();
cache2.set(a2, cache3);
const newValue = fn(a1, a2, a3);
cache3.set(a3, newValue);
return newValue;
}
let cache3 = cache2.get(a2);
if (!cache3) {
cache3 = new WeakMap();
cache2.set(a2, cache3);
const newValue = fn(a1, a2, a3);
cache3.set(a3, newValue);
return newValue;
}
const cachedValue = cache3.get(a3);
if (cachedValue === undefined) {
const newValue = fn(a1, a2, a3);
cache3.set(a3, newValue);
return newValue;
}
return cachedValue;
}
return memoized;
}
function memoize4(fn) {
let cache1;
function memoized(a1, a2, a3, a4) {
if (!cache1) {
cache1 = new WeakMap();
const cache2 = new WeakMap();
cache1.set(a1, cache2);
const cache3 = new WeakMap();
cache2.set(a2, cache3);
const cache4 = new WeakMap();
cache3.set(a3, cache4);
const newValue = fn(a1, a2, a3, a4);
cache4.set(a4, newValue);
return newValue;
}
let cache2 = cache1.get(a1);
if (!cache2) {
cache2 = new WeakMap();
cache1.set(a1, cache2);
const cache3 = new WeakMap();
cache2.set(a2, cache3);
const cache4 = new WeakMap();
cache3.set(a3, cache4);
const newValue = fn(a1, a2, a3, a4);
cache4.set(a4, newValue);
return newValue;
}
let cache3 = cache2.get(a2);
if (!cache3) {
cache3 = new WeakMap();
cache2.set(a2, cache3);
const cache4 = new WeakMap();
cache3.set(a3, cache4);
const newValue = fn(a1, a2, a3, a4);
cache4.set(a4, newValue);
return newValue;
}
const cache4 = cache3.get(a3);
if (!cache4) {
const cache4 = new WeakMap();
cache3.set(a3, cache4);
const newValue = fn(a1, a2, a3, a4);
cache4.set(a4, newValue);
return newValue;
}
const cachedValue = cache4.get(a4);
if (cachedValue === undefined) {
const newValue = fn(a1, a2, a3, a4);
cache4.set(a4, newValue);
return newValue;
}
return cachedValue;
}
return memoized;
}
function memoize3(fn) {
let cache1;
function memoized(a1, a2, a3) {
if (!cache1) {
cache1 = new WeakMap();
const cache2 = new WeakMap();
cache1.set(a1, cache2);
const cache3 = new WeakMap();
cache2.set(a2, cache3);
const newValue = fn(a1, a2, a3);
cache3.set(a3, newValue);
return newValue;
}
let cache2 = cache1.get(a1);
if (!cache2) {
cache2 = new WeakMap();
cache1.set(a1, cache2);
const cache3 = new WeakMap();
cache2.set(a2, cache3);
const newValue = fn(a1, a2, a3);
cache3.set(a3, newValue);
return newValue;
}
let cache3 = cache2.get(a2);
if (!cache3) {
cache3 = new WeakMap();
cache2.set(a2, cache3);
const newValue = fn(a1, a2, a3);
cache3.set(a3, newValue);
return newValue;
}
const cachedValue = cache3.get(a3);
if (cachedValue === undefined) {
const newValue = fn(a1, a2, a3);
cache3.set(a3, newValue);
return newValue;
}
return cachedValue;
}
return memoized;
}
function memoize2(fn) {
let cache1;
function memoized(a1, a2) {
if (!cache1) {
cache1 = new WeakMap();
const cache2 = new WeakMap();
cache1.set(a1, cache2);
const newValue = fn(a1, a2);
cache2.set(a2, newValue);
return newValue;
}
let cache2 = cache1.get(a1);
if (!cache2) {
cache2 = new WeakMap();
cache1.set(a1, cache2);
const newValue = fn(a1, a2);
cache2.set(a2, newValue);
return newValue;
}
const cachedValue = cache2.get(a2);
if (cachedValue === undefined) {
const newValue = fn(a1, a2);
cache2.set(a2, newValue);
return newValue;
}
return cachedValue;
}
return memoized;
}
function collectSubFields(info, typeName) {
let subFieldNodes = Object.create(null);
const visitedFragmentNames = Object.create(null);
const type = info.schema.getType(typeName);
const partialExecutionContext = {
schema: info.schema,
variableValues: info.variableValues,
fragments: info.fragments,
};
info.fieldNodes.forEach(fieldNode => {
subFieldNodes = utils.collectFields(partialExecutionContext, type, fieldNode.selectionSet, subFieldNodes, visitedFragmentNames);
});
const stitchingInfo = info.schema.extensions.stitchingInfo;
const selectionSetsByField = stitchingInfo.selectionSetsByField;
Object.keys(subFieldNodes).forEach(responseName => {
var _a;
const fieldName = subFieldNodes[responseName][0].name.value;
const fieldSelectionSet = (_a = selectionSetsByField === null || selectionSetsByField === void 0 ? void 0 : selectionSetsByField[typeName]) === null || _a === void 0 ? void 0 : _a[fieldName];
if (fieldSelectionSet != null) {
subFieldNodes = utils.collectFields(partialExecutionContext, type, fieldSelectionSet, subFieldNodes, visitedFragmentNames);
}
});
return subFieldNodes;
}
const getFieldsNotInSubschema = memoizeInfoAnd2Objects(function (info, subschema, mergedTypeInfo) {
const typeMap = isSubschemaConfig(subschema) ? mergedTypeInfo.typeMaps.get(subschema) : subschema.getTypeMap();
const typeName = mergedTypeInfo.typeName;
const fields = typeMap[typeName].getFields();
const subFieldNodes = collectSubFields(info, typeName);
let fieldsNotInSchema = [];
Object.keys(subFieldNodes).forEach(responseName => {
const fieldName = subFieldNodes[responseName][0].name.value;
if (!(fieldName in fields)) {
fieldsNotInSchema = fieldsNotInSchema.concat(subFieldNodes[responseName]);
}
});
return fieldsNotInSchema;
});
const sortSubschemasByProxiability = memoize4(function (mergedTypeInfo, sourceSubschemaOrSourceSubschemas, targetSubschemas, fieldNodes) {
// 1. calculate if possible to delegate to given subschema
const proxiableSubschemas = [];
const nonProxiableSubschemas = [];
targetSubschemas.forEach(t => {
const selectionSet = mergedTypeInfo.selectionSets.get(t);
const fieldSelectionSets = mergedTypeInfo.fieldSelectionSets.get(t);
if (selectionSet != null &&
!subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, selectionSet)) {
nonProxiableSubschemas.push(t);
}
else {
if (fieldSelectionSets == null ||
fieldNodes.every(fieldNode => {
const fieldName = fieldNode.name.value;
const fieldSelectionSet = fieldSelectionSets[fieldName];
return (fieldSelectionSet == null ||
subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, fieldSelectionSet));
})) {
proxiableSubschemas.push(t);
}
else {
nonProxiableSubschemas.push(t);
}
}
});
return {
proxiableSubschemas,
nonProxiableSubschemas,
};
});
const buildDelegationPlan = memoize3(function (mergedTypeInfo, fieldNodes, proxiableSubschemas) {
const { uniqueFields, nonUniqueFields } = mergedTypeInfo;
const unproxiableFieldNodes = [];
// 2. for each selection:
const delegationMap = new Map();
fieldNodes.forEach(fieldNode => {
if (fieldNode.name.value === '__typename') {
return;
}
// 2a. use uniqueFields map to assign fields to subschema if one of possible subschemas
const uniqueSubschema = uniqueFields[fieldNode.name.value];
if (uniqueSubschema != null) {
if (!proxiableSubschemas.includes(uniqueSubschema)) {
unproxiableFieldNodes.push(fieldNode);
return;
}
const existingSubschema = delegationMap.get(uniqueSubschema);
if (existingSubschema != null) {
existingSubschema.push(fieldNode);
}
else {
delegationMap.set(uniqueSubschema, [fieldNode]);
}
return;
}
// 2b. use nonUniqueFields to assign to a possible subschema,
// preferring one of the subschemas already targets of delegation
let nonUniqueSubschemas = nonUniqueFields[fieldNode.name.value];
if (nonUniqueSubschemas == null) {
unproxiableFieldNodes.push(fieldNode);
return;
}
nonUniqueSubschemas = nonUniqueSubschemas.filter(s => proxiableSubschemas.includes(s));
if (!nonUniqueSubschemas.length) {
unproxiableFieldNodes.push(fieldNode);
return;
}
const existingSubschema = nonUniqueSubschemas.find(s => delegationMap.has(s));
if (existingSubschema != null) {
delegationMap.get(existingSubschema).push(fieldNode);
}
else {
delegationMap.set(nonUniqueSubschemas[0], [fieldNode]);
}
});
const finalDelegationMap = new Map();
delegationMap.forEach((selections, subschema) => {
finalDelegationMap.set(subschema, {
kind: graphql.Kind.SELECTION_SET,
selections,
});
});
return {
delegationMap: finalDelegationMap,
unproxiableFieldNodes,
};
});
const combineSubschemas = memoize2(function (subschemaOrSubschemas, additionalSubschemas) {
return Array.isArray(subschemaOrSubschemas)
? subschemaOrSubschemas.concat(additionalSubschemas)
: [subschemaOrSubschemas].concat(additionalSubschemas);
});
function mergeFields(mergedTypeInfo, typeName, object, fieldNodes, sourceSubschemaOrSourceSubschemas, targetSubschemas, context, info) {
if (!fieldNodes.length) {
return object;
}
const { proxiableSubschemas, nonProxiableSubschemas } = sortSubschemasByProxiability(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, targetSubschemas, fieldNodes);
const { delegationMap, unproxiableFieldNodes } = buildDelegationPlan(mergedTypeInfo, fieldNodes, proxiableSubschemas);
if (!delegationMap.size) {
return object;
}
let containsPromises = false;
const resultMap = new Map();
delegationMap.forEach((selectionSet, s) => {
const resolver = mergedTypeInfo.resolvers.get(s);
let maybePromise = resolver(object, context, info, s, selectionSet);
if (isPromise(maybePromise)) {
containsPromises = true;
maybePromise = maybePromise.then(undefined, error => error);
}
resultMap.set(maybePromise, selectionSet);
});
return containsPromises
? Promise.all(resultMap.keys()).then(results => mergeFields(mergedTypeInfo, typeName, mergeExternalObjects(info.schema, graphql.responsePathAsArray(info.path), object.__typename, object, results, Array.from(resultMap.values())), unproxiableFieldNodes, combineSubschemas(sourceSubschemaOrSourceSubschemas, proxiableSubschemas), nonProxiableSubschemas, context, info))
: mergeFields(mergedTypeInfo, typeName, mergeExternalObjects(info.schema, graphql.responsePathAsArray(info.path), object.__typename, object, Array.from(resultMap.keys()), Array.from(resultMap.values())), unproxiableFieldNodes, combineSubschemas(sourceSubschemaOrSourceSubschemas, proxiableSubschemas), nonProxiableSubschemas, context, info);
}
const subschemaTypesContainSelectionSet = memoize3(function (mergedTypeInfo, sourceSubschemaOrSourceSubschemas, selectionSet) {
if (Array.isArray(sourceSubschemaOrSourceSubschemas)) {
return typesContainSelectionSet(sourceSubschemaOrSourceSubschemas.map(sourceSubschema => sourceSubschema.transformedSchema.getType(mergedTypeInfo.typeName)), selectionSet);
}
return typesContainSelectionSet([sourceSubschemaOrSourceSubschemas.transformedSchema.getType(mergedTypeInfo.typeName)], selectionSet);
});
function typesContainSelectionSet(types, selectionSet) {
const fieldMaps = types.map(type => type.getFields());
for (const selection of selectionSet.selections) {
if (selection.kind === graphql.Kind.FIELD) {
const fields = fieldMaps.map(fieldMap => fieldMap[selection.name.value]).filter(field => field != null);
if (!fields.length) {
return false;
}
if (selection.selectionSet != null) {
return typesContainSelectionSet(fields.map(field => graphql.getNamedType(field.type)), selection.selectionSet);
}
}
else if (selection.kind === graphql.Kind.INLINE_FRAGMENT && selection.typeCondition.name.value === types[0].name) {
return typesContainSelectionSet(types, selection.selectionSet);
}
}
return true;
}
function resolveExternalValue(result, unpathedErrors, subschema, context, info, returnType = info.returnType, skipTypeMerging) {
const type = graphql.getNullableType(returnType);
if (result instanceof Error) {
return result;
}
if (result == null) {
return reportUnpathedErrorsViaNull(unpathedErrors);
}
if (graphql.isLeafType(type)) {
return type.parseValue(result);
}
else if (graphql.isCompositeType(type)) {
return resolveExternalObject(type, result, unpathedErrors, subschema, context, info, skipTypeMerging);
}
else if (graphql.isListType(type)) {
return resolveExternalList(type, result, unpathedErrors, subschema, context, info, skipTypeMerging);
}
}
function resolveExternalObject(type, object, unpathedErrors, subschema, context, info, skipTypeMerging) {
var _a;
// if we have already resolved this object, for example, when the identical object appears twice
// in a list, see https://github.com/ardatan/graphql-tools/issues/2304
if (isExternalObject(object)) {
return object;
}
annotateExternalObject(object, unpathedErrors, subschema);
const stitchingInfo = (_a = info === null || info === void 0 ? void 0 : info.schema.extensions) === null || _a === void 0 ? void 0 : _a.stitchingInfo;
if (skipTypeMerging || !stitchingInfo) {
return object;
}
let typeName;
if (graphql.isAbstractType(type)) {
const resolvedType = info.schema.getTypeMap()[object.__typename];
if (resolvedType == null) {
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?`);
}
typeName = resolvedType.name;
}
else {
typeName = type.name;
}
const mergedTypeInfo = stitchingInfo.mergedTypes[typeName];
let targetSubschemas;
// Within the stitching context, delegation to a stitched GraphQLSchema or SubschemaConfig
// will be redirected to the appropriate Subschema object, from which merge targets can be queried.
if (mergedTypeInfo != null) {
targetSubschemas = mergedTypeInfo.targetSubschemas.get(subschema);
}
// If there are no merge targets from the subschema, return.
if (!targetSubschemas) {
return object;
}
const fieldNodes = getFieldsNotInSubschema(info, subschema, mergedTypeInfo);
return mergeFields(mergedTypeInfo, typeName, object, fieldNodes, subschema, targetSubschemas, context, info);
}
function resolveExternalList(type, list, unpathedErrors, subschema, context, info, skipTypeMerging) {
return list.map(listMember => resolveExternalListMember(graphql.getNullableType(type.ofType), listMember, unpathedErrors, subschema, context, info, skipTypeMerging));
}
function resolveExternalListMember(type, listMember, unpathedErrors, subschema, context, info, skipTypeMerging) {
if (listMember instanceof Error) {
return listMember;
}
if (listMember == null) {
return reportUnpathedErrorsViaNull(unpathedErrors);
}
if (graphql.isLeafType(type)) {
return type.parseValue(listMember);
}
else if (graphql.isCompositeType(type)) {
return resolveExternalObject(type, listMember, unpathedErrors, subschema, context, info, skipTypeMerging);
}
else if (graphql.isListType(type)) {
return resolveExternalList(type, listMember, unpathedErrors, subschema, context, info, skipTypeMerging);
}
}
const reportedErrors = new Map();
function reportUnpathedErrorsViaNull(unpathedErrors) {
if (unpathedErrors.length) {
const unreportedErrors = [];
unpathedErrors.forEach(error => {
if (!reportedErrors.has(error)) {
unreportedErrors.push(error);
reportedErrors.set(error, true);
}
});
if (unreportedErrors.length) {
if (unreportedErrors.length === 1) {
return unreportedErrors[0];
}
const combinedError = new AggregateError(unreportedErrors);
return graphql.locatedError(combinedError, undefined, unreportedErrors[0].path);
}
}
return null;
}
/**
* Resolver that knows how to:
* a) handle aliases for proxied schemas
* b) handle errors from proxied schemas
* c) handle external to internal enum coversion
*/
function defaultMergedResolver(parent, args, context, info) {
if (!parent) {
return null;
}
const responseKey = utils.getResponseKeyFromInfo(info);
// check to see if parent is not a proxied result, i.e. if parent resolver was manually overwritten
// See https://github.com/apollographql/graphql-tools/issues/967
if (!isExternalObject(parent)) {
return graphql.defaultFieldResolver(parent, args, context, info);
}
const data = parent[responseKey];
const unpathedErrors = getUnpathedErrors(parent);
const subschema = getSubschema(parent, responseKey);
return resolveExternalValue(data, unpathedErrors, subschema, context, info);
}
class VisitSelectionSets {
constructor(visitor) {
this.visitor = visitor;
}
transformRequest(originalRequest, delegationContext, _transformationContext) {
const document = visitSelectionSets(originalRequest, delegationContext.info.schema, delegationContext.returnType, this.visitor);
return {
...originalRequest,
document,
};
}
}
function visitSelectionSets(request, schema, initialType, visitor) {
const { document, variables } = request;
const operations = [];
const fragments = Object.create(null);
document.definitions.forEach(def => {
if (def.kind === graphql.Kind.OPERATION_DEFINITION) {
operations.push(def);
}
else if (def.kind === graphql.Kind.FRAGMENT_DEFINITION) {
fragments[def.name.value] = def;
}
});
const partialExecutionContext = {
schema,
variableValues: variables,
fragments,
};
const typeInfo = new graphql.TypeInfo(schema, undefined, initialType);
const newDefinitions = operations.map(operation => {
const type = operation.operation === 'query'
? schema.getQueryType()
: operation.operation === 'mutation'
? schema.getMutationType()
: schema.getSubscriptionType();
const fields = utils.collectFields(partialExecutionContext, type, operation.selectionSet, Object.create(null), Object.create(null));
const newSelections = [];
Object.keys(fields).forEach(responseKey => {
const fieldNodes = fields[responseKey];
fieldNodes.forEach(fieldNode => {
const selectionSet = fieldNode.selectionSet;
if (selectionSet == null) {
newSelections.push(fieldNode);
return;
}
const newSelectionSet = graphql.visit(selectionSet, graphql.visitWithTypeInfo(typeInfo, {
[graphql.Kind.SELECTION_SET]: node => visitor(node, typeInfo),
}));
if (newSelectionSet === selectionSet) {
newSelections.push(fieldNode);
return;
}
newSelections.push({
...fieldNode,
selectionSet: newSelectionSet,
});
});
});
return {
...operation,
selectionSet: {
kind: graphql.Kind.SELECTION_SET,
selections: newSelections,
},
};
});
Object.values(fragments).forEach(fragment => {
newDefinitions.push(graphql.visit(fragment, graphql.visitWithTypeInfo(typeInfo, {
[graphql.Kind.SELECTION_SET]: node => visitor(node, typeInfo),
})));
});
return {
...document,
definitions: newDefinitions,
};
}
class AddSelectionSets {
constructor(selectionSetsByType, selectionSetsByField, dynamicSelectionSetsByField) {
this.transformer = new VisitSelectionSets((node, typeInfo) => visitSelectionSet(node, typeInfo, selectionSetsByType, selectionSetsByField, dynamicSelectionSetsByField));
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
}
}
function visitSelectionSet(node, typeInfo, selectionSetsByType, selectionSetsByField, dynamicSelectionSetsByField) {
const parentType = typeInfo.getParentType();
const newSelections = new Map();
if (parentType != null) {
const parentTypeName = parentType.name;
addSelectionsToMap(newSelections, node);
if (parentTypeName in selectionSetsByType) {
const selectionSet = selectionSetsByType[parentTypeName];
addSelectionsToMap(newSelections, selectionSet);
}
if (parentTypeName in selectionSetsByField) {
node.selections.forEach(selection => {
if (selection.kind === graphql.Kind.FIELD) {
const name = selection.name.value;
const selectionSet = selectionSetsByField[parentTypeName][name];
if (selectionSet != null) {
addSelectionsToMap(newSelections, selectionSet);
}
}
});
}
if (parentTypeName in dynamicSelectionSetsByField) {
node.selections.forEach(selection => {
if (selection.kind === graphql.Kind.FIELD) {
const name = selection.name.value;
const dynamicSelectionSets = dynamicSelectionSetsByField[parentTypeName][name];
if (dynamicSelectionSets != null) {
dynamicSelectionSets.forEach(selectionSetFn => {
const selectionSet = selectionSetFn(selection);
if (selectionSet != null) {
addSelectionsToMap(newSelections, selectionSet);
}
});
}
}
});
}
return {
...node,
selections: Array.from(newSelections.values()),
};
}
}
const addSelectionsToMap = memoize2(function (map, selectionSet) {
selectionSet.selections.forEach(selection => {
map.set(graphql.print(selection), selection);
});
});
class ExpandAbstractTypes {
transformRequest(originalRequest, delegationContext, _transformationContext) {
const targetSchema = delegationContext.targetSchema;
const { possibleTypesMap, interfaceExtensionsMap } = extractPossibleTypes(delegationContext.info.schema, targetSchema);
const reversePossibleTypesMap = flipMapping(possibleTypesMap);
const document = expandAbstractTypes(targetSchema, possibleTypesMap, reversePossibleTypesMap, interfaceExtensionsMap, originalRequest.document);
return {
...originalRequest,
document,
};
}
}
function extractPossibleTypes(sourceSchema, targetSchema) {
const typeMap = sourceSchema.getTypeMap();
const possibleTypesMap = Object.create(null);
const interfaceExtensionsMap = Object.create(null);
Object.keys(typeMap).forEach(typeName => {
const type = typeMap[typeName];
if (graphql.isAbstractType(type)) {
const targetType = targetSchema.getType(typeName);
if (graphql.isInterfaceType(type) && graphql.isInterfaceType(targetType)) {
const targetTypeFields = targetType.getFields();
const extensionFields = Object.create(null);
Object.keys(type.getFields()).forEach((fieldName) => {
if (!targetTypeFields[fieldName]) {
extensionFields[fieldName] = true;
}
});
if (Object.keys(extensionFields).length) {
interfaceExtensionsMap[typeName] = extensionFields;
}
}
if (!graphql.isAbstractType(targetType) || typeName in interfaceExtensionsMap) {
const implementations = sourceSchema.getPossibleTypes(type);
possibleTypesMap[typeName] = implementations
.filter(impl => targetSchema.getType(impl.name))
.map(impl => impl.name);
}
}
});
return { possibleTypesMap, interfaceExtensionsMap };
}
function flipMapping(mapping) {
const result = Object.create(null);
Object.keys(mapping).forEach(typeName => {
const toTypeNames = mapping[typeName];
toTypeNames.forEach(toTypeName => {
if (!(toTypeName in result)) {
result[toTypeName] = [];
}
result[toTypeName].push(typeName);
});
});
return result;
}
function expandAbstractTypes(targetSchema, possibleTypesMap, reversePossibleTypesMap, interfaceExtensionsMap, document) {
const operations = document.definitions.filter(def => def.kind === graphql.Kind.OPERATION_DEFINITION);
const fragments = document.definitions.filter(def => def.kind === graphql.Kind.FRAGMENT_DEFINITION);
const existingFragmentNames = fragments.map(fragment => fragment.name.value);
let fragmentCounter = 0;
const generateFragmentName = (typeName) => {
let fragmentName;
do {
fragmentName = `_${typeName}_Fragment${fragmentCounter.toString()}`;
fragmentCounter++;
} while (existingFragmentNames.indexOf(fragmentName) !== -1);
return fragmentName;
};
const generateInlineFragment = (typeName, selectionSet) => {
return {
kind: graphql.Kind.INLINE_FRAGMENT,
typeCondition: {
kind: graphql.Kind.NAMED_TYPE,
name: {
kind: graphql.Kind.NAME,
value: typeName,
},
},
selectionSet,
};
};
const newFragments = [];
const fragmentReplacements = Object.create(null);
fragments.forEach((fragment) => {
newFragments.push(fragment);
const possibleTypes = possibleTypesMap[fragment.typeCondition.name.value];
if (possibleTypes != null) {
fragmentReplacements[fragment.name.value] = [];
possibleTypes.forEach(possibleTypeName => {
const name = generateFragmentName(possibleTypeName);
existingFragmentNames.push(name);
const newFragment = {
kind: graphql.Kind.FRAGMENT_DEFINITION,
name: {
kind: graphql.Kind.NAME,
value: name,
},
typeCondition: {
kind: graphql.Kind.NAMED_TYPE,
name: {
kind: graphql.Kind.NAME,
value: possibleTypeName,
},
},
selectionSet: fragment.selectionSet,
};
newFragments.push(newFragment);
fragmentReplacements[fragment.name.value].push({
fragmentName: name,
typeName: possibleTypeName,
});
});
}
});
const newDocument = {
...document,
definitions: [...operations, ...newFragments],
};
const typeInfo = new graphql.TypeInfo(targetSchema);
return graphql.visit(newDocument, graphql.visitWithTypeInfo(typeInfo, {
[graphql.Kind.SELECTION_SET](node) {
let newSelections = node.selections;
const addedSelections = [];
const maybeType = typeInfo.getParentType();
if (maybeType != null) {
const parentType = graphql.getNamedType(maybeType);
const interfaceExtension = interfaceExtensionsMap[parentType.name];
const interfaceExtensionFields = [];
node.selections.forEach((selection) => {
if (selection.kind === graphql.Kind.INLINE_FRAGMENT) {
if (selection.typeCondition != null) {
const possibleTypes = possibleTypesMap[selection.typeCondition.name.value];
if (possibleTypes != null) {
possibleTypes.forEach(possibleType => {
const maybePossibleType = targetSchema.getType(possibleType);
if (maybePossibleType != null &&
utils.implementsAbstractType(targetSchema, parentType, maybePossibleType)) {
addedSelections.push(generateInlineFragment(possibleType, selection.selectionSet));
}
});
}
}
}
else if (selection.kind === graphql.Kind.FRAGMENT_SPREAD) {
const fragmentName = selection.name.value;
if (fragmentName in fragmentReplacements) {
fragmentReplacements[fragmentName].forEach(replacement => {
const typeName = replacement.typeName;
const maybeReplacementType = targetSchema.getType(typeName);
if (maybeReplacementType != null && utils.implementsAbstractType(targetSchema, parentType, maybeType)) {
addedSelections.push({
kind: graphql.Kind.FRAGMENT_SPREAD,
name: {
kind: graphql.Kind.NAME,
value: replacement.fragmentName,
},
});
}
});
}
}
else if (interfaceExtension != null &&
interfaceExtension[selection.name.value] &&
selection.kind === graphql.Kind.FIELD) {
interfaceExtensionFields.push(selection);
}
});
if (parentType.name in reversePossibleTypesMap) {
addedSelections.push({
kind: graphql.Kind.FIELD,
name: {
kind: graphql.Kind.NAME,
value: '__typename',
},
});
}
if (interfaceExtensionFields.length) {
const possibleTypes = possibleTypesMap[parentType.name];
if (possibleTypes != null) {
possibleTypes.forEach(possibleType => {
addedSelections.push(generateInlineFragment(possibleType, {
kind: graphql.Kind.SELECTION_SET,
selections: interfaceExtensionFields,
}));
});
newSelections = newSelections.filter((selection) => !(selection.kind === graphql.Kind.FIELD && interfaceExtension[selection.name.value]));
}
}
}
if (addedSelections.length) {
return {
...node,
selections: newSelections.concat(addedSelections),
};
}
},
}));
}
// For motivation, see https://github.com/ardatan/graphql-tools/issues/751
class WrapConcreteTypes {
transformRequest(originalRequest, delegationContext, _transformationContext) {
const document = wrapConcreteTypes(delegationContext.returnType, delegationContext.targetSchema, originalRequest.document);
return {
...originalRequest,
document,
};
}
}
function wrapConcreteTypes(returnType, targetSchema, document) {
var _a, _b, _c;
const namedType = graphql.getNamedType(returnType);
if (!graphql.isObjectType(namedType)) {
return document;
}
const queryTypeName = (_a = targetSchema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name;
const mutationTypeName = (_b = targetSchema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name;
const subscriptionTypeName = (_c = targetSchema.getSubscriptionType()) === null || _c === void 0 ? void 0 : _c.name;
const typeInfo = new graphql.TypeInfo(targetSchema);
const newDocument = graphql.visit(document, graphql.visitWithTypeInfo(typeInfo, {
[graphql.Kind.FRAGMENT_DEFINITION]: (node) => {
const typeName = node.typeCondition.name.value;
if (typeName !== queryTypeName && typeName !== mutationTypeName && typeName !== subscriptionTypeName) {
return false;
}
},
[graphql.Kind.FIELD]: (node) => {
if (graphql.isAbstractType(graphql.getNamedType(typeInfo.getType()))) {
return {
...node,
selectionSet: {
kind: graphql.Kind.SELECTION_SET,
selections: [
{
kind: graphql.Kind.INLINE_FRAGMENT,
typeCondition: {
kind: graphql.Kind.NAMED_TYPE,
name: {
kind: graphql.Kind.NAME,
value: namedType.name,
},
},
selectionSet: node.selectionSet,
},
],
},
};
}
},
}),
// visitorKeys argument usage a la https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js
// empty keys cannot be removed only because of typescript errors
// will hopefully be fixed in future version of graphql-js to be optional
{
Name: [],
Document: ['definitions'],
OperationDefinition: ['selectionSet'],
VariableDefinition: [],
Variable: [],
SelectionSet: ['selections'],
Field: [],
Argument: [],
FragmentSpread: [],
InlineFragment: ['selectionSet'],
FragmentDefinition: ['selectionSet'],
IntValue: [],
FloatValue: [],
StringValue: [],
BooleanValue: [],
NullValue: [],
EnumValue: [],
ListValue: [],
ObjectValue: [],
ObjectField: [],
Directive: [],
NamedType: [],
ListType: [],
NonNullType: [],
SchemaDefinition: [],
OperationTypeDefinition: [],
ScalarTypeDefinition: [],
ObjectTypeDefinition: [],
FieldDefinition: [],
InputValueDefinition: [],
InterfaceTypeDefinition: [],
UnionTypeDefinition: [],
EnumTypeDefinition: [],
EnumValueDefinition: [],
InputObjectTypeDefinition: [],
DirectiveDefinition: [],
SchemaExtension: [],
ScalarTypeExtension: [],
ObjectTypeExtension: [],
InterfaceTypeExtension: [],
UnionTypeExtension: [],
EnumTypeExtension: [],
InputObjectTypeExtension: [],
});
return newDocument;
}
class FilterToSchema {
transformRequest(originalRequest, delegationContext, _transformationContext) {
return {
...originalRequest,
...filterToSchema(delegationContext.targetSchema, originalRequest.document, originalRequest.variables),
};
}
}
function filterToSchema(targetSchema, document, variables) {
const operations = document.definitions.filter(def => def.kind === graphql.Kind.OPERATION_DEFINITION);
const fragments = document.definitions.filter(def => def.kind === graphql.Kind.FRAGMENT_DEFINITION);
let usedVariables = [];
let usedFragments = [];
const newOperations = [];
let newFragments = [];
const validFragments = fragments.filter((fragment) => {
const typeName = fragment.typeCondition.name.value;
return Boolean(targetSchema.getType(typeName));
});
const validFragmentsWithType = validFragments.reduce((prev, fragment) => ({
...prev,
[fragment.name.value]: targetSchema.getType(fragment.typeCondition.name.value),
}), {});
let fragmentSet = Object.create(null);
operations.forEach((operation) => {
let type;
if (operation.operation === 'subscription') {
type = targetSchema.getSubscriptionType();
}
else if (operation.operation === 'mutation') {
type = targetSchema.getMutationType();
}
else {
type = targetSchema.getQueryType();
}
const { selectionSet, usedFragments: operationUsedFragments, usedVariables: operationUsedVariables, } = filterSelectionSet(targetSchema, type, validFragmentsWithType, operation.selectionSet);
usedFragments = union(usedFragments, operationUsedFragments);
const { usedVariables: collectedUsedVariables, newFragments: collectedNewFragments, fragmentSet: collectedFragmentSet, } = collectFragmentVariables(targetSchema, fragmentSet, validFragments, validFragmentsWithType, usedFragments);
const operationOrFragmentVariables = union(operationUsedVariables, collectedUsedVariables);
usedVariables = union(usedVariables, operationOrFragmentVariables);
newFragments = collectedNewFragments;
fragmentSet = collectedFragmentSet;
const variableDefinitions = operation.variableDefinitions.filter((variable) => operationOrFragmentVariables.indexOf(variable.variable.name.value) !== -1);
newOperations.push({
kind: graphql.Kind.OPERATION_DEFINITION,
operation: operation.operation,
name: operation.name,
directives: operation.directives,
variableDefinitions,
selectionSet,
});
});
const newVariables = usedVariables.reduce((acc, variableName) => {
const variableValue = variables[variableName];
if (variableValue !== undefined) {
acc[variableName] = variableValue;
}
return acc;
}, {});
return {
document: {
kind: graphql.Kind.DOCUMENT,
definitions: [...newOperations, ...newFragments],
},
variables: newVariables,
};
}
function collectFragmentVariables(targetSchema, fragmentSet, validFragments, validFragmentsWithType, usedFragments) {
let remainingFragments = usedFragments.slice();
let usedVariables = [];
const newFragments = [];
while (remainingFragments.length !== 0) {
const nextFragmentName = remainingFragments.pop();
const fragment = validFragments.find(fr => fr.name.value === nextFragmentName);
if (fragment != null) {
const name = nextFragmentName;
const typeName = fragment.typeCondition.name.value;
const type = targetSchema.getType(typeName);
const { selectionSet, usedFragments: fragmentUsedFragments, usedVariables: fragmentUsedVariables, } = filterSelectionSet(targetSchema, type, validFragmentsWithType, fragment.selectionSet);
remainingFragments = union(remainingFragments, fragmentUsedFragments);
usedVariables = union(usedVariables, fragmentUsedVariables);
if (!(name in fragmentSet)) {
fragmentSet[name] = true;
newFragments.push({
kind: graphql.Kind.FRAGMENT_DEFINITION,
name: {
kind: graphql.Kind.NAME,
value: name,
},
typeCondition: fragment.typeCondition,
selectionSet,
});
}
}
}
return {
usedVariables,
newFragments,
fragmentSet,
};
}
function filterSelectionSet(schema, type, validFragments, selectionSet) {
const usedFragments = [];
const usedVariables = [];
const typeInfo = new graphql.TypeInfo(schema, undefined, type);
const filteredSelectionSet = graphql.visit(selectionSet, graphql.visitWithTypeInfo(typeInfo, {
[graphql.Kind.FIELD]: {
enter(node) {
const parentType = typeInfo.getParentType();
if (graphql.isObjectType(parentType) || graphql.isInterfaceType(parentType)) {
const fields = parentType.getFields();
const field = node.name.value === '__typename' ? graphql.TypeNameMetaFieldDef : fields[node.name.value];
if (!field) {
return null;
}
const argNames = (field.args != null ? field.args : []).map(arg => arg.name);
if (node.arguments != null) {
const args = node.arguments.filter((arg) => argNames.indexOf(arg.name.value) !== -1);
if (args.length !== node.arguments.length) {
return {
...node,
arguments: args,
};
}
}
}
},
leave(node) {
const resolvedType = graphql.getNamedType(typeInfo.getType());
if (graphql.isObjectType(resolvedType) || graphql.isInterfaceType(resolvedType)) {
const selections = node.selectionSet != null ? node.selectionSet.selections : null;
if (selections == null || selections.length === 0) {
// need to remove any added variables. Is there a better way to do this?
graphql.visit(node, {
[graphql.Kind.VARIABLE](variableNode) {
const index = usedVariables.indexOf(variableNode.name.value);
if (index !== -1) {
usedVariables.splice(index, 1);
}
},
});
return null;
}
}
},
},
[graphql.Kind.FRAGMENT_SPREAD](node) {
if (node.name.value in validFragments) {
const parentType = typeInfo.getParentType();
const innerType = validFragments[node.name.value];
if (!utils.implementsAbstractType(schema, parentType, innerType)) {
return null;
}
usedFragments.push(node.name.value);
return;
}
return null;
},
[graphql.Kind.INLINE_FRAGMENT]: {
enter(node) {
if (node.typeCondition != null) {
const parentType = typeInfo.getParentType();
const innerType = schema.getType(node.typeCondition.name.value);
if (!utils.implementsAbstractType(schema, parentType, innerType)) {
return null;
}
}
},
},
[graphql.Kind.VARIABLE](node) {
usedVariables.push(node.name.value);
},
}));
return {
selectionSet: filteredSelectionSet,
usedFragments,
usedVariables,
};
}
function union(...arrays) {
const cache = Object.create(null);
const result = [];
arrays.forEach(array => {
array.forEach(item => {
if (!(item in cache)) {
cache[item] = true;
result.push(item);
}
});
});
return result;
}
class AddTypenameToAbstract {
transformRequest(originalRequest, delegationContext, _transformationContext) {
const document = addTypenameToAbstract(delegationContext.targetSchema, originalRequest.document);
return {
...originalRequest,
document,
};
}
}
function addTypenameToAbstract(targetSchema, document) {
const typeInfo = new graphql.TypeInfo(targetSchema);
return graphql.visit(document, graphql.visitWithTypeInfo(typeInfo, {
[graphql.Kind.SELECTION_SET](node) {
const parentType = typeInfo.getParentType();
let selections = node.selections;
if (parentType != null && graphql.isAbstractType(parentType)) {
selections = selections.concat({
kind: graphql.Kind.FIELD,
name: {
kind: graphql.Kind.NAME,
value: '__typename',
},
});
}
if (selections !== node.selections) {
return {
...node,
selections,
};
}
},
}));
}
class CheckResultAndHandleErrors {
transformResult(originalResult, delegationContext, _transformationContext) {
return checkResultAndHandleErrors(originalResult, delegationContext.context != null ? delegationContext.context : {}, delegationContext.info, delegationContext.fieldName, delegationContext.subschema, delegationContext.returnType, delegationContext.skipTypeMerging, delegationContext.onLocatedError);
}
}
function checkResultAndHandleErrors(result, context, info, responseKey = utils.getResponseKeyFromInfo(info), subschema, returnType = info.returnType, skipTypeMerging, onLocatedError) {
const { data, unpathedErrors } = mergeDataAndErrors(result.data == null ? undefined : result.data[responseKey], result.errors == null ? [] : result.errors, info ? graphql.responsePathAsArray(info.path) : undefined, onLocatedError);
return resolveExternalValue(data, unpathedErrors, subschema, context, info, returnType, skipTypeMerging);
}
function mergeDataAndErrors(data, errors, path, onLocatedError, index = 1) {
if (data == null) {
if (!errors.length) {
return { data: null, unpathedErrors: [] };
}
if (errors.length === 1) {
const error = onLocatedError ? onLocatedError(errors[0]) : errors[0];
const newPath = path === undefined ? error.path : error.path === undefined ? path : path.concat(error.path.slice(1));
return { data: utils.relocatedError(errors[0], newPath), unpathedErrors: [] };
}
const newError = graphql.locatedError(new AggregateError(errors), undefined, path);
return { data: newError, unpathedErrors: [] };
}
if (!errors.length) {
return { data, unpathedErrors: [] };
}
let unpathedErrors = [];
const errorMap = Object.create(null);
errors.forEach(error => {
var _a;
const pathSegment = (_a = error.path) === null || _a === void 0 ? void 0 : _a[index];
if (pathSegment != null) {
const pathSegmentErrors = errorMap[pathSegment];
if (pathSegmentErrors === undefined) {
errorMap[pathSegment] = [error];
}
else {
pathSegmentErrors.push(error);
}
}
else {
unpathedErrors.push(error);
}
});
Object.keys(errorMap).forEach(pathSegment => {
if (data[pathSegment] !== undefined) {
const { data: newData, unpathedErrors: newErrors } = mergeDataAndErrors(data[pathSegment], errorMap[pathSegment], path, onLocatedError, index + 1);
data[pathSegment] = newData;
unpathedErrors = unpathedErrors.concat(newErrors);
}
else {
unpathedErrors = unpathedErrors.concat(errorMap[pathSegment]);
}
});
return { data, unpathedErrors };
}
class AddArgumentsAsVariables {
constructor(args) {
this.args = Object.entries(args).reduce((prev, [key, val]) => ({
...prev,
[key]: val,
}), {});
}
transformRequest(originalRequest, delegationContext, _transformationContext) {
const { document, variables } = addVariablesToRootField(delegationContext.targetSchema, originalRequest, this.args);
return {
...originalRequest,
document,
variables,
};
}
}
function addVariablesToRootField(targetSchema, originalRequest, args) {
const document = originalRequest.document;
const variableValues = originalRequest.variables;
const operations = document.definitions.filter(def => def.kind === graphql.Kind.OPERATION_DEFINITION);
const fragments = document.definitions.filter(def => def.kind === graphql.Kind.FRAGMENT_DEFINITION);
const newOperations = operations.map((operation) => {
const variableDefinitionMap = operation.variableDefinitions.reduce((prev, def) => ({
...prev,
[def.variable.name.value]: def,
}), {});
let type;
if (operation.operation === 'subscription') {
type = targetSchema.getSubscriptionType();
}
else if (operation.operation === 'mutation') {
type = targetSchema.getMutationType();
}
else {
type = targetSchema.getQueryType();
}
const newSelectionSet = [];
operation.selectionSet.selections.forEach((selection) => {
var _a;
if (selection.kind === graphql.Kind.FIELD) {
const argumentNodes = (_a = selection.arguments) !== null && _a !== void 0 ? _a : [];
const argumentNodeMap = argumentNodes.reduce((prev, argument) => ({
...prev,
[argument.name.value]: argument,
}), {});
const targetField = type.getFields()[selection.name.value];
// excludes __typename
if (targetField != null) {
updateArguments(targetField, argumentNodeMap, variableDefinitionMap, variableValues, args);
}
newSelectionSet.push({
...selection,
arguments: Object.keys(argumentNodeMap).map(argName => argumentNodeMap[argName]),
});
}
else {
newSelectionSet.push(selection);
}
});
return {
...operation,
variableDefinitions: Object.keys(variableDefinitionMap).map(varName => variableDefinitionMap[varName]),
selectionSet: {
kind: graphql.Kind.SELECTION_SET,
selections: newSelectionSet,
},
};
});
return {
document: {
...document,
definitions: [...newOperations, ...fragments],
},
variables: variableValues,
};
}
function updateArguments(targetField, argumentNodeMap, variableDefinitionMap, variableValues, newArgs) {
targetField.args.forEach((argument) => {
const argName = argument.name;
const argType = argument.type;
if (argName in newArgs) {
utils.updateArgument(argName, argType, argumentNodeMap, variableDefinitionMap, variableValues, utils.serializeInputValue(argType, newArgs[argName]));
}
});
}
function defaultDelegationBinding(delegationContext) {
var _a;
let delegationTransforms = [new CheckResultAndHandleErrors()];
const info = delegationContext.info;
const stitchingInfo = (_a = info === null || info === void 0 ? void 0 : info.schema.extensions) === null || _a === void 0 ? void 0 : _a.stitchingInfo;
if (stitchingInfo != null) {
delegationTransforms = delegationTransforms.concat([
new ExpandAbstractTypes(),
new AddSelectionSets(stitchingInfo.selectionSetsByType, stitchingInfo.selectionSetsByField, stitchingInfo.dynamicSelectionSetsByField),
new WrapConcreteTypes(),
]);
}
else if (info != null) {
delegationTransforms = delegationTransforms.concat([new WrapConcreteTypes(), new ExpandAbstractTypes()]);
}
else {
delegationTransforms.push(new WrapConcreteTypes());
}
const transforms = delegationContext.transforms;
if (transforms != null) {
delegationTransforms = delegationTransforms.concat(transforms.slice().reverse());
}
const args = delegationContext.args;
if (args != null) {
delegationTransforms.push(new AddArgumentsAsVariables(args));
}
delegationTransforms = delegationTransforms.concat([new FilterToSchema(), new AddTypenameToAbstract()]);
return delegationTransforms;
}
class Transformer {
constructor(context, binding = defaultDelegationBinding) {
this.transformations = [];
this.delegationContext = context;
const delegationTransforms = binding(this.delegationContext);
delegationTransforms.forEach(transform => this.addTransform(transform, {}));
}
addTransform(transform, context = {}) {
this.transformations.push({ transform, context });
}
transformRequest(originalRequest) {
return this.transformations.reduce((request, transformation) => transformation.transform.transformRequest != null
? transformation.transform.transformRequest(request, this.delegationContext, transformation.context)
: request, originalRequest);
}
transformResult(originalResult) {
return this.transformations.reduceRight((result, transformation) => transformation.transform.transformResult != null
? transformation.transform.transformResult(result, this.delegationContext, transformation.context)
: result, originalResult);
}
}
function delegateToSchema(options) {
const { info, operationName, operation = getDelegatingOperation(info.parentType, info.schema), fieldName = info.fieldName, returnType = info.returnType, selectionSet, fieldNodes, } = options;
const request = createRequestFromInfo({
info,
operation,
fieldName,
selectionSet,
fieldNodes,
operationName,
});
return delegateRequest({
...options,
request,
operation,
fieldName,
returnType,
});
}
function getDelegationReturnType(targetSchema, operation, fieldName) {
let rootType;
if (operation === 'query') {
rootType = targetSchema.getQueryType();
}
else if (operation === 'mutation') {
rootType = targetSchema.getMutationType();
}
else {
rootType = targetSchema.getSubscriptionType();
}
return rootType.getFields()[fieldName].type;
}
function delegateRequest({ request, schema: subschemaOrSubschemaConfig, rootValue, info, operation, fieldName, args, returnType, onLocatedError, context, transforms = [], transformedSchema, skipValidation, skipTypeMerging, binding, }) {
var _a, _b, _c;
let operationDefinition;
let targetOperation;
let targetFieldName;
if (operation == null) {
operationDefinition = graphql.getOperationAST(request.document, undefined);
targetOperation = operationDefinition.operation;
}
else {
targetOperation = operation;
}
if (fieldName == null) {
operationDefinition = operationDefinition !== null && operationDefinition !== void 0 ? operationDefinition : graphql.getOperationAST(request.document, undefined);
targetFieldName = operationDefinition.selectionSet.selections[0].name.value;
}
else {
targetFieldName = fieldName;
}
const { targetSchema, targetRootValue, subschemaConfig, allTransforms } = collectTargetParameters(subschemaOrSubschemaConfig, rootValue, info, transforms);
const delegationContext = {
subschema: subschemaOrSubschemaConfig,
targetSchema,
operation: targetOperation,
fieldName: targetFieldName,
args,
context,
info,
returnType: (_a = returnType !== null && returnType !== void 0 ? returnType : info === null || info === void 0 ? void 0 : info.returnType) !== null && _a !== void 0 ? _a : getDelegationReturnType(targetSchema, targetOperation, targetFieldName),
onLocatedError,
transforms: allTransforms,
transformedSchema: (_c = transformedSchema !== null && transformedSchema !== void 0 ? transformedSchema : (_b = subschemaConfig) === null || _b === void 0 ? void 0 : _b.transformedSchema) !== null && _c !== void 0 ? _c : targetSchema,
skipTypeMerging,
};
const transformer = new Transformer(delegationContext, binding);
const processedRequest = transformer.transformRequest(request);
if (!skipValidation) {
validateRequest(targetSchema, processedRequest.document);
}
if (targetOperation === 'query' || targetOperation === 'mutation') {
let executor = (subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.executor) || createDefaultExecutor(targetSchema, (subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.rootValue) || targetRootValue);
if (subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.batch) {
const batchingOptions = subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.batchingOptions;
executor = batchExecute.getBatchingExecutor(context, executor, batchingOptions === null || batchingOptions === void 0 ? void 0 : batchingOptions.dataLoaderOptions, batchingOptions === null || batchingOptions === void 0 ? void 0 : batchingOptions.extensionsReducer);
}
const executionResult = executor({
...processedRequest,
context,
info,
});
if (isPromise(executionResult)) {
return executionResult.then(originalResult => {
return transformer.transformResult(originalResult);
});
}
return transformer.transformResult(executionResult);
}
const subscriber = (subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.subscriber) || createDefaultSubscriber(targetSchema, (subschemaConfig === null || subschemaConfig === void 0 ? void 0 : subschemaConfig.rootValue) || targetRootValue);
return subscriber({
...processedRequest,
context,
info,
}).then((subscriptionResult) => {
if (Symbol.asyncIterator in subscriptionResult) {
// "subscribe" to the subscription result and map the result through the transforms
return utils.mapAsyncIterator(subscriptionResult, originalResult => ({
[targetFieldName]: transformer.transformResult(originalResult),
}));
}
return transformer.transformResult(subscriptionResult);
});
}
const emptyObject = {};
function collectTargetParameters(subschema, rootValue, info, transforms = []) {
var _a, _b, _c, _d, _e;
const stitchingInfo = (_a = info === null || info === void 0 ? void 0 : info.schema.extensions) === null || _a === void 0 ? void 0 : _a.stitchingInfo;
const subschemaOrSubschemaConfig = (_b = stitchingInfo === null || stitchingInfo === void 0 ? void 0 : stitchingInfo.subschemaMap.get(subschema)) !== null && _b !== void 0 ? _b : subschema;
if (isSubschemaConfig(subschemaOrSubschemaConfig)) {
return {
targetSchema: subschemaOrSubschemaConfig.schema,
targetRootValue: (_d = (_c = rootValue !== null && rootValue !== void 0 ? rootValue : subschemaOrSubschemaConfig === null || subschemaOrSubschemaConfig === void 0 ? void 0 : subschemaOrSubschemaConfig.rootValue) !== null && _c !== void 0 ? _c : info === null || info === void 0 ? void 0 : info.rootValue) !== null && _d !== void 0 ? _d : emptyObject,
subschemaConfig: subschemaOrSubschemaConfig,
allTransforms: subschemaOrSubschemaConfig.transforms != null
? subschemaOrSubschemaConfig.transforms.concat(transforms)
: transforms,
};
}
return {
targetSchema: subschemaOrSubschemaConfig,
targetRootValue: (_e = rootValue !== null && rootValue !== void 0 ? rootValue : info === null || info === void 0 ? void 0 : info.rootValue) !== null && _e !== void 0 ? _e : emptyObject,
allTransforms: transforms,
};
}
function validateRequest(targetSchema, document) {
const errors = graphql.validate(targetSchema, document);
if (errors.length > 0) {
if (errors.length > 1) {
const combinedError = new AggregateError(errors);
throw combinedError;
}
const error = errors[0];
throw error.originalError || error;
}
}
const createDefaultExecutor = memoize2(function (schema, rootValue) {
return (({ document, context, variables, info }) => graphql.execute({
schema,
document,
contextValue: context,
variableValues: variables,
rootValue: rootValue !== null && rootValue !== void 0 ? rootValue : info === null || info === void 0 ? void 0 : info.rootValue,
}));
});
function createDefaultSubscriber(schema, rootValue) {
return ({ document, context, variables, info }) => graphql.subscribe({
schema,
document,
contextValue: context,
variableValues: variables,
rootValue: rootValue !== null && rootValue !== void 0 ? rootValue : info === null || info === void 0 ? void 0 : info.rootValue,
});
}
exports.AddArgumentsAsVariables = AddArgumentsAsVariables;
exports.AddSelectionSets = AddSelectionSets;
exports.AddTypenameToAbstract = AddTypenameToAbstract;
exports.CheckResultAndHandleErrors = CheckResultAndHandleErrors;
exports.ExpandAbstractTypes = ExpandAbstractTypes;
exports.FilterToSchema = FilterToSchema;
exports.Subschema = Subschema;
exports.VisitSelectionSets = VisitSelectionSets;
exports.annotateExternalObject = annotateExternalObject;
exports.applySchemaTransforms = applySchemaTransforms;
exports.checkResultAndHandleErrors = checkResultAndHandleErrors;
exports.cloneSubschemaConfig = cloneSubschemaConfig;
exports.createRequest = createRequest;
exports.createRequestFromInfo = createRequestFromInfo;
exports.defaultDelegationBinding = defaultDelegationBinding;
exports.defaultMergedResolver = defaultMergedResolver;
exports.delegateRequest = delegateRequest;
exports.delegateToSchema = delegateToSchema;
exports.getDelegatingOperation = getDelegatingOperation;
exports.getSubschema = getSubschema;
exports.getUnpathedErrors = getUnpathedErrors;
exports.isExternalObject = isExternalObject;
exports.isSubschema = isSubschema;
exports.isSubschemaConfig = isSubschemaConfig;
exports.mergeExternalObjects = mergeExternalObjects;
exports.resolveExternalValue = resolveExternalValue;
//# sourceMappingURL=index.cjs.js.map