12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037 |
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true,
- });
- exports.assertValidExecutionArguments = assertValidExecutionArguments;
- exports.buildExecutionContext = buildExecutionContext;
- exports.buildResolveInfo = buildResolveInfo;
- exports.defaultTypeResolver = exports.defaultFieldResolver = void 0;
- exports.execute = execute;
- exports.executeSync = executeSync;
- exports.getFieldDef = getFieldDef;
- var _devAssert = require('../jsutils/devAssert.js');
- var _inspect = require('../jsutils/inspect.js');
- var _invariant = require('../jsutils/invariant.js');
- var _isIterableObject = require('../jsutils/isIterableObject.js');
- var _isObjectLike = require('../jsutils/isObjectLike.js');
- var _isPromise = require('../jsutils/isPromise.js');
- var _memoize = require('../jsutils/memoize3.js');
- var _Path = require('../jsutils/Path.js');
- var _promiseForObject = require('../jsutils/promiseForObject.js');
- var _promiseReduce = require('../jsutils/promiseReduce.js');
- var _GraphQLError = require('../error/GraphQLError.js');
- var _locatedError = require('../error/locatedError.js');
- var _ast = require('../language/ast.js');
- var _kinds = require('../language/kinds.js');
- var _definition = require('../type/definition.js');
- var _introspection = require('../type/introspection.js');
- var _validate = require('../type/validate.js');
- var _collectFields = require('./collectFields.js');
- var _values = require('./values.js');
- /**
- * A memoized collection of relevant subfields with regard to the return
- * type. Memoizing ensures the subfields are not repeatedly calculated, which
- * saves overhead when resolving lists of values.
- */
- const collectSubfields = (0, _memoize.memoize3)(
- (exeContext, returnType, fieldNodes) =>
- (0, _collectFields.collectSubfields)(
- exeContext.schema,
- exeContext.fragments,
- exeContext.variableValues,
- returnType,
- fieldNodes,
- ),
- );
- /**
- * Terminology
- *
- * "Definitions" are the generic name for top-level statements in the document.
- * Examples of this include:
- * 1) Operations (such as a query)
- * 2) Fragments
- *
- * "Operations" are a generic name for requests in the document.
- * Examples of this include:
- * 1) query,
- * 2) mutation
- *
- * "Selections" are the definitions that can appear legally and at
- * single level of the query. These include:
- * 1) field references e.g `a`
- * 2) fragment "spreads" e.g. `...c`
- * 3) inline fragment "spreads" e.g. `...on Type { a }`
- */
- /**
- * Data that must be available at all points during query execution.
- *
- * Namely, schema of the type system that is currently executing,
- * and the fragments defined in the query document
- */
- /**
- * Implements the "Executing requests" section of the GraphQL specification.
- *
- * Returns either a synchronous ExecutionResult (if all encountered resolvers
- * are synchronous), or a Promise of an ExecutionResult that will eventually be
- * resolved and never rejected.
- *
- * If the arguments to this function do not result in a legal execution context,
- * a GraphQLError will be thrown immediately explaining the invalid input.
- */
- function execute(args) {
- // Temporary for v15 to v16 migration. Remove in v17
- arguments.length < 2 ||
- (0, _devAssert.devAssert)(
- false,
- 'graphql@16 dropped long-deprecated support for positional arguments, please pass an object instead.',
- );
- const { schema, document, variableValues, rootValue } = args; // If arguments are missing or incorrect, throw an error.
- assertValidExecutionArguments(schema, document, variableValues); // If a valid execution context cannot be created due to incorrect arguments,
- // a "Response" with only errors is returned.
- const exeContext = buildExecutionContext(args); // Return early errors if execution context failed.
- if (!('schema' in exeContext)) {
- return {
- errors: exeContext,
- };
- } // Return a Promise that will eventually resolve to the data described by
- // The "Response" section of the GraphQL specification.
- //
- // If errors are encountered while executing a GraphQL field, only that
- // field and its descendants will be omitted, and sibling fields will still
- // be executed. An execution which encounters errors will still result in a
- // resolved Promise.
- //
- // Errors from sub-fields of a NonNull type may propagate to the top level,
- // at which point we still log the error and null the parent field, which
- // in this case is the entire response.
- try {
- const { operation } = exeContext;
- const result = executeOperation(exeContext, operation, rootValue);
- if ((0, _isPromise.isPromise)(result)) {
- return result.then(
- (data) => buildResponse(data, exeContext.errors),
- (error) => {
- exeContext.errors.push(error);
- return buildResponse(null, exeContext.errors);
- },
- );
- }
- return buildResponse(result, exeContext.errors);
- } catch (error) {
- exeContext.errors.push(error);
- return buildResponse(null, exeContext.errors);
- }
- }
- /**
- * Also implements the "Executing requests" section of the GraphQL specification.
- * However, it guarantees to complete synchronously (or throw an error) assuming
- * that all field resolvers are also synchronous.
- */
- function executeSync(args) {
- const result = execute(args); // Assert that the execution was synchronous.
- if ((0, _isPromise.isPromise)(result)) {
- throw new Error('GraphQL execution failed to complete synchronously.');
- }
- return result;
- }
- /**
- * Given a completed execution context and data, build the `{ errors, data }`
- * response defined by the "Response" section of the GraphQL specification.
- */
- function buildResponse(data, errors) {
- return errors.length === 0
- ? {
- data,
- }
- : {
- errors,
- data,
- };
- }
- /**
- * Essential assertions before executing to provide developer feedback for
- * improper use of the GraphQL library.
- *
- * @internal
- */
- function assertValidExecutionArguments(schema, document, rawVariableValues) {
- document || (0, _devAssert.devAssert)(false, 'Must provide document.'); // If the schema used for execution is invalid, throw an error.
- (0, _validate.assertValidSchema)(schema); // Variables, if provided, must be an object.
- rawVariableValues == null ||
- (0, _isObjectLike.isObjectLike)(rawVariableValues) ||
- (0, _devAssert.devAssert)(
- false,
- 'Variables must be provided as an Object where each property is a variable value. Perhaps look to see if an unparsed JSON string was provided.',
- );
- }
- /**
- * Constructs a ExecutionContext object from the arguments passed to
- * execute, which we will pass throughout the other execution methods.
- *
- * Throws a GraphQLError if a valid execution context cannot be created.
- *
- * @internal
- */
- function buildExecutionContext(args) {
- var _definition$name, _operation$variableDe;
- const {
- schema,
- document,
- rootValue,
- contextValue,
- variableValues: rawVariableValues,
- operationName,
- fieldResolver,
- typeResolver,
- subscribeFieldResolver,
- } = args;
- let operation;
- const fragments = Object.create(null);
- for (const definition of document.definitions) {
- switch (definition.kind) {
- case _kinds.Kind.OPERATION_DEFINITION:
- if (operationName == null) {
- if (operation !== undefined) {
- return [
- new _GraphQLError.GraphQLError(
- 'Must provide operation name if query contains multiple operations.',
- ),
- ];
- }
- operation = definition;
- } else if (
- ((_definition$name = definition.name) === null ||
- _definition$name === void 0
- ? void 0
- : _definition$name.value) === operationName
- ) {
- operation = definition;
- }
- break;
- case _kinds.Kind.FRAGMENT_DEFINITION:
- fragments[definition.name.value] = definition;
- break;
- default: // ignore non-executable definitions
- }
- }
- if (!operation) {
- if (operationName != null) {
- return [
- new _GraphQLError.GraphQLError(
- `Unknown operation named "${operationName}".`,
- ),
- ];
- }
- return [new _GraphQLError.GraphQLError('Must provide an operation.')];
- } // FIXME: https://github.com/graphql/graphql-js/issues/2203
- /* c8 ignore next */
- const variableDefinitions =
- (_operation$variableDe = operation.variableDefinitions) !== null &&
- _operation$variableDe !== void 0
- ? _operation$variableDe
- : [];
- const coercedVariableValues = (0, _values.getVariableValues)(
- schema,
- variableDefinitions,
- rawVariableValues !== null && rawVariableValues !== void 0
- ? rawVariableValues
- : {},
- {
- maxErrors: 50,
- },
- );
- if (coercedVariableValues.errors) {
- return coercedVariableValues.errors;
- }
- return {
- schema,
- fragments,
- rootValue,
- contextValue,
- operation,
- variableValues: coercedVariableValues.coerced,
- fieldResolver:
- fieldResolver !== null && fieldResolver !== void 0
- ? fieldResolver
- : defaultFieldResolver,
- typeResolver:
- typeResolver !== null && typeResolver !== void 0
- ? typeResolver
- : defaultTypeResolver,
- subscribeFieldResolver:
- subscribeFieldResolver !== null && subscribeFieldResolver !== void 0
- ? subscribeFieldResolver
- : defaultFieldResolver,
- errors: [],
- };
- }
- /**
- * Implements the "Executing operations" section of the spec.
- */
- function executeOperation(exeContext, operation, rootValue) {
- const rootType = exeContext.schema.getRootType(operation.operation);
- if (rootType == null) {
- throw new _GraphQLError.GraphQLError(
- `Schema is not configured to execute ${operation.operation} operation.`,
- {
- nodes: operation,
- },
- );
- }
- const rootFields = (0, _collectFields.collectFields)(
- exeContext.schema,
- exeContext.fragments,
- exeContext.variableValues,
- rootType,
- operation.selectionSet,
- );
- const path = undefined;
- switch (operation.operation) {
- case _ast.OperationTypeNode.QUERY:
- return executeFields(exeContext, rootType, rootValue, path, rootFields);
- case _ast.OperationTypeNode.MUTATION:
- return executeFieldsSerially(
- exeContext,
- rootType,
- rootValue,
- path,
- rootFields,
- );
- case _ast.OperationTypeNode.SUBSCRIPTION:
- // TODO: deprecate `subscribe` and move all logic here
- // Temporary solution until we finish merging execute and subscribe together
- return executeFields(exeContext, rootType, rootValue, path, rootFields);
- }
- }
- /**
- * Implements the "Executing selection sets" section of the spec
- * for fields that must be executed serially.
- */
- function executeFieldsSerially(
- exeContext,
- parentType,
- sourceValue,
- path,
- fields,
- ) {
- return (0, _promiseReduce.promiseReduce)(
- fields.entries(),
- (results, [responseName, fieldNodes]) => {
- const fieldPath = (0, _Path.addPath)(path, responseName, parentType.name);
- const result = executeField(
- exeContext,
- parentType,
- sourceValue,
- fieldNodes,
- fieldPath,
- );
- if (result === undefined) {
- return results;
- }
- if ((0, _isPromise.isPromise)(result)) {
- return result.then((resolvedResult) => {
- results[responseName] = resolvedResult;
- return results;
- });
- }
- results[responseName] = result;
- return results;
- },
- Object.create(null),
- );
- }
- /**
- * Implements the "Executing selection sets" section of the spec
- * for fields that may be executed in parallel.
- */
- function executeFields(exeContext, parentType, sourceValue, path, fields) {
- const results = Object.create(null);
- let containsPromise = false;
- try {
- for (const [responseName, fieldNodes] of fields.entries()) {
- const fieldPath = (0, _Path.addPath)(path, responseName, parentType.name);
- const result = executeField(
- exeContext,
- parentType,
- sourceValue,
- fieldNodes,
- fieldPath,
- );
- if (result !== undefined) {
- results[responseName] = result;
- if ((0, _isPromise.isPromise)(result)) {
- containsPromise = true;
- }
- }
- }
- } catch (error) {
- if (containsPromise) {
- // Ensure that any promises returned by other fields are handled, as they may also reject.
- return (0, _promiseForObject.promiseForObject)(results).finally(() => {
- throw error;
- });
- }
- throw error;
- } // If there are no promises, we can just return the object
- if (!containsPromise) {
- return results;
- } // Otherwise, results is a map from field name to the result of resolving that
- // field, which is possibly a promise. Return a promise that will return this
- // same map, but with any promises replaced with the values they resolved to.
- return (0, _promiseForObject.promiseForObject)(results);
- }
- /**
- * Implements the "Executing fields" section of the spec
- * In particular, this function figures out the value that the field returns by
- * calling its resolve function, then calls completeValue to complete promises,
- * serialize scalars, or execute the sub-selection-set for objects.
- */
- function executeField(exeContext, parentType, source, fieldNodes, path) {
- var _fieldDef$resolve;
- const fieldDef = getFieldDef(exeContext.schema, parentType, fieldNodes[0]);
- if (!fieldDef) {
- return;
- }
- const returnType = fieldDef.type;
- const resolveFn =
- (_fieldDef$resolve = fieldDef.resolve) !== null &&
- _fieldDef$resolve !== void 0
- ? _fieldDef$resolve
- : exeContext.fieldResolver;
- const info = buildResolveInfo(
- exeContext,
- fieldDef,
- fieldNodes,
- parentType,
- path,
- ); // Get the resolve function, regardless of if its result is normal or abrupt (error).
- try {
- // Build a JS object of arguments from the field.arguments AST, using the
- // variables scope to fulfill any variable references.
- // TODO: find a way to memoize, in case this field is within a List type.
- const args = (0, _values.getArgumentValues)(
- fieldDef,
- fieldNodes[0],
- exeContext.variableValues,
- ); // The resolve function's optional third argument is a context value that
- // is provided to every resolve function within an execution. It is commonly
- // used to represent an authenticated user, or request-specific caches.
- const contextValue = exeContext.contextValue;
- const result = resolveFn(source, args, contextValue, info);
- let completed;
- if ((0, _isPromise.isPromise)(result)) {
- completed = result.then((resolved) =>
- completeValue(exeContext, returnType, fieldNodes, info, path, resolved),
- );
- } else {
- completed = completeValue(
- exeContext,
- returnType,
- fieldNodes,
- info,
- path,
- result,
- );
- }
- if ((0, _isPromise.isPromise)(completed)) {
- // Note: we don't rely on a `catch` method, but we do expect "thenable"
- // to take a second callback for the error case.
- return completed.then(undefined, (rawError) => {
- const error = (0, _locatedError.locatedError)(
- rawError,
- fieldNodes,
- (0, _Path.pathToArray)(path),
- );
- return handleFieldError(error, returnType, exeContext);
- });
- }
- return completed;
- } catch (rawError) {
- const error = (0, _locatedError.locatedError)(
- rawError,
- fieldNodes,
- (0, _Path.pathToArray)(path),
- );
- return handleFieldError(error, returnType, exeContext);
- }
- }
- /**
- * @internal
- */
- function buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path) {
- // The resolve function's optional fourth argument is a collection of
- // information about the current execution state.
- return {
- fieldName: fieldDef.name,
- fieldNodes,
- returnType: fieldDef.type,
- parentType,
- path,
- schema: exeContext.schema,
- fragments: exeContext.fragments,
- rootValue: exeContext.rootValue,
- operation: exeContext.operation,
- variableValues: exeContext.variableValues,
- };
- }
- function handleFieldError(error, returnType, exeContext) {
- // If the field type is non-nullable, then it is resolved without any
- // protection from errors, however it still properly locates the error.
- if ((0, _definition.isNonNullType)(returnType)) {
- throw error;
- } // Otherwise, error protection is applied, logging the error and resolving
- // a null value for this field if one is encountered.
- exeContext.errors.push(error);
- return null;
- }
- /**
- * Implements the instructions for completeValue as defined in the
- * "Value Completion" section of the spec.
- *
- * If the field type is Non-Null, then this recursively completes the value
- * for the inner type. It throws a field error if that completion returns null,
- * as per the "Nullability" section of the spec.
- *
- * If the field type is a List, then this recursively completes the value
- * for the inner type on each item in the list.
- *
- * If the field type is a Scalar or Enum, ensures the completed value is a legal
- * value of the type by calling the `serialize` method of GraphQL type
- * definition.
- *
- * If the field is an abstract type, determine the runtime type of the value
- * and then complete based on that type
- *
- * Otherwise, the field type expects a sub-selection set, and will complete the
- * value by executing all sub-selections.
- */
- function completeValue(exeContext, returnType, fieldNodes, info, path, result) {
- // If result is an Error, throw a located error.
- if (result instanceof Error) {
- throw result;
- } // If field type is NonNull, complete for inner type, and throw field error
- // if result is null.
- if ((0, _definition.isNonNullType)(returnType)) {
- const completed = completeValue(
- exeContext,
- returnType.ofType,
- fieldNodes,
- info,
- path,
- result,
- );
- if (completed === null) {
- throw new Error(
- `Cannot return null for non-nullable field ${info.parentType.name}.${info.fieldName}.`,
- );
- }
- return completed;
- } // If result value is null or undefined then return null.
- if (result == null) {
- return null;
- } // If field type is List, complete each item in the list with the inner type
- if ((0, _definition.isListType)(returnType)) {
- return completeListValue(
- exeContext,
- returnType,
- fieldNodes,
- info,
- path,
- result,
- );
- } // If field type is a leaf type, Scalar or Enum, serialize to a valid value,
- // returning null if serialization is not possible.
- if ((0, _definition.isLeafType)(returnType)) {
- return completeLeafValue(returnType, result);
- } // If field type is an abstract type, Interface or Union, determine the
- // runtime Object type and complete for that type.
- if ((0, _definition.isAbstractType)(returnType)) {
- return completeAbstractValue(
- exeContext,
- returnType,
- fieldNodes,
- info,
- path,
- result,
- );
- } // If field type is Object, execute and complete all sub-selections.
- if ((0, _definition.isObjectType)(returnType)) {
- return completeObjectValue(
- exeContext,
- returnType,
- fieldNodes,
- info,
- path,
- result,
- );
- }
- /* c8 ignore next 6 */
- // Not reachable, all possible output types have been considered.
- false ||
- (0, _invariant.invariant)(
- false,
- 'Cannot complete value of unexpected output type: ' +
- (0, _inspect.inspect)(returnType),
- );
- }
- /**
- * Complete a list value by completing each item in the list with the
- * inner type
- */
- function completeListValue(
- exeContext,
- returnType,
- fieldNodes,
- info,
- path,
- result,
- ) {
- if (!(0, _isIterableObject.isIterableObject)(result)) {
- throw new _GraphQLError.GraphQLError(
- `Expected Iterable, but did not find one for field "${info.parentType.name}.${info.fieldName}".`,
- );
- } // This is specified as a simple map, however we're optimizing the path
- // where the list contains no Promises by avoiding creating another Promise.
- const itemType = returnType.ofType;
- let containsPromise = false;
- const completedResults = Array.from(result, (item, index) => {
- // No need to modify the info object containing the path,
- // since from here on it is not ever accessed by resolver functions.
- const itemPath = (0, _Path.addPath)(path, index, undefined);
- try {
- let completedItem;
- if ((0, _isPromise.isPromise)(item)) {
- completedItem = item.then((resolved) =>
- completeValue(
- exeContext,
- itemType,
- fieldNodes,
- info,
- itemPath,
- resolved,
- ),
- );
- } else {
- completedItem = completeValue(
- exeContext,
- itemType,
- fieldNodes,
- info,
- itemPath,
- item,
- );
- }
- if ((0, _isPromise.isPromise)(completedItem)) {
- containsPromise = true; // Note: we don't rely on a `catch` method, but we do expect "thenable"
- // to take a second callback for the error case.
- return completedItem.then(undefined, (rawError) => {
- const error = (0, _locatedError.locatedError)(
- rawError,
- fieldNodes,
- (0, _Path.pathToArray)(itemPath),
- );
- return handleFieldError(error, itemType, exeContext);
- });
- }
- return completedItem;
- } catch (rawError) {
- const error = (0, _locatedError.locatedError)(
- rawError,
- fieldNodes,
- (0, _Path.pathToArray)(itemPath),
- );
- return handleFieldError(error, itemType, exeContext);
- }
- });
- return containsPromise ? Promise.all(completedResults) : completedResults;
- }
- /**
- * Complete a Scalar or Enum by serializing to a valid value, returning
- * null if serialization is not possible.
- */
- function completeLeafValue(returnType, result) {
- const serializedResult = returnType.serialize(result);
- if (serializedResult == null) {
- throw new Error(
- `Expected \`${(0, _inspect.inspect)(returnType)}.serialize(${(0,
- _inspect.inspect)(result)})\` to ` +
- `return non-nullable value, returned: ${(0, _inspect.inspect)(
- serializedResult,
- )}`,
- );
- }
- return serializedResult;
- }
- /**
- * Complete a value of an abstract type by determining the runtime object type
- * of that value, then complete the value for that type.
- */
- function completeAbstractValue(
- exeContext,
- returnType,
- fieldNodes,
- info,
- path,
- result,
- ) {
- var _returnType$resolveTy;
- const resolveTypeFn =
- (_returnType$resolveTy = returnType.resolveType) !== null &&
- _returnType$resolveTy !== void 0
- ? _returnType$resolveTy
- : exeContext.typeResolver;
- const contextValue = exeContext.contextValue;
- const runtimeType = resolveTypeFn(result, contextValue, info, returnType);
- if ((0, _isPromise.isPromise)(runtimeType)) {
- return runtimeType.then((resolvedRuntimeType) =>
- completeObjectValue(
- exeContext,
- ensureValidRuntimeType(
- resolvedRuntimeType,
- exeContext,
- returnType,
- fieldNodes,
- info,
- result,
- ),
- fieldNodes,
- info,
- path,
- result,
- ),
- );
- }
- return completeObjectValue(
- exeContext,
- ensureValidRuntimeType(
- runtimeType,
- exeContext,
- returnType,
- fieldNodes,
- info,
- result,
- ),
- fieldNodes,
- info,
- path,
- result,
- );
- }
- function ensureValidRuntimeType(
- runtimeTypeName,
- exeContext,
- returnType,
- fieldNodes,
- info,
- result,
- ) {
- if (runtimeTypeName == null) {
- throw new _GraphQLError.GraphQLError(
- `Abstract type "${returnType.name}" must resolve to an Object type at runtime for field "${info.parentType.name}.${info.fieldName}". Either the "${returnType.name}" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.`,
- fieldNodes,
- );
- } // releases before 16.0.0 supported returning `GraphQLObjectType` from `resolveType`
- // TODO: remove in 17.0.0 release
- if ((0, _definition.isObjectType)(runtimeTypeName)) {
- throw new _GraphQLError.GraphQLError(
- 'Support for returning GraphQLObjectType from resolveType was removed in graphql-js@16.0.0 please return type name instead.',
- );
- }
- if (typeof runtimeTypeName !== 'string') {
- throw new _GraphQLError.GraphQLError(
- `Abstract type "${returnType.name}" must resolve to an Object type at runtime for field "${info.parentType.name}.${info.fieldName}" with ` +
- `value ${(0, _inspect.inspect)(result)}, received "${(0,
- _inspect.inspect)(runtimeTypeName)}".`,
- );
- }
- const runtimeType = exeContext.schema.getType(runtimeTypeName);
- if (runtimeType == null) {
- throw new _GraphQLError.GraphQLError(
- `Abstract type "${returnType.name}" was resolved to a type "${runtimeTypeName}" that does not exist inside the schema.`,
- {
- nodes: fieldNodes,
- },
- );
- }
- if (!(0, _definition.isObjectType)(runtimeType)) {
- throw new _GraphQLError.GraphQLError(
- `Abstract type "${returnType.name}" was resolved to a non-object type "${runtimeTypeName}".`,
- {
- nodes: fieldNodes,
- },
- );
- }
- if (!exeContext.schema.isSubType(returnType, runtimeType)) {
- throw new _GraphQLError.GraphQLError(
- `Runtime Object type "${runtimeType.name}" is not a possible type for "${returnType.name}".`,
- {
- nodes: fieldNodes,
- },
- );
- }
- return runtimeType;
- }
- /**
- * Complete an Object value by executing all sub-selections.
- */
- function completeObjectValue(
- exeContext,
- returnType,
- fieldNodes,
- info,
- path,
- result,
- ) {
- // Collect sub-fields to execute to complete this value.
- const subFieldNodes = collectSubfields(exeContext, returnType, fieldNodes); // If there is an isTypeOf predicate function, call it with the
- // current result. If isTypeOf returns false, then raise an error rather
- // than continuing execution.
- if (returnType.isTypeOf) {
- const isTypeOf = returnType.isTypeOf(result, exeContext.contextValue, info);
- if ((0, _isPromise.isPromise)(isTypeOf)) {
- return isTypeOf.then((resolvedIsTypeOf) => {
- if (!resolvedIsTypeOf) {
- throw invalidReturnTypeError(returnType, result, fieldNodes);
- }
- return executeFields(
- exeContext,
- returnType,
- result,
- path,
- subFieldNodes,
- );
- });
- }
- if (!isTypeOf) {
- throw invalidReturnTypeError(returnType, result, fieldNodes);
- }
- }
- return executeFields(exeContext, returnType, result, path, subFieldNodes);
- }
- function invalidReturnTypeError(returnType, result, fieldNodes) {
- return new _GraphQLError.GraphQLError(
- `Expected value of type "${returnType.name}" but got: ${(0,
- _inspect.inspect)(result)}.`,
- {
- nodes: fieldNodes,
- },
- );
- }
- /**
- * If a resolveType function is not given, then a default resolve behavior is
- * used which attempts two strategies:
- *
- * First, See if the provided value has a `__typename` field defined, if so, use
- * that value as name of the resolved type.
- *
- * Otherwise, test each possible type for the abstract type by calling
- * isTypeOf for the object being coerced, returning the first type that matches.
- */
- const defaultTypeResolver = function (value, contextValue, info, abstractType) {
- // First, look for `__typename`.
- if (
- (0, _isObjectLike.isObjectLike)(value) &&
- typeof value.__typename === 'string'
- ) {
- return value.__typename;
- } // Otherwise, test each possible type.
- const possibleTypes = info.schema.getPossibleTypes(abstractType);
- const promisedIsTypeOfResults = [];
- for (let i = 0; i < possibleTypes.length; i++) {
- const type = possibleTypes[i];
- if (type.isTypeOf) {
- const isTypeOfResult = type.isTypeOf(value, contextValue, info);
- if ((0, _isPromise.isPromise)(isTypeOfResult)) {
- promisedIsTypeOfResults[i] = isTypeOfResult;
- } else if (isTypeOfResult) {
- return type.name;
- }
- }
- }
- if (promisedIsTypeOfResults.length) {
- return Promise.all(promisedIsTypeOfResults).then((isTypeOfResults) => {
- for (let i = 0; i < isTypeOfResults.length; i++) {
- if (isTypeOfResults[i]) {
- return possibleTypes[i].name;
- }
- }
- });
- }
- };
- /**
- * If a resolve function is not given, then a default resolve behavior is used
- * which takes the property of the source object of the same name as the field
- * and returns it as the result, or if it's a function, returns the result
- * of calling that function while passing along args and context value.
- */
- exports.defaultTypeResolver = defaultTypeResolver;
- const defaultFieldResolver = function (source, args, contextValue, info) {
- // ensure source is a value for which property access is acceptable.
- if ((0, _isObjectLike.isObjectLike)(source) || typeof source === 'function') {
- const property = source[info.fieldName];
- if (typeof property === 'function') {
- return source[info.fieldName](args, contextValue, info);
- }
- return property;
- }
- };
- /**
- * This method looks up the field on the given type definition.
- * It has special casing for the three introspection fields,
- * __schema, __type and __typename. __typename is special because
- * it can always be queried as a field, even in situations where no
- * other fields are allowed, like on a Union. __schema and __type
- * could get automatically added to the query type, but that would
- * require mutating type definitions, which would cause issues.
- *
- * @internal
- */
- exports.defaultFieldResolver = defaultFieldResolver;
- function getFieldDef(schema, parentType, fieldNode) {
- const fieldName = fieldNode.name.value;
- if (
- fieldName === _introspection.SchemaMetaFieldDef.name &&
- schema.getQueryType() === parentType
- ) {
- return _introspection.SchemaMetaFieldDef;
- } else if (
- fieldName === _introspection.TypeMetaFieldDef.name &&
- schema.getQueryType() === parentType
- ) {
- return _introspection.TypeMetaFieldDef;
- } else if (fieldName === _introspection.TypeNameMetaFieldDef.name) {
- return _introspection.TypeNameMetaFieldDef;
- }
- return parentType.getFields()[fieldName];
- }
|