UNPKG

5.3 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', {
4 value: true,
5});
6exports.coerceInputValue = coerceInputValue;
7
8var _didYouMean = require('../jsutils/didYouMean.js');
9
10var _inspect = require('../jsutils/inspect.js');
11
12var _invariant = require('../jsutils/invariant.js');
13
14var _isIterableObject = require('../jsutils/isIterableObject.js');
15
16var _isObjectLike = require('../jsutils/isObjectLike.js');
17
18var _Path = require('../jsutils/Path.js');
19
20var _printPathArray = require('../jsutils/printPathArray.js');
21
22var _suggestionList = require('../jsutils/suggestionList.js');
23
24var _GraphQLError = require('../error/GraphQLError.js');
25
26var _definition = require('../type/definition.js');
27
28/**
29 * Coerces a JavaScript value given a GraphQL Input Type.
30 */
31function coerceInputValue(inputValue, type, onError = defaultOnError) {
32 return coerceInputValueImpl(inputValue, type, onError, undefined);
33}
34
35function defaultOnError(path, invalidValue, error) {
36 let errorPrefix = 'Invalid value ' + (0, _inspect.inspect)(invalidValue);
37
38 if (path.length > 0) {
39 errorPrefix += ` at "value${(0, _printPathArray.printPathArray)(path)}"`;
40 }
41
42 error.message = errorPrefix + ': ' + error.message;
43 throw error;
44}
45
46function coerceInputValueImpl(inputValue, type, onError, path) {
47 if ((0, _definition.isNonNullType)(type)) {
48 if (inputValue != null) {
49 return coerceInputValueImpl(inputValue, type.ofType, onError, path);
50 }
51
52 onError(
53 (0, _Path.pathToArray)(path),
54 inputValue,
55 new _GraphQLError.GraphQLError(
56 `Expected non-nullable type "${(0, _inspect.inspect)(
57 type,
58 )}" not to be null.`,
59 ),
60 );
61 return;
62 }
63
64 if (inputValue == null) {
65 // Explicitly return the value null.
66 return null;
67 }
68
69 if ((0, _definition.isListType)(type)) {
70 const itemType = type.ofType;
71
72 if ((0, _isIterableObject.isIterableObject)(inputValue)) {
73 return Array.from(inputValue, (itemValue, index) => {
74 const itemPath = (0, _Path.addPath)(path, index, undefined);
75 return coerceInputValueImpl(itemValue, itemType, onError, itemPath);
76 });
77 } // Lists accept a non-list value as a list of one.
78
79 return [coerceInputValueImpl(inputValue, itemType, onError, path)];
80 }
81
82 if ((0, _definition.isInputObjectType)(type)) {
83 if (!(0, _isObjectLike.isObjectLike)(inputValue)) {
84 onError(
85 (0, _Path.pathToArray)(path),
86 inputValue,
87 new _GraphQLError.GraphQLError(
88 `Expected type "${type.name}" to be an object.`,
89 ),
90 );
91 return;
92 }
93
94 const coercedValue = {};
95 const fieldDefs = type.getFields();
96
97 for (const field of Object.values(fieldDefs)) {
98 const fieldValue = inputValue[field.name];
99
100 if (fieldValue === undefined) {
101 if (field.defaultValue !== undefined) {
102 coercedValue[field.name] = field.defaultValue;
103 } else if ((0, _definition.isNonNullType)(field.type)) {
104 const typeStr = (0, _inspect.inspect)(field.type);
105 onError(
106 (0, _Path.pathToArray)(path),
107 inputValue,
108 new _GraphQLError.GraphQLError(
109 `Field "${field.name}" of required type "${typeStr}" was not provided.`,
110 ),
111 );
112 }
113
114 continue;
115 }
116
117 coercedValue[field.name] = coerceInputValueImpl(
118 fieldValue,
119 field.type,
120 onError,
121 (0, _Path.addPath)(path, field.name, type.name),
122 );
123 } // Ensure every provided field is defined.
124
125 for (const fieldName of Object.keys(inputValue)) {
126 if (!fieldDefs[fieldName]) {
127 const suggestions = (0, _suggestionList.suggestionList)(
128 fieldName,
129 Object.keys(type.getFields()),
130 );
131 onError(
132 (0, _Path.pathToArray)(path),
133 inputValue,
134 new _GraphQLError.GraphQLError(
135 `Field "${fieldName}" is not defined by type "${type.name}".` +
136 (0, _didYouMean.didYouMean)(suggestions),
137 ),
138 );
139 }
140 }
141
142 return coercedValue;
143 }
144
145 if ((0, _definition.isLeafType)(type)) {
146 let parseResult; // Scalars and Enums determine if a input value is valid via parseValue(),
147 // which can throw to indicate failure. If it throws, maintain a reference
148 // to the original error.
149
150 try {
151 parseResult = type.parseValue(inputValue);
152 } catch (error) {
153 if (error instanceof _GraphQLError.GraphQLError) {
154 onError((0, _Path.pathToArray)(path), inputValue, error);
155 } else {
156 onError(
157 (0, _Path.pathToArray)(path),
158 inputValue,
159 new _GraphQLError.GraphQLError(
160 `Expected type "${type.name}". ` + error.message,
161 {
162 originalError: error,
163 },
164 ),
165 );
166 }
167
168 return;
169 }
170
171 if (parseResult === undefined) {
172 onError(
173 (0, _Path.pathToArray)(path),
174 inputValue,
175 new _GraphQLError.GraphQLError(`Expected type "${type.name}".`),
176 );
177 }
178
179 return parseResult;
180 }
181 /* c8 ignore next 3 */
182 // Not reachable, all possible types have been considered.
183
184 false ||
185 (0, _invariant.invariant)(
186 false,
187 'Unexpected input type: ' + (0, _inspect.inspect)(type),
188 );
189}