UNPKG

graphql-constraint-directive

Version:
99 lines (81 loc) 2.99 kB
const { GraphQLScalarType } = require('graphql') const { contains, isLength } = require('validator') const defaultFormats = require('./formats') const ValidationError = require('../lib/error') class ConstraintStringType extends GraphQLScalarType { constructor (fieldName, uniqueTypeName, type, args, options = {}) { super({ name: uniqueTypeName, serialize (value) { value = type.serialize(value) validate(fieldName, args, value, options) return value }, parseValue (value) { value = type.serialize(value) validate(fieldName, args, value, options) return type.parseValue(value) }, parseLiteral (ast) { const value = type.parseLiteral(ast) validate(fieldName, args, value, options) return value } }) } } function validate (fieldName, args, value, options = {}) { if (args.minLength && !isLength(value, { min: args.minLength })) { throw new ValidationError(fieldName, `Must be at least ${args.minLength} characters in length`, [{ arg: 'minLength', value: args.minLength }]) } if (args.maxLength && !isLength(value, { max: args.maxLength })) { throw new ValidationError(fieldName, `Must be no more than ${args.maxLength} characters in length`, [{ arg: 'maxLength', value: args.maxLength }]) } if (args.startsWith && !value.startsWith(args.startsWith)) { throw new ValidationError(fieldName, `Must start with ${args.startsWith}`, [{ arg: 'startsWith', value: args.startsWith }]) } if (args.endsWith && !value.endsWith(args.endsWith)) { throw new ValidationError(fieldName, `Must end with ${args.endsWith}`, [{ arg: 'endsWith', value: args.endsWith }]) } if (args.contains && !contains(value, args.contains)) { throw new ValidationError(fieldName, `Must contain ${args.contains}`, [{ arg: 'contains', value: args.contains }]) } if (args.notContains && contains(value, args.notContains)) { throw new ValidationError(fieldName, `Must not contain ${args.notContains}`, [{ arg: 'notContains', value: args.notContains }]) } if (args.pattern && !new RegExp(args.pattern).test(value)) { throw new ValidationError(fieldName, `Must match ${args.pattern}`, [{ arg: 'pattern', value: args.pattern }]) } if (args.format) { const pluginOptions = options.pluginOptions || {} const formats = { ...defaultFormats, ...(pluginOptions.formats || {}) } const formatter = formats[args.format] if (!formatter) { throw new ValidationError(fieldName, `Invalid format type ${args.format}`, [{ arg: 'format', value: args.format }]) } try { formatter(value, args) // Will throw if invalid } catch (e) { throw new ValidationError(fieldName, e.message, [{ arg: 'format', value: args.format }]) } } } module.exports = { ConstraintStringType, validate }