UNPKG

4.06 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const decorators_1 = require("../decorators");
5const core_1 = require("../decorators/core");
6const index_1 = require("../index");
7const load_package_util_1 = require("../utils/load-package.util");
8const shared_utils_1 = require("../utils/shared.utils");
9let classValidator = {};
10let classTransformer = {};
11let ValidationPipe = class ValidationPipe {
12 constructor(options) {
13 options = options || {};
14 const { transform, disableErrorMessages, transformOptions, validateCustomDecorators } = options, validatorOptions = tslib_1.__rest(options, ["transform", "disableErrorMessages", "transformOptions", "validateCustomDecorators"]);
15 this.isTransformEnabled = !!transform;
16 this.validatorOptions = validatorOptions;
17 this.transformOptions = transformOptions;
18 this.isDetailedOutputDisabled = disableErrorMessages;
19 this.validateCustomDecorators = validateCustomDecorators || false;
20 this.exceptionFactory =
21 options.exceptionFactory ||
22 (errors => new index_1.BadRequestException(this.isDetailedOutputDisabled ? undefined : errors));
23 classValidator = load_package_util_1.loadPackage('class-validator', 'ValidationPipe', () => require('class-validator'));
24 classTransformer = load_package_util_1.loadPackage('class-transformer', 'ValidationPipe', () => require('class-transformer'));
25 }
26 async transform(value, metadata) {
27 const { metatype } = metadata;
28 if (!metatype || !this.toValidate(metadata)) {
29 return value;
30 }
31 value = this.toEmptyIfNil(value);
32 const isPrimitive = this.isPrimitive(value);
33 this.stripProtoKeys(value);
34 let entity = classTransformer.plainToClass(metatype, value, this.transformOptions);
35 const originalEntity = entity;
36 const isCtorNotEqual = entity.constructor !== metatype;
37 if (isCtorNotEqual && !isPrimitive) {
38 entity.constructor = metatype;
39 }
40 else if (isCtorNotEqual) {
41 // when "entity" is a primitive value, we have to temporarily
42 // replace the entity to perform the validation against the original
43 // metatype defined inside the handler
44 entity = { constructor: metatype };
45 }
46 const errors = await classValidator.validate(entity, this.validatorOptions);
47 if (errors.length > 0) {
48 throw this.exceptionFactory(errors);
49 }
50 if (isPrimitive) {
51 // if the value is a primitive value and the validation process has been successfully completed
52 // we have to revert the original value passed through the pipe
53 entity = originalEntity;
54 }
55 return this.isTransformEnabled
56 ? entity
57 : Object.keys(this.validatorOptions).length > 0
58 ? classTransformer.classToPlain(entity, this.transformOptions)
59 : value;
60 }
61 toValidate(metadata) {
62 const { metatype, type } = metadata;
63 if (type === 'custom' && !this.validateCustomDecorators) {
64 return false;
65 }
66 const types = [String, Boolean, Number, Array, Object];
67 return !types.some(t => metatype === t) && !shared_utils_1.isNil(metatype);
68 }
69 toEmptyIfNil(value) {
70 return shared_utils_1.isNil(value) ? {} : value;
71 }
72 stripProtoKeys(value) {
73 delete value.__proto__;
74 const keys = Object.keys(value);
75 keys
76 .filter(key => typeof value[key] === 'object' && value[key])
77 .forEach(key => this.stripProtoKeys(value[key]));
78 }
79 isPrimitive(value) {
80 return ['number', 'boolean', 'string'].includes(typeof value);
81 }
82};
83ValidationPipe = tslib_1.__decorate([
84 core_1.Injectable(),
85 tslib_1.__param(0, decorators_1.Optional()),
86 tslib_1.__metadata("design:paramtypes", [Object])
87], ValidationPipe);
88exports.ValidationPipe = ValidationPipe;