values.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true,
  4. });
  5. exports.getArgumentValues = getArgumentValues;
  6. exports.getDirectiveValues = getDirectiveValues;
  7. exports.getVariableValues = getVariableValues;
  8. var _inspect = require('../jsutils/inspect.js');
  9. var _keyMap = require('../jsutils/keyMap.js');
  10. var _printPathArray = require('../jsutils/printPathArray.js');
  11. var _GraphQLError = require('../error/GraphQLError.js');
  12. var _kinds = require('../language/kinds.js');
  13. var _printer = require('../language/printer.js');
  14. var _definition = require('../type/definition.js');
  15. var _coerceInputValue = require('../utilities/coerceInputValue.js');
  16. var _typeFromAST = require('../utilities/typeFromAST.js');
  17. var _valueFromAST = require('../utilities/valueFromAST.js');
  18. /**
  19. * Prepares an object map of variableValues of the correct type based on the
  20. * provided variable definitions and arbitrary input. If the input cannot be
  21. * parsed to match the variable definitions, a GraphQLError will be thrown.
  22. *
  23. * Note: The returned value is a plain Object with a prototype, since it is
  24. * exposed to user code. Care should be taken to not pull values from the
  25. * Object prototype.
  26. */
  27. function getVariableValues(schema, varDefNodes, inputs, options) {
  28. const errors = [];
  29. const maxErrors =
  30. options === null || options === void 0 ? void 0 : options.maxErrors;
  31. try {
  32. const coerced = coerceVariableValues(
  33. schema,
  34. varDefNodes,
  35. inputs,
  36. (error) => {
  37. if (maxErrors != null && errors.length >= maxErrors) {
  38. throw new _GraphQLError.GraphQLError(
  39. 'Too many errors processing variables, error limit reached. Execution aborted.',
  40. );
  41. }
  42. errors.push(error);
  43. },
  44. );
  45. if (errors.length === 0) {
  46. return {
  47. coerced,
  48. };
  49. }
  50. } catch (error) {
  51. errors.push(error);
  52. }
  53. return {
  54. errors,
  55. };
  56. }
  57. function coerceVariableValues(schema, varDefNodes, inputs, onError) {
  58. const coercedValues = {};
  59. for (const varDefNode of varDefNodes) {
  60. const varName = varDefNode.variable.name.value;
  61. const varType = (0, _typeFromAST.typeFromAST)(schema, varDefNode.type);
  62. if (!(0, _definition.isInputType)(varType)) {
  63. // Must use input types for variables. This should be caught during
  64. // validation, however is checked again here for safety.
  65. const varTypeStr = (0, _printer.print)(varDefNode.type);
  66. onError(
  67. new _GraphQLError.GraphQLError(
  68. `Variable "$${varName}" expected value of type "${varTypeStr}" which cannot be used as an input type.`,
  69. {
  70. nodes: varDefNode.type,
  71. },
  72. ),
  73. );
  74. continue;
  75. }
  76. if (!hasOwnProperty(inputs, varName)) {
  77. if (varDefNode.defaultValue) {
  78. coercedValues[varName] = (0, _valueFromAST.valueFromAST)(
  79. varDefNode.defaultValue,
  80. varType,
  81. );
  82. } else if ((0, _definition.isNonNullType)(varType)) {
  83. const varTypeStr = (0, _inspect.inspect)(varType);
  84. onError(
  85. new _GraphQLError.GraphQLError(
  86. `Variable "$${varName}" of required type "${varTypeStr}" was not provided.`,
  87. {
  88. nodes: varDefNode,
  89. },
  90. ),
  91. );
  92. }
  93. continue;
  94. }
  95. const value = inputs[varName];
  96. if (value === null && (0, _definition.isNonNullType)(varType)) {
  97. const varTypeStr = (0, _inspect.inspect)(varType);
  98. onError(
  99. new _GraphQLError.GraphQLError(
  100. `Variable "$${varName}" of non-null type "${varTypeStr}" must not be null.`,
  101. {
  102. nodes: varDefNode,
  103. },
  104. ),
  105. );
  106. continue;
  107. }
  108. coercedValues[varName] = (0, _coerceInputValue.coerceInputValue)(
  109. value,
  110. varType,
  111. (path, invalidValue, error) => {
  112. let prefix =
  113. `Variable "$${varName}" got invalid value ` +
  114. (0, _inspect.inspect)(invalidValue);
  115. if (path.length > 0) {
  116. prefix += ` at "${varName}${(0, _printPathArray.printPathArray)(
  117. path,
  118. )}"`;
  119. }
  120. onError(
  121. new _GraphQLError.GraphQLError(prefix + '; ' + error.message, {
  122. nodes: varDefNode,
  123. originalError: error,
  124. }),
  125. );
  126. },
  127. );
  128. }
  129. return coercedValues;
  130. }
  131. /**
  132. * Prepares an object map of argument values given a list of argument
  133. * definitions and list of argument AST nodes.
  134. *
  135. * Note: The returned value is a plain Object with a prototype, since it is
  136. * exposed to user code. Care should be taken to not pull values from the
  137. * Object prototype.
  138. */
  139. function getArgumentValues(def, node, variableValues) {
  140. var _node$arguments;
  141. const coercedValues = {}; // FIXME: https://github.com/graphql/graphql-js/issues/2203
  142. /* c8 ignore next */
  143. const argumentNodes =
  144. (_node$arguments = node.arguments) !== null && _node$arguments !== void 0
  145. ? _node$arguments
  146. : [];
  147. const argNodeMap = (0, _keyMap.keyMap)(
  148. argumentNodes,
  149. (arg) => arg.name.value,
  150. );
  151. for (const argDef of def.args) {
  152. const name = argDef.name;
  153. const argType = argDef.type;
  154. const argumentNode = argNodeMap[name];
  155. if (!argumentNode) {
  156. if (argDef.defaultValue !== undefined) {
  157. coercedValues[name] = argDef.defaultValue;
  158. } else if ((0, _definition.isNonNullType)(argType)) {
  159. throw new _GraphQLError.GraphQLError(
  160. `Argument "${name}" of required type "${(0, _inspect.inspect)(
  161. argType,
  162. )}" ` + 'was not provided.',
  163. {
  164. nodes: node,
  165. },
  166. );
  167. }
  168. continue;
  169. }
  170. const valueNode = argumentNode.value;
  171. let isNull = valueNode.kind === _kinds.Kind.NULL;
  172. if (valueNode.kind === _kinds.Kind.VARIABLE) {
  173. const variableName = valueNode.name.value;
  174. if (
  175. variableValues == null ||
  176. !hasOwnProperty(variableValues, variableName)
  177. ) {
  178. if (argDef.defaultValue !== undefined) {
  179. coercedValues[name] = argDef.defaultValue;
  180. } else if ((0, _definition.isNonNullType)(argType)) {
  181. throw new _GraphQLError.GraphQLError(
  182. `Argument "${name}" of required type "${(0, _inspect.inspect)(
  183. argType,
  184. )}" ` +
  185. `was provided the variable "$${variableName}" which was not provided a runtime value.`,
  186. {
  187. nodes: valueNode,
  188. },
  189. );
  190. }
  191. continue;
  192. }
  193. isNull = variableValues[variableName] == null;
  194. }
  195. if (isNull && (0, _definition.isNonNullType)(argType)) {
  196. throw new _GraphQLError.GraphQLError(
  197. `Argument "${name}" of non-null type "${(0, _inspect.inspect)(
  198. argType,
  199. )}" ` + 'must not be null.',
  200. {
  201. nodes: valueNode,
  202. },
  203. );
  204. }
  205. const coercedValue = (0, _valueFromAST.valueFromAST)(
  206. valueNode,
  207. argType,
  208. variableValues,
  209. );
  210. if (coercedValue === undefined) {
  211. // Note: ValuesOfCorrectTypeRule validation should catch this before
  212. // execution. This is a runtime check to ensure execution does not
  213. // continue with an invalid argument value.
  214. throw new _GraphQLError.GraphQLError(
  215. `Argument "${name}" has invalid value ${(0, _printer.print)(
  216. valueNode,
  217. )}.`,
  218. {
  219. nodes: valueNode,
  220. },
  221. );
  222. }
  223. coercedValues[name] = coercedValue;
  224. }
  225. return coercedValues;
  226. }
  227. /**
  228. * Prepares an object map of argument values given a directive definition
  229. * and a AST node which may contain directives. Optionally also accepts a map
  230. * of variable values.
  231. *
  232. * If the directive does not exist on the node, returns undefined.
  233. *
  234. * Note: The returned value is a plain Object with a prototype, since it is
  235. * exposed to user code. Care should be taken to not pull values from the
  236. * Object prototype.
  237. */
  238. function getDirectiveValues(directiveDef, node, variableValues) {
  239. var _node$directives;
  240. const directiveNode =
  241. (_node$directives = node.directives) === null || _node$directives === void 0
  242. ? void 0
  243. : _node$directives.find(
  244. (directive) => directive.name.value === directiveDef.name,
  245. );
  246. if (directiveNode) {
  247. return getArgumentValues(directiveDef, directiveNode, variableValues);
  248. }
  249. }
  250. function hasOwnProperty(obj, prop) {
  251. return Object.prototype.hasOwnProperty.call(obj, prop);
  252. }