Description
Hello, I defined a custom validator, as many others i have working correctly, but i am getting an error:
(0, is_valid_order_generation_flow_1.IsValidOrderGenerationFlow)(),
^
TypeError: (0 , is_valid_order_generation_flow_1.IsValidOrderGenerationFlow) is not a function
at Object. (E:\proyectos personales\centr0\backend\universal-clothing-api\node_modules\universal-clothing-shared\dist\order\CreateOrderRequestDTO.js:27:69)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Object.require.extensions. [as .js] (E:\proyectos personales\centr0\backend\universal-clothing-api\node_modules\ts-node\src\index.ts:1608:43)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Function.Module._load (node:internal/modules/cjs/loader:1023:12)
at Module.require (node:internal/modules/cjs/loader:1235:19)
at require (node:internal/modules/helpers:176:18)
at Object. (E:\proyectos personales\centr0\backend\universal-clothing-api\node_modules\universal-clothing-shared\dist\order\index.js:18:14)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
I am using the validator in my express api, which imports it from an npm package i published where i expose types and validators to share between my frontend and backend. Here is how the validator looks in the shared types library:
`import { ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, registerDecorator } from "class-validator";
import { allowedOrderGenerationFlows } from "../../order";
@ValidatorConstraint({ name: 'isValidOrderGenerationFlow', async: false })
class IsValidOrderGenerationFlowConstraint implements ValidatorConstraintInterface {
validate(value: any, args?: ValidationArguments | undefined) {
return allowedOrderGenerationFlows.includes(value);
}
defaultMessage?(validationArguments?: ValidationArguments | undefined): string {
return `Flow de generacion de orden: ${validationArguments?.value} es invalido. Valores posibles son ${allowedOrderGenerationFlows.join(', ')}`;
}
}
export function IsValidOrderGenerationFlow(validationOptions?: ValidationOptions) {
return function(object: Object, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName,
constraints: [],
options: validationOptions,
validator: IsValidOrderGenerationFlowConstraint,
});
}
}`
Here is the DTO in the shared library that uses it:
`import { ArrayNotEmpty, IsEmail, IsOptional, IsString } from "class-validator";
import { OrderGenerationFlow } from ".";
import { IsValidOrderGenerationFlow } from "../typeorm/custom-validators/is-valid-order-generation-flow";
export class CreateOrderRequestDTO {
@ArrayNotEmpty({ message: 'No puede ser un array vacio' })
@IsString({ message: 'Cada elemento debe ser un string', each: true })
items!: string[];
@IsValidOrderGenerationFlow()
orderGenerationFlow!: OrderGenerationFlow;
@IsOptional()
@IsEmail(undefined, { message: "Debe ser un email valido" })
clientEmail?: string;
}`
And here is how i am using it in my backend, just like all other DTOs i use which don't fail, even those using a custom validator:
const requestDTO = await validateRequestBody(OrderDTO.CreateOrderRequestDTO, req.body);
I have another custom validator which doesn't fail which is almost identical to this one, in terms of the validation it performs and the usage inside a DTO. This doesn't fail:
`import { ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, registerDecorator } from "class-validator";
import { allowedProductConditions } from "../../product";
@ValidatorConstraint({ name: 'isValidProductCondition', async: false })
class IsValidProductConditionConstraint implements ValidatorConstraintInterface {
validate(condition: any, args: ValidationArguments) {
return allowedProductConditions.includes(condition);
}
defaultMessage?(validationArguments?: ValidationArguments | undefined): string {
return `Invalid product condition. Allowed product conditions: ${allowedProductConditions.join(', ')}`;
}
}
export function IsValidProductCondition(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName,
options: validationOptions,
constraints: [],
validator: IsValidProductConditionConstraint,
});
}
}`
DTO usage:
`
import { Type } from 'class-transformer';
import { ArrayNotEmpty, IsArray, IsBoolean, IsNotEmptyObject, IsNumber, IsOptional, IsPositive, IsString, MinLength, ValidateNested } from 'class-validator';
import { AssignSizeToProductDTO, BaseProductConditionDTO, ProductCondition, ProductSizeDTO } from '.';
import { BaseStoreDTO } from '../store';
import { IsValidProductCondition } from '../typeorm/custom-validators/is-valid-product-condition';
import { ProductBaseCategoryDTO } from './ProductCategory';
export class CreateProductDTO {
@IsString()
title!: string;
@IsPositive()
price!: number;
@IsValidProductCondition()
condition!: ProductCondition;
@IsNotEmptyObject(undefined, { message: '\'size\' tiene que ser un objeto' })
@ValidateNested()
@Type(() => AssignSizeToProductDTO)
size!: AssignSizeToProductDTO
@IsNumber()
categoryId!: number;
@IsOptional()
@IsString()
description?: string;
@IsOptional()
@IsString()
brand?: string;
@IsOptional()
@IsString()
color?: string;
}`
Please this is driving me nuts, any help is appreciated!