UNPKG

6.25 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.valueFromAST = valueFromAST;
7
8var _objectValues3 = _interopRequireDefault(require("../polyfills/objectValues"));
9
10var _keyMap = _interopRequireDefault(require("../jsutils/keyMap"));
11
12var _inspect = _interopRequireDefault(require("../jsutils/inspect"));
13
14var _invariant = _interopRequireDefault(require("../jsutils/invariant"));
15
16var _isInvalid = _interopRequireDefault(require("../jsutils/isInvalid"));
17
18var _kinds = require("../language/kinds");
19
20var _definition = require("../type/definition");
21
22function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
24/**
25 * Produces a JavaScript value given a GraphQL Value AST.
26 *
27 * A GraphQL type must be provided, which will be used to interpret different
28 * GraphQL Value literals.
29 *
30 * Returns `undefined` when the value could not be validly coerced according to
31 * the provided type.
32 *
33 * | GraphQL Value | JSON Value |
34 * | -------------------- | ------------- |
35 * | Input Object | Object |
36 * | List | Array |
37 * | Boolean | Boolean |
38 * | String | String |
39 * | Int / Float | Number |
40 * | Enum Value | Mixed |
41 * | NullValue | null |
42 *
43 */
44function valueFromAST(valueNode, type, variables) {
45 if (!valueNode) {
46 // When there is no node, then there is also no value.
47 // Importantly, this is different from returning the value null.
48 return;
49 }
50
51 if ((0, _definition.isNonNullType)(type)) {
52 if (valueNode.kind === _kinds.Kind.NULL) {
53 return; // Invalid: intentionally return no value.
54 }
55
56 return valueFromAST(valueNode, type.ofType, variables);
57 }
58
59 if (valueNode.kind === _kinds.Kind.NULL) {
60 // This is explicitly returning the value null.
61 return null;
62 }
63
64 if (valueNode.kind === _kinds.Kind.VARIABLE) {
65 var variableName = valueNode.name.value;
66
67 if (!variables || (0, _isInvalid.default)(variables[variableName])) {
68 // No valid return value.
69 return;
70 }
71
72 var variableValue = variables[variableName];
73
74 if (variableValue === null && (0, _definition.isNonNullType)(type)) {
75 return; // Invalid: intentionally return no value.
76 } // Note: This does no further checking that this variable is correct.
77 // This assumes that this query has been validated and the variable
78 // usage here is of the correct type.
79
80
81 return variableValue;
82 }
83
84 if ((0, _definition.isListType)(type)) {
85 var itemType = type.ofType;
86
87 if (valueNode.kind === _kinds.Kind.LIST) {
88 var coercedValues = [];
89
90 for (var _i2 = 0, _valueNode$values2 = valueNode.values; _i2 < _valueNode$values2.length; _i2++) {
91 var itemNode = _valueNode$values2[_i2];
92
93 if (isMissingVariable(itemNode, variables)) {
94 // If an array contains a missing variable, it is either coerced to
95 // null or if the item type is non-null, it considered invalid.
96 if ((0, _definition.isNonNullType)(itemType)) {
97 return; // Invalid: intentionally return no value.
98 }
99
100 coercedValues.push(null);
101 } else {
102 var itemValue = valueFromAST(itemNode, itemType, variables);
103
104 if ((0, _isInvalid.default)(itemValue)) {
105 return; // Invalid: intentionally return no value.
106 }
107
108 coercedValues.push(itemValue);
109 }
110 }
111
112 return coercedValues;
113 }
114
115 var coercedValue = valueFromAST(valueNode, itemType, variables);
116
117 if ((0, _isInvalid.default)(coercedValue)) {
118 return; // Invalid: intentionally return no value.
119 }
120
121 return [coercedValue];
122 }
123
124 if ((0, _definition.isInputObjectType)(type)) {
125 if (valueNode.kind !== _kinds.Kind.OBJECT) {
126 return; // Invalid: intentionally return no value.
127 }
128
129 var coercedObj = Object.create(null);
130 var fieldNodes = (0, _keyMap.default)(valueNode.fields, function (field) {
131 return field.name.value;
132 });
133
134 for (var _i4 = 0, _objectValues2 = (0, _objectValues3.default)(type.getFields()); _i4 < _objectValues2.length; _i4++) {
135 var field = _objectValues2[_i4];
136 var fieldNode = fieldNodes[field.name];
137
138 if (!fieldNode || isMissingVariable(fieldNode.value, variables)) {
139 if (field.defaultValue !== undefined) {
140 coercedObj[field.name] = field.defaultValue;
141 } else if ((0, _definition.isNonNullType)(field.type)) {
142 return; // Invalid: intentionally return no value.
143 }
144
145 continue;
146 }
147
148 var fieldValue = valueFromAST(fieldNode.value, field.type, variables);
149
150 if ((0, _isInvalid.default)(fieldValue)) {
151 return; // Invalid: intentionally return no value.
152 }
153
154 coercedObj[field.name] = fieldValue;
155 }
156
157 return coercedObj;
158 }
159
160 if ((0, _definition.isEnumType)(type)) {
161 if (valueNode.kind !== _kinds.Kind.ENUM) {
162 return; // Invalid: intentionally return no value.
163 }
164
165 var enumValue = type.getValue(valueNode.value);
166
167 if (!enumValue) {
168 return; // Invalid: intentionally return no value.
169 }
170
171 return enumValue.value;
172 }
173
174 /* istanbul ignore else */
175 if ((0, _definition.isScalarType)(type)) {
176 // Scalars fulfill parsing a literal value via parseLiteral().
177 // Invalid values represent a failure to parse correctly, in which case
178 // no value is returned.
179 var result;
180
181 try {
182 result = type.parseLiteral(valueNode, variables);
183 } catch (_error) {
184 return; // Invalid: intentionally return no value.
185 }
186
187 if ((0, _isInvalid.default)(result)) {
188 return; // Invalid: intentionally return no value.
189 }
190
191 return result;
192 } // Not reachable. All possible input types have been considered.
193
194
195 /* istanbul ignore next */
196 (0, _invariant.default)(false, 'Unexpected input type: ' + (0, _inspect.default)(type));
197} // Returns true if the provided valueNode is a variable which is not defined
198// in the set of variables.
199
200
201function isMissingVariable(valueNode, variables) {
202 return valueNode.kind === _kinds.Kind.VARIABLE && (!variables || (0, _isInvalid.default)(variables[valueNode.name.value]));
203}