@giraphql/plugin-validation
Version:
A GiraphQL plugin for adding argument validation
241 lines • 9.35 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.combine = exports.isBaseValidator = exports.createObjectValidator = exports.createArrayValidator = exports.isArrayValidator = exports.createStringValidator = exports.createDateValidator = exports.createBooleanValidator = exports.createBigintValidator = exports.createNumberValidator = exports.refine = void 0;
const zod = __importStar(require("zod"));
const baseValidations = ['refine', 'schema'];
const numberValidations = [
...baseValidations,
'int',
'max',
'min',
'negative',
'nonnegative',
'nonpositive',
'positive',
'type',
];
const bigIntValidations = [...baseValidations, 'type'];
const booleanValidations = [...baseValidations, 'type'];
const dateValidations = [...baseValidations, 'type'];
const stringValidations = [
...baseValidations,
'email',
'length',
'maxLength',
'minLength',
'regex',
'type',
'url',
'uuid',
];
const arrayValidations = [
...baseValidations,
'items',
'length',
'maxLength',
'minLength',
'type',
];
const objectValidations = [...baseValidations, 'type'];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function validatorCreator(type, validationNames, create) {
function check(options) {
if (typeof options !== 'object' || (options.type && options.type !== type)) {
return false;
}
const validations = Object.keys(options);
return validations.every((validation) => validationNames.includes(validation));
}
return (options) => {
if (check(options)) {
return create(options);
}
return null;
};
}
function refine(originalValidator, options) {
var _a;
if (!options) {
return originalValidator;
}
if (typeof options === 'function') {
return originalValidator.refine(options);
}
let validator = originalValidator;
// TODO find a better way to merge array fields
// eslint-disable-next-line no-underscore-dangle
if (options.schema && options.schema._def.typeName === 'ZodArray') {
validator = originalValidator.refine((value) => { var _a; return (_a = options.schema) === null || _a === void 0 ? void 0 : _a.parse(value); });
}
else if (options.schema) {
validator = originalValidator.and(options.schema);
}
if (!options.refine) {
return validator;
}
if (typeof options.refine === 'function') {
return validator.refine(options.refine);
}
if (typeof ((_a = options.refine) === null || _a === void 0 ? void 0 : _a[0]) === 'function') {
return validator.refine(...options.refine);
}
const refinements = options.refine;
return refinements.reduce((prev, [refineFn, opts]) => prev.refine(refineFn, opts), validator);
}
exports.refine = refine;
exports.createNumberValidator = validatorCreator('number', numberValidations, (options) => {
let validator = zod.number();
if (options.min) {
validator = Array.isArray(options.min)
? validator.min(Number(options.min[0]), options.min[1])
: validator.min(Number(options.min));
}
if (options.max) {
validator = Array.isArray(options.max)
? validator.max(Number(options.max[0]), options.max[1])
: validator.max(Number(options.max));
}
const booleanConstraints = [
'int',
'negative',
'nonnegative',
'positive',
'nonpositive',
];
for (const constraint of booleanConstraints) {
if (options[constraint]) {
const value = options[constraint];
validator = validator[constraint](Array.isArray(value) ? value[1] : {});
}
}
return refine(validator, options);
});
exports.createBigintValidator = validatorCreator('bigint', bigIntValidations, (options) => refine(zod.bigint(), options));
exports.createBooleanValidator = validatorCreator('boolean', booleanValidations, (options) => refine(zod.boolean(), options));
exports.createDateValidator = validatorCreator('date', dateValidations, (options) => refine(zod.date(), options));
exports.createStringValidator = validatorCreator('string', stringValidations, (options) => {
let validator = zod.string();
if (options.length !== undefined) {
validator = Array.isArray(options.length)
? validator.length(options.length[0], options.length[1])
: validator.length(options.length);
}
if (options.minLength) {
validator = Array.isArray(options.minLength)
? validator.min(options.minLength[0], options.minLength[1])
: validator.min(options.minLength);
}
if (options.maxLength) {
validator = Array.isArray(options.maxLength)
? validator.max(options.maxLength[0], options.maxLength[1])
: validator.max(options.maxLength);
}
if (options.regex) {
validator = Array.isArray(options.regex)
? validator.regex(options.regex[0], options.regex[1])
: validator.regex(options.regex);
}
const booleanConstraints = ['email', 'url', 'uuid'];
for (const constraint of booleanConstraints) {
if (options[constraint]) {
const value = options[constraint];
validator = validator[constraint](Array.isArray(value) ? value[1] : {});
}
}
return refine(validator, options);
});
function isArrayValidator(options) {
if (typeof options !== 'object' || (options.type && options.type !== 'array')) {
return false;
}
const validations = Object.keys(options);
return validations.every((validation) => arrayValidations.includes(validation));
}
exports.isArrayValidator = isArrayValidator;
function createArrayValidator(options, items) {
let validator = items.array();
if (options.length !== undefined) {
validator = Array.isArray(options.length)
? validator.length(options.length[0], options.length[1].message)
: validator.length(options.length);
}
if (options.minLength) {
validator = Array.isArray(options.minLength)
? validator.min(options.minLength[0], options.minLength[1])
: validator.min(options.minLength);
}
if (options.maxLength) {
validator = Array.isArray(options.maxLength)
? validator.max(options.maxLength[0], options.maxLength[1])
: validator.max(options.maxLength);
}
return refine(validator, options);
}
exports.createArrayValidator = createArrayValidator;
exports.createObjectValidator = validatorCreator('object', objectValidations, (options) => refine(zod.object({}).passthrough(), options));
const validationCreators = [
exports.createNumberValidator,
exports.createBigintValidator,
exports.createBooleanValidator,
exports.createDateValidator,
exports.createStringValidator,
exports.createObjectValidator,
];
function isBaseValidator(options) {
if (typeof options === 'function') {
return true;
}
const validations = Object.keys(options);
return validations.every((validation) => baseValidations.includes(validation));
}
exports.isBaseValidator = isBaseValidator;
function combine(validators, required) {
const union = validators.length > 1
? zod.union(validators)
: validators[0];
return required ? union : union.optional().nullable();
}
exports.combine = combine;
function createZodSchema(optionsOrConstraint, required = false) {
const options = Array.isArray(optionsOrConstraint) || typeof optionsOrConstraint === 'function'
? { refine: optionsOrConstraint }
: optionsOrConstraint;
if (!options) {
return zod.unknown();
}
if (isBaseValidator(options)) {
return combine([refine(zod.unknown(), options)], required);
}
const typeValidators = validationCreators
.map((create) => create(options))
.filter(Boolean);
if (isArrayValidator(options)) {
const items = options.items ? createZodSchema(options.items) : zod.unknown();
typeValidators.push(createArrayValidator(options, items));
}
if (typeValidators.length === 0) {
throw new Error(`No type validator can implement every constraint in (${Object.keys(options)})`);
}
return combine([...typeValidators], required);
}
exports.default = createZodSchema;
//# sourceMappingURL=createZodSchema.js.map