import { registerDecorator, ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, } from "class-validator"; import { normalizeMoneyAmountString } from "src/utils/unicode-digits"; @ValidatorConstraint({ name: "isMoneyAmountString", async: false }) export class IsMoneyAmountStringConstraint implements ValidatorConstraintInterface { validate(value: unknown): boolean { if (value == null || value === "") return true; if (typeof value !== "string") return false; const n = normalizeMoneyAmountString(value); if (!n) return false; return /^\d+(\.\d+)?$/.test(n); } defaultMessage(): string { return "Must be a non-negative amount (digits only, optional decimal)."; } } export function IsMoneyAmountString(validationOptions?: ValidationOptions) { return (object: object, propertyName: string) => { registerDecorator({ target: object.constructor, propertyName, options: validationOptions, constraints: [], validator: IsMoneyAmountStringConstraint, }); }; }