execute.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.execute = execute;
  6. exports.executeSync = executeSync;
  7. exports.assertValidExecutionArguments = assertValidExecutionArguments;
  8. exports.buildExecutionContext = buildExecutionContext;
  9. exports.collectFields = collectFields;
  10. exports.buildResolveInfo = buildResolveInfo;
  11. exports.resolveFieldValueOrError = resolveFieldValueOrError;
  12. exports.getFieldDef = getFieldDef;
  13. exports.defaultFieldResolver = exports.defaultTypeResolver = void 0;
  14. var _arrayFrom = _interopRequireDefault(require("../polyfills/arrayFrom"));
  15. var _inspect = _interopRequireDefault(require("../jsutils/inspect"));
  16. var _memoize = _interopRequireDefault(require("../jsutils/memoize3"));
  17. var _invariant = _interopRequireDefault(require("../jsutils/invariant"));
  18. var _devAssert = _interopRequireDefault(require("../jsutils/devAssert"));
  19. var _isPromise = _interopRequireDefault(require("../jsutils/isPromise"));
  20. var _isObjectLike = _interopRequireDefault(require("../jsutils/isObjectLike"));
  21. var _isCollection = _interopRequireDefault(require("../jsutils/isCollection"));
  22. var _promiseReduce = _interopRequireDefault(require("../jsutils/promiseReduce"));
  23. var _promiseForObject = _interopRequireDefault(require("../jsutils/promiseForObject"));
  24. var _Path = require("../jsutils/Path");
  25. var _GraphQLError = require("../error/GraphQLError");
  26. var _locatedError = require("../error/locatedError");
  27. var _kinds = require("../language/kinds");
  28. var _validate = require("../type/validate");
  29. var _introspection = require("../type/introspection");
  30. var _directives = require("../type/directives");
  31. var _definition = require("../type/definition");
  32. var _typeFromAST = require("../utilities/typeFromAST");
  33. var _getOperationRootType = require("../utilities/getOperationRootType");
  34. var _values = require("./values");
  35. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  36. function execute(argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) {
  37. /* eslint-enable no-redeclare */
  38. // Extract arguments from object args if provided.
  39. return arguments.length === 1 ? executeImpl(argsOrSchema) : executeImpl({
  40. schema: argsOrSchema,
  41. document: document,
  42. rootValue: rootValue,
  43. contextValue: contextValue,
  44. variableValues: variableValues,
  45. operationName: operationName,
  46. fieldResolver: fieldResolver,
  47. typeResolver: typeResolver
  48. });
  49. }
  50. /**
  51. * Also implements the "Evaluating requests" section of the GraphQL specification.
  52. * However, it guarantees to complete synchronously (or throw an error) assuming
  53. * that all field resolvers are also synchronous.
  54. */
  55. function executeSync(args) {
  56. var result = executeImpl(args); // Assert that the execution was synchronous.
  57. if ((0, _isPromise.default)(result)) {
  58. throw new Error('GraphQL execution failed to complete synchronously.');
  59. }
  60. return result;
  61. }
  62. function executeImpl(args) {
  63. var schema = args.schema,
  64. document = args.document,
  65. rootValue = args.rootValue,
  66. contextValue = args.contextValue,
  67. variableValues = args.variableValues,
  68. operationName = args.operationName,
  69. fieldResolver = args.fieldResolver,
  70. typeResolver = args.typeResolver; // If arguments are missing or incorrect, throw an error.
  71. assertValidExecutionArguments(schema, document, variableValues); // If a valid execution context cannot be created due to incorrect arguments,
  72. // a "Response" with only errors is returned.
  73. var exeContext = buildExecutionContext(schema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver); // Return early errors if execution context failed.
  74. if (Array.isArray(exeContext)) {
  75. return {
  76. errors: exeContext
  77. };
  78. } // Return a Promise that will eventually resolve to the data described by
  79. // The "Response" section of the GraphQL specification.
  80. //
  81. // If errors are encountered while executing a GraphQL field, only that
  82. // field and its descendants will be omitted, and sibling fields will still
  83. // be executed. An execution which encounters errors will still result in a
  84. // resolved Promise.
  85. var data = executeOperation(exeContext, exeContext.operation, rootValue);
  86. return buildResponse(exeContext, data);
  87. }
  88. /**
  89. * Given a completed execution context and data, build the { errors, data }
  90. * response defined by the "Response" section of the GraphQL specification.
  91. */
  92. function buildResponse(exeContext, data) {
  93. if ((0, _isPromise.default)(data)) {
  94. return data.then(function (resolved) {
  95. return buildResponse(exeContext, resolved);
  96. });
  97. }
  98. return exeContext.errors.length === 0 ? {
  99. data: data
  100. } : {
  101. errors: exeContext.errors,
  102. data: data
  103. };
  104. }
  105. /**
  106. * Essential assertions before executing to provide developer feedback for
  107. * improper use of the GraphQL library.
  108. *
  109. * @internal
  110. */
  111. function assertValidExecutionArguments(schema, document, rawVariableValues) {
  112. document || (0, _devAssert.default)(0, 'Must provide document.'); // If the schema used for execution is invalid, throw an error.
  113. (0, _validate.assertValidSchema)(schema); // Variables, if provided, must be an object.
  114. rawVariableValues == null || (0, _isObjectLike.default)(rawVariableValues) || (0, _devAssert.default)(0, '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.');
  115. }
  116. /**
  117. * Constructs a ExecutionContext object from the arguments passed to
  118. * execute, which we will pass throughout the other execution methods.
  119. *
  120. * Throws a GraphQLError if a valid execution context cannot be created.
  121. *
  122. * @internal
  123. */
  124. function buildExecutionContext(schema, document, rootValue, contextValue, rawVariableValues, operationName, fieldResolver, typeResolver) {
  125. var _definition$name, _operation$variableDe;
  126. var operation;
  127. var fragments = Object.create(null);
  128. for (var _i2 = 0, _document$definitions2 = document.definitions; _i2 < _document$definitions2.length; _i2++) {
  129. var definition = _document$definitions2[_i2];
  130. switch (definition.kind) {
  131. case _kinds.Kind.OPERATION_DEFINITION:
  132. if (operationName == null) {
  133. if (operation !== undefined) {
  134. return [new _GraphQLError.GraphQLError('Must provide operation name if query contains multiple operations.')];
  135. }
  136. operation = definition;
  137. } else if (((_definition$name = definition.name) === null || _definition$name === void 0 ? void 0 : _definition$name.value) === operationName) {
  138. operation = definition;
  139. }
  140. break;
  141. case _kinds.Kind.FRAGMENT_DEFINITION:
  142. fragments[definition.name.value] = definition;
  143. break;
  144. }
  145. }
  146. if (!operation) {
  147. if (operationName != null) {
  148. return [new _GraphQLError.GraphQLError("Unknown operation named \"".concat(operationName, "\"."))];
  149. }
  150. return [new _GraphQLError.GraphQLError('Must provide an operation.')];
  151. } // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
  152. var variableDefinitions = (_operation$variableDe = operation.variableDefinitions) !== null && _operation$variableDe !== void 0 ? _operation$variableDe : [];
  153. var coercedVariableValues = (0, _values.getVariableValues)(schema, variableDefinitions, rawVariableValues !== null && rawVariableValues !== void 0 ? rawVariableValues : {}, {
  154. maxErrors: 50
  155. });
  156. if (coercedVariableValues.errors) {
  157. return coercedVariableValues.errors;
  158. }
  159. return {
  160. schema: schema,
  161. fragments: fragments,
  162. rootValue: rootValue,
  163. contextValue: contextValue,
  164. operation: operation,
  165. variableValues: coercedVariableValues.coerced,
  166. fieldResolver: fieldResolver !== null && fieldResolver !== void 0 ? fieldResolver : defaultFieldResolver,
  167. typeResolver: typeResolver !== null && typeResolver !== void 0 ? typeResolver : defaultTypeResolver,
  168. errors: []
  169. };
  170. }
  171. /**
  172. * Implements the "Evaluating operations" section of the spec.
  173. */
  174. function executeOperation(exeContext, operation, rootValue) {
  175. var type = (0, _getOperationRootType.getOperationRootType)(exeContext.schema, operation);
  176. var fields = collectFields(exeContext, type, operation.selectionSet, Object.create(null), Object.create(null));
  177. var path = undefined; // Errors from sub-fields of a NonNull type may propagate to the top level,
  178. // at which point we still log the error and null the parent field, which
  179. // in this case is the entire response.
  180. //
  181. // Similar to completeValueCatchingError.
  182. try {
  183. var result = operation.operation === 'mutation' ? executeFieldsSerially(exeContext, type, rootValue, path, fields) : executeFields(exeContext, type, rootValue, path, fields);
  184. if ((0, _isPromise.default)(result)) {
  185. return result.then(undefined, function (error) {
  186. exeContext.errors.push(error);
  187. return Promise.resolve(null);
  188. });
  189. }
  190. return result;
  191. } catch (error) {
  192. exeContext.errors.push(error);
  193. return null;
  194. }
  195. }
  196. /**
  197. * Implements the "Evaluating selection sets" section of the spec
  198. * for "write" mode.
  199. */
  200. function executeFieldsSerially(exeContext, parentType, sourceValue, path, fields) {
  201. return (0, _promiseReduce.default)(Object.keys(fields), function (results, responseName) {
  202. var fieldNodes = fields[responseName];
  203. var fieldPath = (0, _Path.addPath)(path, responseName, parentType.name);
  204. var result = resolveField(exeContext, parentType, sourceValue, fieldNodes, fieldPath);
  205. if (result === undefined) {
  206. return results;
  207. }
  208. if ((0, _isPromise.default)(result)) {
  209. return result.then(function (resolvedResult) {
  210. results[responseName] = resolvedResult;
  211. return results;
  212. });
  213. }
  214. results[responseName] = result;
  215. return results;
  216. }, Object.create(null));
  217. }
  218. /**
  219. * Implements the "Evaluating selection sets" section of the spec
  220. * for "read" mode.
  221. */
  222. function executeFields(exeContext, parentType, sourceValue, path, fields) {
  223. var results = Object.create(null);
  224. var containsPromise = false;
  225. for (var _i4 = 0, _Object$keys2 = Object.keys(fields); _i4 < _Object$keys2.length; _i4++) {
  226. var responseName = _Object$keys2[_i4];
  227. var fieldNodes = fields[responseName];
  228. var fieldPath = (0, _Path.addPath)(path, responseName, parentType.name);
  229. var result = resolveField(exeContext, parentType, sourceValue, fieldNodes, fieldPath);
  230. if (result !== undefined) {
  231. results[responseName] = result;
  232. if (!containsPromise && (0, _isPromise.default)(result)) {
  233. containsPromise = true;
  234. }
  235. }
  236. } // If there are no promises, we can just return the object
  237. if (!containsPromise) {
  238. return results;
  239. } // Otherwise, results is a map from field name to the result of resolving that
  240. // field, which is possibly a promise. Return a promise that will return this
  241. // same map, but with any promises replaced with the values they resolved to.
  242. return (0, _promiseForObject.default)(results);
  243. }
  244. /**
  245. * Given a selectionSet, adds all of the fields in that selection to
  246. * the passed in map of fields, and returns it at the end.
  247. *
  248. * CollectFields requires the "runtime type" of an object. For a field which
  249. * returns an Interface or Union type, the "runtime type" will be the actual
  250. * Object type returned by that field.
  251. *
  252. * @internal
  253. */
  254. function collectFields(exeContext, runtimeType, selectionSet, fields, visitedFragmentNames) {
  255. for (var _i6 = 0, _selectionSet$selecti2 = selectionSet.selections; _i6 < _selectionSet$selecti2.length; _i6++) {
  256. var selection = _selectionSet$selecti2[_i6];
  257. switch (selection.kind) {
  258. case _kinds.Kind.FIELD:
  259. {
  260. if (!shouldIncludeNode(exeContext, selection)) {
  261. continue;
  262. }
  263. var name = getFieldEntryKey(selection);
  264. if (!fields[name]) {
  265. fields[name] = [];
  266. }
  267. fields[name].push(selection);
  268. break;
  269. }
  270. case _kinds.Kind.INLINE_FRAGMENT:
  271. {
  272. if (!shouldIncludeNode(exeContext, selection) || !doesFragmentConditionMatch(exeContext, selection, runtimeType)) {
  273. continue;
  274. }
  275. collectFields(exeContext, runtimeType, selection.selectionSet, fields, visitedFragmentNames);
  276. break;
  277. }
  278. case _kinds.Kind.FRAGMENT_SPREAD:
  279. {
  280. var fragName = selection.name.value;
  281. if (visitedFragmentNames[fragName] || !shouldIncludeNode(exeContext, selection)) {
  282. continue;
  283. }
  284. visitedFragmentNames[fragName] = true;
  285. var fragment = exeContext.fragments[fragName];
  286. if (!fragment || !doesFragmentConditionMatch(exeContext, fragment, runtimeType)) {
  287. continue;
  288. }
  289. collectFields(exeContext, runtimeType, fragment.selectionSet, fields, visitedFragmentNames);
  290. break;
  291. }
  292. }
  293. }
  294. return fields;
  295. }
  296. /**
  297. * Determines if a field should be included based on the @include and @skip
  298. * directives, where @skip has higher precedence than @include.
  299. */
  300. function shouldIncludeNode(exeContext, node) {
  301. var skip = (0, _values.getDirectiveValues)(_directives.GraphQLSkipDirective, node, exeContext.variableValues);
  302. if ((skip === null || skip === void 0 ? void 0 : skip.if) === true) {
  303. return false;
  304. }
  305. var include = (0, _values.getDirectiveValues)(_directives.GraphQLIncludeDirective, node, exeContext.variableValues);
  306. if ((include === null || include === void 0 ? void 0 : include.if) === false) {
  307. return false;
  308. }
  309. return true;
  310. }
  311. /**
  312. * Determines if a fragment is applicable to the given type.
  313. */
  314. function doesFragmentConditionMatch(exeContext, fragment, type) {
  315. var typeConditionNode = fragment.typeCondition;
  316. if (!typeConditionNode) {
  317. return true;
  318. }
  319. var conditionalType = (0, _typeFromAST.typeFromAST)(exeContext.schema, typeConditionNode);
  320. if (conditionalType === type) {
  321. return true;
  322. }
  323. if ((0, _definition.isAbstractType)(conditionalType)) {
  324. return exeContext.schema.isSubType(conditionalType, type);
  325. }
  326. return false;
  327. }
  328. /**
  329. * Implements the logic to compute the key of a given field's entry
  330. */
  331. function getFieldEntryKey(node) {
  332. return node.alias ? node.alias.value : node.name.value;
  333. }
  334. /**
  335. * Resolves the field on the given source object. In particular, this
  336. * figures out the value that the field returns by calling its resolve function,
  337. * then calls completeValue to complete promises, serialize scalars, or execute
  338. * the sub-selection-set for objects.
  339. */
  340. function resolveField(exeContext, parentType, source, fieldNodes, path) {
  341. var _fieldDef$resolve;
  342. var fieldNode = fieldNodes[0];
  343. var fieldName = fieldNode.name.value;
  344. var fieldDef = getFieldDef(exeContext.schema, parentType, fieldName);
  345. if (!fieldDef) {
  346. return;
  347. }
  348. var resolveFn = (_fieldDef$resolve = fieldDef.resolve) !== null && _fieldDef$resolve !== void 0 ? _fieldDef$resolve : exeContext.fieldResolver;
  349. var info = buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path); // Get the resolve function, regardless of if its result is normal
  350. // or abrupt (error).
  351. var result = resolveFieldValueOrError(exeContext, fieldDef, fieldNodes, resolveFn, source, info);
  352. return completeValueCatchingError(exeContext, fieldDef.type, fieldNodes, info, path, result);
  353. }
  354. /**
  355. * @internal
  356. */
  357. function buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path) {
  358. // The resolve function's optional fourth argument is a collection of
  359. // information about the current execution state.
  360. return {
  361. fieldName: fieldDef.name,
  362. fieldNodes: fieldNodes,
  363. returnType: fieldDef.type,
  364. parentType: parentType,
  365. path: path,
  366. schema: exeContext.schema,
  367. fragments: exeContext.fragments,
  368. rootValue: exeContext.rootValue,
  369. operation: exeContext.operation,
  370. variableValues: exeContext.variableValues
  371. };
  372. }
  373. /**
  374. * Isolates the "ReturnOrAbrupt" behavior to not de-opt the `resolveField`
  375. * function. Returns the result of resolveFn or the abrupt-return Error object.
  376. *
  377. * @internal
  378. */
  379. function resolveFieldValueOrError(exeContext, fieldDef, fieldNodes, resolveFn, source, info) {
  380. try {
  381. // Build a JS object of arguments from the field.arguments AST, using the
  382. // variables scope to fulfill any variable references.
  383. // TODO: find a way to memoize, in case this field is within a List type.
  384. var args = (0, _values.getArgumentValues)(fieldDef, fieldNodes[0], exeContext.variableValues); // The resolve function's optional third argument is a context value that
  385. // is provided to every resolve function within an execution. It is commonly
  386. // used to represent an authenticated user, or request-specific caches.
  387. var _contextValue = exeContext.contextValue;
  388. var result = resolveFn(source, args, _contextValue, info);
  389. return (0, _isPromise.default)(result) ? result.then(undefined, asErrorInstance) : result;
  390. } catch (error) {
  391. return asErrorInstance(error);
  392. }
  393. } // Sometimes a non-error is thrown, wrap it as an Error instance to ensure a
  394. // consistent Error interface.
  395. function asErrorInstance(error) {
  396. if (error instanceof Error) {
  397. return error;
  398. }
  399. return new Error('Unexpected error value: ' + (0, _inspect.default)(error));
  400. } // This is a small wrapper around completeValue which detects and logs errors
  401. // in the execution context.
  402. function completeValueCatchingError(exeContext, returnType, fieldNodes, info, path, result) {
  403. try {
  404. var completed;
  405. if ((0, _isPromise.default)(result)) {
  406. completed = result.then(function (resolved) {
  407. return completeValue(exeContext, returnType, fieldNodes, info, path, resolved);
  408. });
  409. } else {
  410. completed = completeValue(exeContext, returnType, fieldNodes, info, path, result);
  411. }
  412. if ((0, _isPromise.default)(completed)) {
  413. // Note: we don't rely on a `catch` method, but we do expect "thenable"
  414. // to take a second callback for the error case.
  415. return completed.then(undefined, function (error) {
  416. return handleFieldError(error, fieldNodes, path, returnType, exeContext);
  417. });
  418. }
  419. return completed;
  420. } catch (error) {
  421. return handleFieldError(error, fieldNodes, path, returnType, exeContext);
  422. }
  423. }
  424. function handleFieldError(rawError, fieldNodes, path, returnType, exeContext) {
  425. var error = (0, _locatedError.locatedError)(asErrorInstance(rawError), fieldNodes, (0, _Path.pathToArray)(path)); // If the field type is non-nullable, then it is resolved without any
  426. // protection from errors, however it still properly locates the error.
  427. if ((0, _definition.isNonNullType)(returnType)) {
  428. throw error;
  429. } // Otherwise, error protection is applied, logging the error and resolving
  430. // a null value for this field if one is encountered.
  431. exeContext.errors.push(error);
  432. return null;
  433. }
  434. /**
  435. * Implements the instructions for completeValue as defined in the
  436. * "Field entries" section of the spec.
  437. *
  438. * If the field type is Non-Null, then this recursively completes the value
  439. * for the inner type. It throws a field error if that completion returns null,
  440. * as per the "Nullability" section of the spec.
  441. *
  442. * If the field type is a List, then this recursively completes the value
  443. * for the inner type on each item in the list.
  444. *
  445. * If the field type is a Scalar or Enum, ensures the completed value is a legal
  446. * value of the type by calling the `serialize` method of GraphQL type
  447. * definition.
  448. *
  449. * If the field is an abstract type, determine the runtime type of the value
  450. * and then complete based on that type
  451. *
  452. * Otherwise, the field type expects a sub-selection set, and will complete the
  453. * value by evaluating all sub-selections.
  454. */
  455. function completeValue(exeContext, returnType, fieldNodes, info, path, result) {
  456. // If result is an Error, throw a located error.
  457. if (result instanceof Error) {
  458. throw result;
  459. } // If field type is NonNull, complete for inner type, and throw field error
  460. // if result is null.
  461. if ((0, _definition.isNonNullType)(returnType)) {
  462. var completed = completeValue(exeContext, returnType.ofType, fieldNodes, info, path, result);
  463. if (completed === null) {
  464. throw new Error("Cannot return null for non-nullable field ".concat(info.parentType.name, ".").concat(info.fieldName, "."));
  465. }
  466. return completed;
  467. } // If result value is null or undefined then return null.
  468. if (result == null) {
  469. return null;
  470. } // If field type is List, complete each item in the list with the inner type
  471. if ((0, _definition.isListType)(returnType)) {
  472. return completeListValue(exeContext, returnType, fieldNodes, info, path, result);
  473. } // If field type is a leaf type, Scalar or Enum, serialize to a valid value,
  474. // returning null if serialization is not possible.
  475. if ((0, _definition.isLeafType)(returnType)) {
  476. return completeLeafValue(returnType, result);
  477. } // If field type is an abstract type, Interface or Union, determine the
  478. // runtime Object type and complete for that type.
  479. if ((0, _definition.isAbstractType)(returnType)) {
  480. return completeAbstractValue(exeContext, returnType, fieldNodes, info, path, result);
  481. } // If field type is Object, execute and complete all sub-selections.
  482. // istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2618')
  483. if ((0, _definition.isObjectType)(returnType)) {
  484. return completeObjectValue(exeContext, returnType, fieldNodes, info, path, result);
  485. } // istanbul ignore next (Not reachable. All possible output types have been considered)
  486. false || (0, _invariant.default)(0, 'Cannot complete value of unexpected output type: ' + (0, _inspect.default)(returnType));
  487. }
  488. /**
  489. * Complete a list value by completing each item in the list with the
  490. * inner type
  491. */
  492. function completeListValue(exeContext, returnType, fieldNodes, info, path, result) {
  493. if (!(0, _isCollection.default)(result)) {
  494. throw new _GraphQLError.GraphQLError("Expected Iterable, but did not find one for field \"".concat(info.parentType.name, ".").concat(info.fieldName, "\"."));
  495. } // This is specified as a simple map, however we're optimizing the path
  496. // where the list contains no Promises by avoiding creating another Promise.
  497. var itemType = returnType.ofType;
  498. var containsPromise = false;
  499. var completedResults = (0, _arrayFrom.default)(result, function (item, index) {
  500. // No need to modify the info object containing the path,
  501. // since from here on it is not ever accessed by resolver functions.
  502. var fieldPath = (0, _Path.addPath)(path, index, undefined);
  503. var completedItem = completeValueCatchingError(exeContext, itemType, fieldNodes, info, fieldPath, item);
  504. if (!containsPromise && (0, _isPromise.default)(completedItem)) {
  505. containsPromise = true;
  506. }
  507. return completedItem;
  508. });
  509. return containsPromise ? Promise.all(completedResults) : completedResults;
  510. }
  511. /**
  512. * Complete a Scalar or Enum by serializing to a valid value, returning
  513. * null if serialization is not possible.
  514. */
  515. function completeLeafValue(returnType, result) {
  516. var serializedResult = returnType.serialize(result);
  517. if (serializedResult === undefined) {
  518. throw new Error("Expected a value of type \"".concat((0, _inspect.default)(returnType), "\" but ") + "received: ".concat((0, _inspect.default)(result)));
  519. }
  520. return serializedResult;
  521. }
  522. /**
  523. * Complete a value of an abstract type by determining the runtime object type
  524. * of that value, then complete the value for that type.
  525. */
  526. function completeAbstractValue(exeContext, returnType, fieldNodes, info, path, result) {
  527. var _returnType$resolveTy;
  528. var resolveTypeFn = (_returnType$resolveTy = returnType.resolveType) !== null && _returnType$resolveTy !== void 0 ? _returnType$resolveTy : exeContext.typeResolver;
  529. var contextValue = exeContext.contextValue;
  530. var runtimeType = resolveTypeFn(result, contextValue, info, returnType);
  531. if ((0, _isPromise.default)(runtimeType)) {
  532. return runtimeType.then(function (resolvedRuntimeType) {
  533. return completeObjectValue(exeContext, ensureValidRuntimeType(resolvedRuntimeType, exeContext, returnType, fieldNodes, info, result), fieldNodes, info, path, result);
  534. });
  535. }
  536. return completeObjectValue(exeContext, ensureValidRuntimeType(runtimeType, exeContext, returnType, fieldNodes, info, result), fieldNodes, info, path, result);
  537. }
  538. function ensureValidRuntimeType(runtimeTypeOrName, exeContext, returnType, fieldNodes, info, result) {
  539. var runtimeType = typeof runtimeTypeOrName === 'string' ? exeContext.schema.getType(runtimeTypeOrName) : runtimeTypeOrName;
  540. if (!(0, _definition.isObjectType)(runtimeType)) {
  541. throw new _GraphQLError.GraphQLError("Abstract type \"".concat(returnType.name, "\" must resolve to an Object type at runtime for field \"").concat(info.parentType.name, ".").concat(info.fieldName, "\" with ") + "value ".concat((0, _inspect.default)(result), ", received \"").concat((0, _inspect.default)(runtimeType), "\". ") + "Either the \"".concat(returnType.name, "\" type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function."), fieldNodes);
  542. }
  543. if (!exeContext.schema.isSubType(returnType, runtimeType)) {
  544. throw new _GraphQLError.GraphQLError("Runtime Object type \"".concat(runtimeType.name, "\" is not a possible type for \"").concat(returnType.name, "\"."), fieldNodes);
  545. }
  546. return runtimeType;
  547. }
  548. /**
  549. * Complete an Object value by executing all sub-selections.
  550. */
  551. function completeObjectValue(exeContext, returnType, fieldNodes, info, path, result) {
  552. // If there is an isTypeOf predicate function, call it with the
  553. // current result. If isTypeOf returns false, then raise an error rather
  554. // than continuing execution.
  555. if (returnType.isTypeOf) {
  556. var isTypeOf = returnType.isTypeOf(result, exeContext.contextValue, info);
  557. if ((0, _isPromise.default)(isTypeOf)) {
  558. return isTypeOf.then(function (resolvedIsTypeOf) {
  559. if (!resolvedIsTypeOf) {
  560. throw invalidReturnTypeError(returnType, result, fieldNodes);
  561. }
  562. return collectAndExecuteSubfields(exeContext, returnType, fieldNodes, path, result);
  563. });
  564. }
  565. if (!isTypeOf) {
  566. throw invalidReturnTypeError(returnType, result, fieldNodes);
  567. }
  568. }
  569. return collectAndExecuteSubfields(exeContext, returnType, fieldNodes, path, result);
  570. }
  571. function invalidReturnTypeError(returnType, result, fieldNodes) {
  572. return new _GraphQLError.GraphQLError("Expected value of type \"".concat(returnType.name, "\" but got: ").concat((0, _inspect.default)(result), "."), fieldNodes);
  573. }
  574. function collectAndExecuteSubfields(exeContext, returnType, fieldNodes, path, result) {
  575. // Collect sub-fields to execute to complete this value.
  576. var subFieldNodes = collectSubfields(exeContext, returnType, fieldNodes);
  577. return executeFields(exeContext, returnType, result, path, subFieldNodes);
  578. }
  579. /**
  580. * A memoized collection of relevant subfields with regard to the return
  581. * type. Memoizing ensures the subfields are not repeatedly calculated, which
  582. * saves overhead when resolving lists of values.
  583. */
  584. var collectSubfields = (0, _memoize.default)(_collectSubfields);
  585. function _collectSubfields(exeContext, returnType, fieldNodes) {
  586. var subFieldNodes = Object.create(null);
  587. var visitedFragmentNames = Object.create(null);
  588. for (var _i8 = 0; _i8 < fieldNodes.length; _i8++) {
  589. var node = fieldNodes[_i8];
  590. if (node.selectionSet) {
  591. subFieldNodes = collectFields(exeContext, returnType, node.selectionSet, subFieldNodes, visitedFragmentNames);
  592. }
  593. }
  594. return subFieldNodes;
  595. }
  596. /**
  597. * If a resolveType function is not given, then a default resolve behavior is
  598. * used which attempts two strategies:
  599. *
  600. * First, See if the provided value has a `__typename` field defined, if so, use
  601. * that value as name of the resolved type.
  602. *
  603. * Otherwise, test each possible type for the abstract type by calling
  604. * isTypeOf for the object being coerced, returning the first type that matches.
  605. */
  606. var defaultTypeResolver = function defaultTypeResolver(value, contextValue, info, abstractType) {
  607. // First, look for `__typename`.
  608. if ((0, _isObjectLike.default)(value) && typeof value.__typename === 'string') {
  609. return value.__typename;
  610. } // Otherwise, test each possible type.
  611. var possibleTypes = info.schema.getPossibleTypes(abstractType);
  612. var promisedIsTypeOfResults = [];
  613. for (var i = 0; i < possibleTypes.length; i++) {
  614. var type = possibleTypes[i];
  615. if (type.isTypeOf) {
  616. var isTypeOfResult = type.isTypeOf(value, contextValue, info);
  617. if ((0, _isPromise.default)(isTypeOfResult)) {
  618. promisedIsTypeOfResults[i] = isTypeOfResult;
  619. } else if (isTypeOfResult) {
  620. return type;
  621. }
  622. }
  623. }
  624. if (promisedIsTypeOfResults.length) {
  625. return Promise.all(promisedIsTypeOfResults).then(function (isTypeOfResults) {
  626. for (var _i9 = 0; _i9 < isTypeOfResults.length; _i9++) {
  627. if (isTypeOfResults[_i9]) {
  628. return possibleTypes[_i9];
  629. }
  630. }
  631. });
  632. }
  633. };
  634. /**
  635. * If a resolve function is not given, then a default resolve behavior is used
  636. * which takes the property of the source object of the same name as the field
  637. * and returns it as the result, or if it's a function, returns the result
  638. * of calling that function while passing along args and context value.
  639. */
  640. exports.defaultTypeResolver = defaultTypeResolver;
  641. var defaultFieldResolver = function defaultFieldResolver(source, args, contextValue, info) {
  642. // ensure source is a value for which property access is acceptable.
  643. if ((0, _isObjectLike.default)(source) || typeof source === 'function') {
  644. var property = source[info.fieldName];
  645. if (typeof property === 'function') {
  646. return source[info.fieldName](args, contextValue, info);
  647. }
  648. return property;
  649. }
  650. };
  651. /**
  652. * This method looks up the field on the given type definition.
  653. * It has special casing for the three introspection fields,
  654. * __schema, __type and __typename. __typename is special because
  655. * it can always be queried as a field, even in situations where no
  656. * other fields are allowed, like on a Union. __schema and __type
  657. * could get automatically added to the query type, but that would
  658. * require mutating type definitions, which would cause issues.
  659. *
  660. * @internal
  661. */
  662. exports.defaultFieldResolver = defaultFieldResolver;
  663. function getFieldDef(schema, parentType, fieldName) {
  664. if (fieldName === _introspection.SchemaMetaFieldDef.name && schema.getQueryType() === parentType) {
  665. return _introspection.SchemaMetaFieldDef;
  666. } else if (fieldName === _introspection.TypeMetaFieldDef.name && schema.getQueryType() === parentType) {
  667. return _introspection.TypeMetaFieldDef;
  668. } else if (fieldName === _introspection.TypeNameMetaFieldDef.name) {
  669. return _introspection.TypeNameMetaFieldDef;
  670. }
  671. return parentType.getFields()[fieldName];
  672. }