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.
66 lines (50 loc) • 2.41 kB
text/typescript
import { IsDate } from "../helpers/date";
import { ValDateOptions } from "../types/dv/dv-date";
import { ValidationError } from "./error/validation.error";
import { registerValidation } from "./register.validation";
import { skipValidation } from "./skip/skip.validation";
export function DvDate(options: ValDateOptions = {}) {
const { minDate, maxDate, past, future } = options;
const min = minDate instanceof Date ? minDate : minDate?.value;
const max = maxDate instanceof Date ? maxDate : maxDate?.value;
const minMessage =
typeof minDate === "object" && "message" in minDate
? minDate.message
: `The date must be after ${min?.toLocaleDateString()}`;
const maxMessage =
typeof maxDate === "object" && "message" in maxDate
? maxDate.message
: `The date must be before ${max?.toLocaleDateString()}`;
const isPast = typeof past === "object" ? past.value : past;
const isFuture = typeof future === "object" ? future.value : future;
const pastMessage = typeof past === "object" && "message" in past ? past.message : `The date must be in the past`;
const futureMessage =
typeof future === "object" && "message" in future ? future.message : `A data deve estar no futuro`;
return function (target: any, propertyKey: string) {
const alreadyApplied = Reflect.getMetadata("valdate:applied", target, propertyKey);
if (alreadyApplied) {
throw new Error(`The @ValDate decorator has already been applied to the field"${propertyKey}"`);
}
Reflect.defineMetadata("valdate:applied", true, target, propertyKey);
IsDate("Field must be a valid date")(target, propertyKey);
registerValidation(target, propertyKey, (value: any) => {
// Se o valor não for uma data válida, lança um erro
if (!(value instanceof Date) || isNaN(value.getTime())) {
throw new ValidationError(`The "${propertyKey}" field must be a valid date.`);
}
if (min && value < min) {
throw new ValidationError(minMessage);
}
if (max && value > max) {
throw new ValidationError(maxMessage);
}
const now = new Date();
if (isPast && value >= now) {
throw new ValidationError(pastMessage);
}
if (isFuture && value <= now) {
throw new ValidationError(futureMessage);
}
});
};
}