UNPKG

4.22 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.astFromValue = void 0;
4const cross_inspect_1 = require("cross-inspect");
5const graphql_1 = require("graphql");
6const astFromValueUntyped_js_1 = require("./astFromValueUntyped.js");
7const jsutils_js_1 = require("./jsutils.js");
8/**
9 * Produces a GraphQL Value AST given a JavaScript object.
10 * Function will match JavaScript/JSON values to GraphQL AST schema format
11 * by using suggested GraphQLInputType. For example:
12 *
13 * astFromValue("value", GraphQLString)
14 *
15 * A GraphQL type must be provided, which will be used to interpret different
16 * JavaScript values.
17 *
18 * | JSON Value | GraphQL Value |
19 * | ------------- | -------------------- |
20 * | Object | Input Object |
21 * | Array | List |
22 * | Boolean | Boolean |
23 * | String | String / Enum Value |
24 * | Number | Int / Float |
25 * | BigInt | Int |
26 * | Unknown | Enum Value |
27 * | null | NullValue |
28 *
29 */
30function astFromValue(value, type) {
31 if ((0, graphql_1.isNonNullType)(type)) {
32 const astValue = astFromValue(value, type.ofType);
33 if (astValue?.kind === graphql_1.Kind.NULL) {
34 return null;
35 }
36 return astValue;
37 }
38 // only explicit null, not undefined, NaN
39 if (value === null) {
40 return { kind: graphql_1.Kind.NULL };
41 }
42 // undefined
43 if (value === undefined) {
44 return null;
45 }
46 // Convert JavaScript array to GraphQL list. If the GraphQLType is a list, but
47 // the value is not an array, convert the value using the list's item type.
48 if ((0, graphql_1.isListType)(type)) {
49 const itemType = type.ofType;
50 if ((0, jsutils_js_1.isIterableObject)(value)) {
51 const valuesNodes = [];
52 for (const item of value) {
53 const itemNode = astFromValue(item, itemType);
54 if (itemNode != null) {
55 valuesNodes.push(itemNode);
56 }
57 }
58 return { kind: graphql_1.Kind.LIST, values: valuesNodes };
59 }
60 return astFromValue(value, itemType);
61 }
62 // Populate the fields of the input object by creating ASTs from each value
63 // in the JavaScript object according to the fields in the input type.
64 if ((0, graphql_1.isInputObjectType)(type)) {
65 if (!(0, jsutils_js_1.isObjectLike)(value)) {
66 return null;
67 }
68 const fieldNodes = [];
69 for (const field of Object.values(type.getFields())) {
70 const fieldValue = astFromValue(value[field.name], field.type);
71 if (fieldValue) {
72 fieldNodes.push({
73 kind: graphql_1.Kind.OBJECT_FIELD,
74 name: { kind: graphql_1.Kind.NAME, value: field.name },
75 value: fieldValue,
76 });
77 }
78 }
79 return { kind: graphql_1.Kind.OBJECT, fields: fieldNodes };
80 }
81 if ((0, graphql_1.isLeafType)(type)) {
82 // Since value is an internally represented value, it must be serialized
83 // to an externally represented value before converting into an AST.
84 const serialized = type.serialize(value);
85 if (serialized == null) {
86 return null;
87 }
88 if ((0, graphql_1.isEnumType)(type)) {
89 return { kind: graphql_1.Kind.ENUM, value: serialized };
90 }
91 // ID types can use Int literals.
92 if (type.name === 'ID' &&
93 typeof serialized === 'string' &&
94 integerStringRegExp.test(serialized)) {
95 return { kind: graphql_1.Kind.INT, value: serialized };
96 }
97 return (0, astFromValueUntyped_js_1.astFromValueUntyped)(serialized);
98 }
99 /* c8 ignore next 3 */
100 // Not reachable, all possible types have been considered.
101 console.assert(false, 'Unexpected input type: ' + (0, cross_inspect_1.inspect)(type));
102}
103exports.astFromValue = astFromValue;
104/**
105 * IntValue:
106 * - NegativeSign? 0
107 * - NegativeSign? NonZeroDigit ( Digit+ )?
108 */
109const integerStringRegExp = /^-?(?:0|[1-9][0-9]*)$/;