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.
37 lines (36 loc) • 1.75 kB
JavaScript
import { ValidationError } from "./error/validation.error";
import { registerValidation } from "./register.validation";
export function DvCustom(rules) {
if (!rules || (Array.isArray(rules) && rules.length === 0)) {
throw new Error("The 'rules' parameter of the @DvCustom decorator cannot be empty or undefined.");
}
const ruleList = Array.isArray(rules) ? rules : [rules];
for (const rule of ruleList) {
if (typeof rule !== "object" || rule === null) {
throw new Error("Each custom rule must be a valid object.");
}
if (typeof rule.validate !== "function") {
throw new Error("The 'validate' property of each rule must be a function.");
}
if (typeof rule.message !== "string" || rule.message.trim() === "") {
throw new Error("The 'message' property of each rule must be a non-empty string.");
}
}
return function (target, propertyKey) {
var _a;
const appliedDecorators = (_a = Reflect.getMetadata("valtcustom:applied", target, propertyKey)) !== null && _a !== void 0 ? _a : new Set();
if (appliedDecorators.has("DvCustom")) {
throw new Error(`The @DvCustom decorator has already been applied in the field "${propertyKey}".`);
}
appliedDecorators.add("DvCustom");
Reflect.defineMetadata("valcustom:applied", appliedDecorators, target, propertyKey);
registerValidation(target, propertyKey, (value) => {
for (const rule of ruleList) {
const isValid = rule.validate(value);
if (!isValid) {
throw new ValidationError(`[${propertyKey}] ${rule.message}`);
}
}
});
};
}