graphql
Version:
A Query Language and Runtime which can target any service.
116 lines • 4.09 kB
JavaScript
import { inspect } from "../jsutils/inspect.mjs";
import { isIterableObject } from "../jsutils/isIterableObject.mjs";
import { isObjectLike } from "../jsutils/isObjectLike.mjs";
import { Kind } from "../language/kinds.mjs";
import { assertLeafType, isInputObjectType, isListType, isNonNullType, isRequiredInputField, } from "../type/definition.mjs";
export function valueToLiteral(value, type) {
if (isNonNullType(type)) {
if (value == null) {
return;
}
return valueToLiteral(value, type.ofType);
}
if (value == null) {
return { kind: Kind.NULL };
}
if (isListType(type)) {
if (!isIterableObject(value)) {
return valueToLiteral(value, type.ofType);
}
const values = [];
for (const itemValue of value) {
const itemNode = valueToLiteral(itemValue, type.ofType);
if (!itemNode) {
return;
}
values.push(itemNode);
}
return { kind: Kind.LIST, values };
}
if (isInputObjectType(type)) {
if (!isObjectLike(value)) {
return;
}
const fields = [];
const fieldDefs = type.getFields();
const hasUndefinedField = Object.keys(value).some((name) => value[name] !== undefined && !Object.hasOwn(fieldDefs, name));
if (hasUndefinedField) {
return;
}
for (const field of Object.values(type.getFields())) {
const fieldValue = value[field.name];
if (fieldValue === undefined) {
if (isRequiredInputField(field)) {
return;
}
}
else {
const fieldNode = valueToLiteral(value[field.name], field.type);
if (!fieldNode) {
return;
}
fields.push({
kind: Kind.OBJECT_FIELD,
name: { kind: Kind.NAME, value: field.name },
value: fieldNode,
});
}
}
return { kind: Kind.OBJECT, fields };
}
const leafType = assertLeafType(type);
if (leafType.valueToLiteral) {
try {
return leafType.valueToLiteral(value);
}
catch (_error) {
return;
}
}
return defaultScalarValueToLiteral(value);
}
export function defaultScalarValueToLiteral(value) {
if (value == null) {
return { kind: Kind.NULL };
}
switch (typeof value) {
case 'boolean':
return { kind: Kind.BOOLEAN, value };
case 'string':
return { kind: Kind.STRING, value, block: false };
case 'bigint':
return { kind: Kind.INT, value: value.toString() };
case 'number': {
if (!Number.isFinite(value)) {
return { kind: Kind.NULL };
}
const stringValue = String(value);
return /^-?(?:0|[1-9][0-9]*)$/.test(stringValue)
? { kind: Kind.INT, value: stringValue }
: { kind: Kind.FLOAT, value: stringValue };
}
case 'object': {
if (isIterableObject(value)) {
return {
kind: Kind.LIST,
values: Array.from(value, defaultScalarValueToLiteral),
};
}
const objValue = value;
const fields = [];
for (const fieldName of Object.keys(objValue)) {
const fieldValue = objValue[fieldName];
if (fieldValue !== undefined) {
fields.push({
kind: Kind.OBJECT_FIELD,
name: { kind: Kind.NAME, value: fieldName },
value: defaultScalarValueToLiteral(fieldValue),
});
}
}
return { kind: Kind.OBJECT, fields };
}
}
throw new TypeError(`Cannot convert value to AST: ${inspect(value)}.`);
}
//# sourceMappingURL=valueToLiteral.js.map