typestack / class-validator

Decorator-based property validation for classes.
MIT License
10.92k stars 787 forks source link

question: is there any way to give a conditional error message without repeating code in defaultMessage function. #2485

Open Rami-Ry opened 4 months ago

Rami-Ry commented 4 months ago

I am writing a custom validation decorator and I have a property that either could be a number, array, or a string depend on other property in the same class.

I am trying to give an error message depend on group of conditions, without replicating the same code in defaultMessage() function to avoid unnecessary repeated process. How can I achieve that?

import {
  registerDecorator,
  ValidationOptions,
  ValidationArguments,
} from 'class-validator';

export function FilterValue(validationOptions?: ValidationOptions) {
  return function (object: unknown, propertyName: string) {
    registerDecorator({
      name: 'FilterValue',
      target: object.constructor,
      propertyName: propertyName,
      constraints: ['filter-value'],
      options: validationOptions,
      validator: {
        validate(value: any, validationArgs: ValidationArguments) {
          const filter = (validationArgs.object as any).field;

          const numberFilters = [
            'eq',
            '!eq',
            'gt',
            '!gt',
            'gte',
            '!gte',
            'lt',
            '!lt',
            'lte',
            '!lte',
          ];

          if (numberFilters.includes(filter)) {
            if (typeof value == 'number') return true;
            return false;
          }

          const arrayFilters = ['in', '!in'];
          if (arrayFilters.includes(filter)) {
            if (Array.isArray(value)) return true;
            return false;
          }

          const stringFilters = ['between', '!between', 'before', 'after'];
          if (stringFilters.includes(filter)) {
            if (typeof value === 'string') return true;
            return false;
          }

          return false;
        },

        defaultMessage(args: ValidationArguments) {
          return `${args.property} here should be the error message depend on the conditions in the validate function.`;
        },
      },
    });
  };
}