@@ -8,7 +8,7 @@ import {ValidationTypes} from "./ValidationTypes";
8
8
import { ConstraintMetadata } from "../metadata/ConstraintMetadata" ;
9
9
import { ValidationArguments } from "./ValidationArguments" ;
10
10
import { ValidationUtils } from "./ValidationUtils" ;
11
- import { isPromise } from "../utils" ;
11
+ import { isPromise , convertToArray } from "../utils" ;
12
12
13
13
/**
14
14
* Executes validation over given object.
@@ -225,8 +225,9 @@ export class ValidationExecutor {
225
225
return metadatas
226
226
. filter ( metadata => {
227
227
if ( metadata . each ) {
228
- if ( value instanceof Array ) {
229
- return ! value . every ( ( subValue : any ) => this . validator . validateValueByMetadata ( subValue , metadata ) ) ;
228
+ if ( value instanceof Array || value instanceof Set || value instanceof Map ) {
229
+ const arrayValue = convertToArray ( value ) ;
230
+ return ! arrayValue . every ( ( subValue : any ) => this . validator . validateValueByMetadata ( subValue , metadata ) ) ;
230
231
}
231
232
232
233
} else {
@@ -259,7 +260,7 @@ export class ValidationExecutor {
259
260
constraints : metadata . constraints
260
261
} ;
261
262
262
- if ( ! metadata . each || ! ( value instanceof Array ) ) {
263
+ if ( ! metadata . each || ! ( value instanceof Array || value instanceof Set || value instanceof Map ) ) {
263
264
const validatedValue = customConstraintMetadata . instance . validate ( value , validationArguments ) ;
264
265
if ( isPromise ( validatedValue ) ) {
265
266
const promise = validatedValue . then ( isValid => {
@@ -279,8 +280,10 @@ export class ValidationExecutor {
279
280
return ;
280
281
}
281
282
283
+ // convert set and map into array
284
+ const arrayValue = convertToArray ( value ) ;
282
285
// Validation needs to be applied to each array item
283
- const validatedSubValues = value . map ( ( subValue : any ) => customConstraintMetadata . instance . validate ( subValue , validationArguments ) ) ;
286
+ const validatedSubValues = arrayValue . map ( ( subValue : any ) => customConstraintMetadata . instance . validate ( subValue , validationArguments ) ) ;
284
287
const validationIsAsync = validatedSubValues
285
288
. some ( ( validatedSubValue : boolean | Promise < boolean > ) => isPromise ( validatedSubValue ) ) ;
286
289
@@ -338,33 +341,16 @@ export class ValidationExecutor {
338
341
339
342
const targetSchema = typeof metadata . target === "string" ? metadata . target as string : undefined ;
340
343
341
- if ( value instanceof Array ) {
342
- value . forEach ( ( subValue : any , index : number ) => {
344
+ if ( value instanceof Array || value instanceof Set || value instanceof Map ) {
345
+ // Treats Set as an array - as index of Set value is value itself and it is common case to have Object as value
346
+ const arrayLikeValue = value instanceof Set ? Array . from ( value ) : value ;
347
+ arrayLikeValue . forEach ( ( subValue : any , index : any ) => {
343
348
const validationError = this . generateValidationError ( value , subValue , index . toString ( ) ) ;
344
349
errors . push ( validationError ) ;
345
350
346
351
this . execute ( subValue , targetSchema , validationError . children ) ;
347
352
} ) ;
348
353
349
- } else if ( value instanceof Set ) {
350
- let index = 0 ;
351
- value . forEach ( ( subValue : any ) => {
352
- const validationError = this . generateValidationError ( value , subValue , index . toString ( ) ) ;
353
- errors . push ( validationError ) ;
354
-
355
- this . execute ( subValue , targetSchema , validationError . children ) ;
356
-
357
- ++ index ;
358
- } ) ;
359
-
360
- } else if ( value instanceof Map ) {
361
- value . forEach ( ( subValue : any , key : any ) => {
362
- const validationError = this . generateValidationError ( value , subValue , key . toString ( ) ) ;
363
- errors . push ( validationError ) ;
364
-
365
- this . execute ( subValue , targetSchema , validationError . children ) ;
366
- } ) ;
367
-
368
354
} else if ( value instanceof Object ) {
369
355
this . execute ( value , targetSchema , errors ) ;
370
356
0 commit comments