UNPKG

2.59 kBJavaScriptView Raw
1import { Kind } from 'graphql';
2/**
3 * Produces a GraphQL Value AST given a JavaScript object.
4 * Function will match JavaScript/JSON values to GraphQL AST schema format
5 * by using the following mapping.
6 *
7 * | JSON Value | GraphQL Value |
8 * | ------------- | -------------------- |
9 * | Object | Input Object |
10 * | Array | List |
11 * | Boolean | Boolean |
12 * | String | String |
13 * | Number | Int / Float |
14 * | null | NullValue |
15 *
16 */
17export function astFromValueUntyped(value) {
18 // only explicit null, not undefined, NaN
19 if (value === null) {
20 return { kind: Kind.NULL };
21 }
22 // undefined
23 if (value === undefined) {
24 return null;
25 }
26 // Convert JavaScript array to GraphQL list. If the GraphQLType is a list, but
27 // the value is not an array, convert the value using the list's item type.
28 if (Array.isArray(value)) {
29 const valuesNodes = [];
30 for (const item of value) {
31 const itemNode = astFromValueUntyped(item);
32 if (itemNode != null) {
33 valuesNodes.push(itemNode);
34 }
35 }
36 return { kind: Kind.LIST, values: valuesNodes };
37 }
38 if (typeof value === 'object') {
39 const fieldNodes = [];
40 for (const fieldName in value) {
41 const fieldValue = value[fieldName];
42 const ast = astFromValueUntyped(fieldValue);
43 if (ast) {
44 fieldNodes.push({
45 kind: Kind.OBJECT_FIELD,
46 name: { kind: Kind.NAME, value: fieldName },
47 value: ast,
48 });
49 }
50 }
51 return { kind: Kind.OBJECT, fields: fieldNodes };
52 }
53 // Others serialize based on their corresponding JavaScript scalar types.
54 if (typeof value === 'boolean') {
55 return { kind: Kind.BOOLEAN, value };
56 }
57 // JavaScript numbers can be Int or Float values.
58 if (typeof value === 'number' && isFinite(value)) {
59 const stringNum = String(value);
60 return integerStringRegExp.test(stringNum)
61 ? { kind: Kind.INT, value: stringNum }
62 : { kind: Kind.FLOAT, value: stringNum };
63 }
64 if (typeof value === 'string') {
65 return { kind: Kind.STRING, value };
66 }
67 throw new TypeError(`Cannot convert value to AST: ${value}.`);
68}
69/**
70 * IntValue:
71 * - NegativeSign? 0
72 * - NegativeSign? NonZeroDigit ( Digit+ )?
73 */
74const integerStringRegExp = /^-?(?:0|[1-9][0-9]*)$/;