UNPKG

4.96 kBJavaScriptView Raw
1import isFinite from "../polyfills/isFinite.mjs";
2import objectValues from "../polyfills/objectValues.mjs";
3import inspect from "../jsutils/inspect.mjs";
4import invariant from "../jsutils/invariant.mjs";
5import isObjectLike from "../jsutils/isObjectLike.mjs";
6import safeArrayFrom from "../jsutils/safeArrayFrom.mjs";
7import { Kind } from "../language/kinds.mjs";
8import { GraphQLID } from "../type/scalars.mjs";
9import { isLeafType, isEnumType, isInputObjectType, isListType, isNonNullType } from "../type/definition.mjs";
10/**
11 * Produces a GraphQL Value AST given a JavaScript object.
12 * Function will match JavaScript/JSON values to GraphQL AST schema format
13 * by using suggested GraphQLInputType. For example:
14 *
15 * astFromValue("value", GraphQLString)
16 *
17 * A GraphQL type must be provided, which will be used to interpret different
18 * JavaScript values.
19 *
20 * | JSON Value | GraphQL Value |
21 * | ------------- | -------------------- |
22 * | Object | Input Object |
23 * | Array | List |
24 * | Boolean | Boolean |
25 * | String | String / Enum Value |
26 * | Number | Int / Float |
27 * | Mixed | Enum Value |
28 * | null | NullValue |
29 *
30 */
31
32export function astFromValue(value, type) {
33 if (isNonNullType(type)) {
34 var astValue = astFromValue(value, type.ofType);
35
36 if ((astValue === null || astValue === void 0 ? void 0 : astValue.kind) === Kind.NULL) {
37 return null;
38 }
39
40 return astValue;
41 } // only explicit null, not undefined, NaN
42
43
44 if (value === null) {
45 return {
46 kind: Kind.NULL
47 };
48 } // undefined
49
50
51 if (value === undefined) {
52 return null;
53 } // Convert JavaScript array to GraphQL list. If the GraphQLType is a list, but
54 // the value is not an array, convert the value using the list's item type.
55
56
57 if (isListType(type)) {
58 var itemType = type.ofType;
59 var items = safeArrayFrom(value);
60
61 if (items != null) {
62 var valuesNodes = [];
63
64 for (var _i2 = 0; _i2 < items.length; _i2++) {
65 var item = items[_i2];
66 var itemNode = astFromValue(item, itemType);
67
68 if (itemNode != null) {
69 valuesNodes.push(itemNode);
70 }
71 }
72
73 return {
74 kind: Kind.LIST,
75 values: valuesNodes
76 };
77 }
78
79 return astFromValue(value, itemType);
80 } // Populate the fields of the input object by creating ASTs from each value
81 // in the JavaScript object according to the fields in the input type.
82
83
84 if (isInputObjectType(type)) {
85 if (!isObjectLike(value)) {
86 return null;
87 }
88
89 var fieldNodes = [];
90
91 for (var _i4 = 0, _objectValues2 = objectValues(type.getFields()); _i4 < _objectValues2.length; _i4++) {
92 var field = _objectValues2[_i4];
93 var fieldValue = astFromValue(value[field.name], field.type);
94
95 if (fieldValue) {
96 fieldNodes.push({
97 kind: Kind.OBJECT_FIELD,
98 name: {
99 kind: Kind.NAME,
100 value: field.name
101 },
102 value: fieldValue
103 });
104 }
105 }
106
107 return {
108 kind: Kind.OBJECT,
109 fields: fieldNodes
110 };
111 } // istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2618')
112
113
114 if (isLeafType(type)) {
115 // Since value is an internally represented value, it must be serialized
116 // to an externally represented value before converting into an AST.
117 var serialized = type.serialize(value);
118
119 if (serialized == null) {
120 return null;
121 } // Others serialize based on their corresponding JavaScript scalar types.
122
123
124 if (typeof serialized === 'boolean') {
125 return {
126 kind: Kind.BOOLEAN,
127 value: serialized
128 };
129 } // JavaScript numbers can be Int or Float values.
130
131
132 if (typeof serialized === 'number' && isFinite(serialized)) {
133 var stringNum = String(serialized);
134 return integerStringRegExp.test(stringNum) ? {
135 kind: Kind.INT,
136 value: stringNum
137 } : {
138 kind: Kind.FLOAT,
139 value: stringNum
140 };
141 }
142
143 if (typeof serialized === 'string') {
144 // Enum types use Enum literals.
145 if (isEnumType(type)) {
146 return {
147 kind: Kind.ENUM,
148 value: serialized
149 };
150 } // ID types can use Int literals.
151
152
153 if (type === GraphQLID && integerStringRegExp.test(serialized)) {
154 return {
155 kind: Kind.INT,
156 value: serialized
157 };
158 }
159
160 return {
161 kind: Kind.STRING,
162 value: serialized
163 };
164 }
165
166 throw new TypeError("Cannot convert value to AST: ".concat(inspect(serialized), "."));
167 } // istanbul ignore next (Not reachable. All possible input types have been considered)
168
169
170 false || invariant(0, 'Unexpected input type: ' + inspect(type));
171}
172/**
173 * IntValue:
174 * - NegativeSign? 0
175 * - NegativeSign? NonZeroDigit ( Digit+ )?
176 */
177
178var integerStringRegExp = /^-?(?:0|[1-9][0-9]*)$/;