mirror of
https://github.com/nestjs/nest.git
synced 2026-02-21 23:11:44 +00:00
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { Optional } from '../decorators';
|
|
import { ArgumentMetadata, BadRequestException } from '../index';
|
|
import { ValidatorOptions } from '../interfaces/external/validator-options.interface';
|
|
import { PipeTransform } from '../interfaces/features/pipe-transform.interface';
|
|
import { loadPackage } from '../utils/load-package.util';
|
|
import { isNil } from '../utils/shared.utils';
|
|
import { Injectable } from './../decorators/core/component.decorator';
|
|
|
|
export interface ValidationPipeOptions extends ValidatorOptions {
|
|
transform?: boolean;
|
|
disableErrorMessages?: boolean;
|
|
}
|
|
|
|
let classValidator: any = {};
|
|
let classTransformer: any = {};
|
|
|
|
@Injectable()
|
|
export class ValidationPipe implements PipeTransform<any> {
|
|
protected isTransformEnabled: boolean;
|
|
protected isDetailedOutputDisabled: boolean;
|
|
protected validatorOptions: ValidatorOptions;
|
|
|
|
constructor(@Optional() options?: ValidationPipeOptions) {
|
|
options = options || {};
|
|
const { transform, disableErrorMessages, ...validatorOptions } = options;
|
|
this.isTransformEnabled = !!transform;
|
|
this.validatorOptions = validatorOptions;
|
|
this.isDetailedOutputDisabled = disableErrorMessages;
|
|
|
|
const loadPkg = pkg => loadPackage(pkg, 'ValidationPipe');
|
|
classValidator = loadPkg('class-validator');
|
|
classTransformer = loadPkg('class-transformer');
|
|
}
|
|
|
|
public async transform(value, metadata: ArgumentMetadata) {
|
|
const { metatype } = metadata;
|
|
if (!metatype || !this.toValidate(metadata)) {
|
|
return value;
|
|
}
|
|
const entity = classTransformer.plainToClass(
|
|
metatype,
|
|
this.toEmptyIfNil(value),
|
|
);
|
|
const errors = await classValidator.validate(entity, this.validatorOptions);
|
|
if (errors.length > 0) {
|
|
throw new BadRequestException(
|
|
this.isDetailedOutputDisabled ? undefined : errors,
|
|
);
|
|
}
|
|
return this.isTransformEnabled
|
|
? entity
|
|
: Object.keys(this.validatorOptions).length > 0
|
|
? classTransformer.classToPlain(entity)
|
|
: value;
|
|
}
|
|
|
|
private toValidate(metadata: ArgumentMetadata): boolean {
|
|
const { metatype, type } = metadata;
|
|
if (type === 'custom') {
|
|
return false;
|
|
}
|
|
const types = [String, Boolean, Number, Array, Object];
|
|
return !types.find(t => metatype === t) && !isNil(metatype);
|
|
}
|
|
|
|
toEmptyIfNil<T = any, R = any>(value: T): R | {} {
|
|
return isNil(value) ? {} : value;
|
|
}
|
|
}
|