UNPKG

@graphql-tools/delegate

Version:

A set of utils for faster development of GraphQL tools

90 lines (89 loc) 4.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveExternalValue = void 0; const graphql_1 = require("graphql"); const utils_1 = require("@graphql-tools/utils"); const mergeFields_js_1 = require("./mergeFields.js"); function resolveExternalValue(result, unpathedErrors, subschema, context, info, returnType = getReturnType(info), skipTypeMerging) { const type = (0, graphql_1.getNullableType)(returnType); if (result instanceof Error) { return result; } if (result == null) { return reportUnpathedErrorsViaNull(unpathedErrors); } if ('parseValue' in type) { return type.parseValue(result); } else if ((0, graphql_1.isCompositeType)(type)) { return resolveExternalObject(type, result, unpathedErrors, subschema, context, info, skipTypeMerging); } else if ((0, graphql_1.isListType)(type)) { if (Array.isArray(result)) { return resolveExternalList(type, result, unpathedErrors, subschema, context, info, skipTypeMerging); } return resolveExternalValue(result, unpathedErrors, subschema, context, info, type.ofType, skipTypeMerging); } } exports.resolveExternalValue = resolveExternalValue; 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 (!(0, mergeFields_js_1.isExternalObject)(object)) { (0, mergeFields_js_1.annotateExternalObject)(object, unpathedErrors, subschema, Object.create(null)); } if (skipTypeMerging || info == null) { return object; } const stitchingInfo = (_a = info.schema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo']; if (stitchingInfo == null) { return object; } const typeName = (0, graphql_1.isAbstractType)(type) ? object.__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 || !targetSubschemas.length) { return object; } return (0, mergeFields_js_1.mergeFields)(mergedTypeInfo, object, subschema, context, info); } function resolveExternalList(type, list, unpathedErrors, subschema, context, info, skipTypeMerging) { return list.map(listMember => resolveExternalValue(listMember, unpathedErrors, subschema, context, info, type.ofType, skipTypeMerging)); } const reportedErrors = new WeakMap(); function reportUnpathedErrorsViaNull(unpathedErrors) { if (unpathedErrors.length) { const unreportedErrors = []; for (const error of unpathedErrors) { if (!reportedErrors.has(error)) { unreportedErrors.push(error); reportedErrors.set(error, true); } } if (unreportedErrors.length) { if (unreportedErrors.length === 1) { return unreportedErrors[0]; } const combinedError = new utils_1.AggregateError(unreportedErrors, unreportedErrors.map(error => error.message).join(', \n')); // We cast path as any for GraphQL.js 14 compat // locatedError path argument must be defined, but it is just forwarded to a constructor that allows a undefined value // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/locatedError.js#L25 // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/GraphQLError.js#L19 return (0, graphql_1.locatedError)(combinedError, undefined, unreportedErrors[0].path); } } return null; } function getReturnType(info) { if (info == null) { throw new Error(`Return type cannot be inferred without a source schema.`); } return info.returnType; }