coerceInputValue.mjs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import objectValues from "../polyfills/objectValues.mjs";
  2. import inspect from "../jsutils/inspect.mjs";
  3. import invariant from "../jsutils/invariant.mjs";
  4. import didYouMean from "../jsutils/didYouMean.mjs";
  5. import isObjectLike from "../jsutils/isObjectLike.mjs";
  6. import safeArrayFrom from "../jsutils/safeArrayFrom.mjs";
  7. import suggestionList from "../jsutils/suggestionList.mjs";
  8. import printPathArray from "../jsutils/printPathArray.mjs";
  9. import { addPath, pathToArray } from "../jsutils/Path.mjs";
  10. import { GraphQLError } from "../error/GraphQLError.mjs";
  11. import { isLeafType, isInputObjectType, isListType, isNonNullType } from "../type/definition.mjs";
  12. /**
  13. * Coerces a JavaScript value given a GraphQL Input Type.
  14. */
  15. export function coerceInputValue(inputValue, type) {
  16. var onError = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultOnError;
  17. return coerceInputValueImpl(inputValue, type, onError);
  18. }
  19. function defaultOnError(path, invalidValue, error) {
  20. var errorPrefix = 'Invalid value ' + inspect(invalidValue);
  21. if (path.length > 0) {
  22. errorPrefix += " at \"value".concat(printPathArray(path), "\"");
  23. }
  24. error.message = errorPrefix + ': ' + error.message;
  25. throw error;
  26. }
  27. function coerceInputValueImpl(inputValue, type, onError, path) {
  28. if (isNonNullType(type)) {
  29. if (inputValue != null) {
  30. return coerceInputValueImpl(inputValue, type.ofType, onError, path);
  31. }
  32. onError(pathToArray(path), inputValue, new GraphQLError("Expected non-nullable type \"".concat(inspect(type), "\" not to be null.")));
  33. return;
  34. }
  35. if (inputValue == null) {
  36. // Explicitly return the value null.
  37. return null;
  38. }
  39. if (isListType(type)) {
  40. var itemType = type.ofType;
  41. var coercedList = safeArrayFrom(inputValue, function (itemValue, index) {
  42. var itemPath = addPath(path, index, undefined);
  43. return coerceInputValueImpl(itemValue, itemType, onError, itemPath);
  44. });
  45. if (coercedList != null) {
  46. return coercedList;
  47. } // Lists accept a non-list value as a list of one.
  48. return [coerceInputValueImpl(inputValue, itemType, onError, path)];
  49. }
  50. if (isInputObjectType(type)) {
  51. if (!isObjectLike(inputValue)) {
  52. onError(pathToArray(path), inputValue, new GraphQLError("Expected type \"".concat(type.name, "\" to be an object.")));
  53. return;
  54. }
  55. var coercedValue = {};
  56. var fieldDefs = type.getFields();
  57. for (var _i2 = 0, _objectValues2 = objectValues(fieldDefs); _i2 < _objectValues2.length; _i2++) {
  58. var field = _objectValues2[_i2];
  59. var fieldValue = inputValue[field.name];
  60. if (fieldValue === undefined) {
  61. if (field.defaultValue !== undefined) {
  62. coercedValue[field.name] = field.defaultValue;
  63. } else if (isNonNullType(field.type)) {
  64. var typeStr = inspect(field.type);
  65. onError(pathToArray(path), inputValue, new GraphQLError("Field \"".concat(field.name, "\" of required type \"").concat(typeStr, "\" was not provided.")));
  66. }
  67. continue;
  68. }
  69. coercedValue[field.name] = coerceInputValueImpl(fieldValue, field.type, onError, addPath(path, field.name, type.name));
  70. } // Ensure every provided field is defined.
  71. for (var _i4 = 0, _Object$keys2 = Object.keys(inputValue); _i4 < _Object$keys2.length; _i4++) {
  72. var fieldName = _Object$keys2[_i4];
  73. if (!fieldDefs[fieldName]) {
  74. var suggestions = suggestionList(fieldName, Object.keys(type.getFields()));
  75. onError(pathToArray(path), inputValue, new GraphQLError("Field \"".concat(fieldName, "\" is not defined by type \"").concat(type.name, "\".") + didYouMean(suggestions)));
  76. }
  77. }
  78. return coercedValue;
  79. } // istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2618')
  80. if (isLeafType(type)) {
  81. var parseResult; // Scalars and Enums determine if a input value is valid via parseValue(),
  82. // which can throw to indicate failure. If it throws, maintain a reference
  83. // to the original error.
  84. try {
  85. parseResult = type.parseValue(inputValue);
  86. } catch (error) {
  87. if (error instanceof GraphQLError) {
  88. onError(pathToArray(path), inputValue, error);
  89. } else {
  90. onError(pathToArray(path), inputValue, new GraphQLError("Expected type \"".concat(type.name, "\". ") + error.message, undefined, undefined, undefined, undefined, error));
  91. }
  92. return;
  93. }
  94. if (parseResult === undefined) {
  95. onError(pathToArray(path), inputValue, new GraphQLError("Expected type \"".concat(type.name, "\".")));
  96. }
  97. return parseResult;
  98. } // istanbul ignore next (Not reachable. All possible input types have been considered)
  99. false || invariant(0, 'Unexpected input type: ' + inspect(type));
  100. }