-
-
Notifications
You must be signed in to change notification settings - Fork 7.7k
/
validation.pipe.ts
69 lines (61 loc) · 2.34 KB
/
validation.pipe.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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.some(t => metatype === t) && !isNil(metatype);
}
toEmptyIfNil<T = any, R = any>(value: T): R | {} {
return isNil(value) ? {} : value;
}
}