UNPKG

decoval

Version:

DecoVal is a decorator-driven validation pattern that allows you to add validation rules directly to the properties of TypeScript classes, simplifying data control and increasing code readability and reusability.

44 lines (43 loc) 2.42 kB
import { ValidationError } from "./error/validation.error"; import { registerValidation } from "./register.validation"; export function DvArray(options = {}) { const { minLength = { value: 0, message: "The array must contain at least {minLength.value} elements." }, maxLength = { value: Infinity, message: "The array must contain at most {maxLength.value} elements." }, elementsType = { value: "any", message: "The array elements must be of type {elementsType.value}." }, allowedValues = { value: [], message: "The array elements must be one of the allowed values: {allowedValues.value.join(', ')}.", }, message = "The array contains invalid elements.", } = options; const interpolateMessage = (message, data) => { return message.replace(/{([^}]+)}/g, (_, key) => data[key] || ""); }; return function (target, propertyKey) { const alreadyApplied = Reflect.getMetadata("valarray:applied", target, propertyKey); if (alreadyApplied) { throw new Error(`The @ValArray decorator has already been applied to the field "${propertyKey}"`); } Reflect.defineMetadata("valarray:applied", true, target, propertyKey); registerValidation(target, propertyKey, (value) => { if (!Array.isArray(value)) { throw new ValidationError(interpolateMessage(`The field "${propertyKey}" must be an array.`, {})); } if (value.length < minLength.value) { throw new ValidationError(interpolateMessage(minLength.message, { minLength })); } if (value.length > maxLength.value) { throw new ValidationError(interpolateMessage(maxLength.message, { maxLength })); } if (elementsType.value !== "any") { for (const item of value) { if (typeof item !== elementsType.value) { throw new ValidationError(interpolateMessage(elementsType.message, { elementsType })); } } } if (allowedValues.value.length > 0) { for (const item of value) { if (!allowedValues.value.includes(item)) { throw new ValidationError(interpolateMessage(allowedValues.message || message, { allowedValues })); } } } }); }; }