UNPKG

@saeris/graphql-scalars

Version:

A collection of scalar types using Joi for validation

45 lines (37 loc) 1.53 kB
import { GraphQLScalarType, GraphQLError, Kind } from "graphql"; import { number as yupNumber } from "yup"; export const rangeFactory = ({ name, start, end, float = false }) => { const validate = value => { yupNumber().typeError(`Value is not a number: ${value}`).notOneOf([Infinity, -Infinity], `Value is not a finite number: ${value}`).required(`Value is not a number: ${value}`).min(0, `Value is not a positive number: ${value}`).validateSync(value); if (!float) { yupNumber().integer(`Value is not an integer: ${value}`).test(`unsafeInt`, `Value is not a number: ${value}`, val => Number.isSafeInteger(val)).validateSync(value); } const parsed = float ? parseFloat(value) : parseInt(value, 10); yupNumber().strict(true).min(start, `Value is less than limit: ${start}: ${parsed}`).max(end, `Value is greater than limit: ${end}: ${parsed}`).validateSync(parsed); return parsed; }; return { scalar: `scalar ${name}`, resolver: new GraphQLScalarType({ name, description: `A${float ? ` Float` : `n Integer`} with a value between ${start} and ${end} (inclusive).`, serialize(value) { return validate(value); }, parseValue(value) { return validate(value); }, parseLiteral(ast) { if (ast.kind !== (float ? Kind.FLOAT : Kind.INT)) { throw new GraphQLError(`Can only validate ${float ? `Floats` : `Integers`} but got a: ${ast.kind}`); } return validate(ast.value); } }) }; };