use*_*012 10 typescript class-validator nestjs
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,
});
};
}
Run Code Online (Sandbox Code Playgroud)
And in main.ts
I will container class-validator like follow
useContainer(app, { fallbackOnErrors: true });
Run Code Online (Sandbox Code Playgroud)
and dto
@IsUnqiueForEnterprise({model: Role})
label!: string;
Run Code Online (Sandbox Code Playgroud)
但受限的request是undefined,我怎样才能得到它呢?
小智 1
您应该执行多个步骤:
1-创建一个ContextInterceptor,当请求有正文时将用户信息注入到请求中(如果您有 post API,那么您的请求有正文)。
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class ContextInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest();
if (request.body) {
request.body.context = {
user: request.user,
};
}
return next.handle();
}
}
Run Code Online (Sandbox Code Playgroud)
2-在 RoleController 或全局中使用拦截器。
...
@Controller('roles')
@UseInterceptors(ContextInterceptor)
export class RolesController {
...
}
Run Code Online (Sandbox Code Playgroud)
3-创建StripContextPipe以从请求正文中剥离上下文,以在约束中使用后删除上下文。
/*
https://docs.nestjs.com/pipes
*/
import { PipeTransform, Injectable } from '@nestjs/common';
@Injectable()
export class StripContextPipe implements PipeTransform {
transform(value: any) {
if (value.context) {
// drop context key in the desired way
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { context, ...rest } = value;
return rest;
}
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
4-在 RolesController 中的 post 方法上使用管道。
@Post()
@UsePipes(new ValidationPipe({ whitelist: true }))
async create(
@Body(StripContextPipe)
createDto: createRoleDto,
@Res() res: Response,
) {
const record = await this.roleService.create(
createDto,
);
return res.success(record);
}
Run Code Online (Sandbox Code Playgroud)
5-创建ContextAwareDto以从中扩展createRoleDto 。
import { Allow } from 'class-validator';
export class ContextAwareDto {
@Allow()
context?: {
user: any;
};
}
export class createRoleDto extends ContextAwareDto {
...
@IsUnqiueForEnterprise({model: Role})
label!: string;
...
}
Run Code Online (Sandbox Code Playgroud)
6-在约束验证器中读取用户表单上下文
...
async validate(dto, validationArguments?: ContextValidationArguments) {
const user = validationArguments.object.context.user;
// you can load relations of user with find and repo
// repo.find({where:{id:user.id},relations: {enterpris:true}})
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2438 次 |
| 最近记录: |