If I want to validate the role
which user post to api to create if is unique
of relation enterprise
@Injectable({ scope: Scope.REQUEST })
@ValidatorConstraint({ name: 'Ddd', async: true })
export class IsUnqiueForEnterpriseConstraint implements ValidatorConstraintInterface {
constructor(@Inject(REQUEST) private request: Request) {}
async validate(value: any, args: ValidationArguments) {
const { enterprise } = this.request.user as any
const { model } = args.constraints[0] as IParams;
if(!enterprise) return false;
if (!model) return false;
const repo = getManager().getRepository(model as ObjectType<any>);
const item = await repo.findOne({
[args.property]: value,
enterprise: { id: enterprise.id },
});
return !item;
}
defaultMessage(args: ValidationArguments) {
const { model } = args.constraints[0];
if (!model) {
return 'Model not been specified!';
}
return `${args.property} of ${model.name} must been unique!`;
}
}
export function IsUnqiueForEnterprise(params: IParams, validationOptions?: ValidationOptions) {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
target: object.constructor,
propertyName,
options: validationOptions,
constraints: [params],
validator: IsUnqiueForEnterpriseConstraint,
});
};
}
And in main.ts
I will container class-validator like follow
useContainer(app, { fallbackOnErrors: true });
and dto
@IsUnqiueForEnterprise({model: Role})
label!: string;
But in constraint request
is undefined
,how can I get it?
You should perform multiple steps:
1- Create a ContextInterceptor that injects user info into request when it has body (if you have post API then your request has body).
2- Use interceptor in RoleController or global.
3- create StripContextPipe to stripe context from request body to drop context after use in constraint.
4- use pipe on post method in RolesController.
5- create ContextAwareDto to extend createRoleDto from it.
6- read user form context in your constraint validator