@@ -2,15 +2,19 @@ import {ClassTransformOptions} from "./ClassTransformOptions";
2
2
import { defaultMetadataStorage } from "./storage" ;
3
3
import { TypeOptions } from "./metadata/ExposeExcludeOptions" ;
4
4
5
- export type TransformationType = "plainToClass" | "classToPlain" | "classToClass" ;
5
+ export enum TransformationType {
6
+ PLAIN_TO_CLASS ,
7
+ CLASS_TO_PLAIN ,
8
+ CLASS_TO_CLASS
9
+ }
6
10
7
11
export class TransformOperationExecutor {
8
12
9
13
// -------------------------------------------------------------------------
10
14
// Private Properties
11
15
// -------------------------------------------------------------------------
12
16
13
- private transformedTypesMap = new Map < Object , { level : number , object : Object } > ( ) ;
17
+ private transformedTypesMap = new Map < Object , { level : number , object : Object } > ( ) ;
14
18
15
19
// -------------------------------------------------------------------------
16
20
// Constructor
@@ -32,7 +36,7 @@ export class TransformOperationExecutor {
32
36
level : number = 0 ) {
33
37
34
38
if ( value instanceof Array || value instanceof Set ) {
35
- const newValue = arrayType && this . transformationType === "plainToClass" ? new ( arrayType as any ) ( ) : [ ] ;
39
+ const newValue = arrayType && this . transformationType === TransformationType . PLAIN_TO_CLASS ? new ( arrayType as any ) ( ) : [ ] ;
36
40
( value as any [ ] ) . forEach ( ( subValue , index ) => {
37
41
const subSource = source ? source [ index ] : undefined ;
38
42
if ( ! this . options . enableCircularCheck || ! this . isCircular ( subValue , level ) ) {
@@ -42,7 +46,7 @@ export class TransformOperationExecutor {
42
46
} else {
43
47
newValue . push ( value ) ;
44
48
}
45
- } else if ( this . transformationType === "classToClass" ) {
49
+ } else if ( this . transformationType === TransformationType . CLASS_TO_CLASS ) {
46
50
if ( newValue instanceof Set ) {
47
51
newValue . add ( subValue ) ;
48
52
} else {
@@ -73,17 +77,17 @@ export class TransformOperationExecutor {
73
77
} else if ( value instanceof Object ) {
74
78
75
79
// try to guess the type
76
- if ( ! targetType && value . constructor !== Object /* && operationType === "classToPlain" */ ) targetType = value . constructor ;
80
+ if ( ! targetType && value . constructor !== Object /* && TransformationType === TransformationType.CLASS_TO_PLAIN */ ) targetType = value . constructor ;
77
81
if ( ! targetType && source ) targetType = source . constructor ;
78
82
79
83
if ( this . options . enableCircularCheck ) {
80
84
// add transformed type to prevent circular references
81
- this . transformedTypesMap . set ( value , { level : level , object : value } ) ;
85
+ this . transformedTypesMap . set ( value , { level : level , object : value } ) ;
82
86
}
83
87
84
88
const keys = this . getKeys ( targetType , value ) ;
85
89
let newValue : any = source ? source : { } ;
86
- if ( ! source && ( this . transformationType === "plainToClass" || this . transformationType === "classToClass" ) ) {
90
+ if ( ! source && ( this . transformationType === TransformationType . PLAIN_TO_CLASS || this . transformationType === TransformationType . CLASS_TO_CLASS ) ) {
87
91
if ( isMap ) {
88
92
newValue = new Map ( ) ;
89
93
} else if ( targetType ) {
@@ -98,14 +102,14 @@ export class TransformOperationExecutor {
98
102
99
103
let valueKey = key , newValueKey = key , propertyName = key ;
100
104
if ( ! this . options . ignoreDecorators && targetType ) {
101
- if ( this . transformationType === "plainToClass" ) {
105
+ if ( this . transformationType === TransformationType . PLAIN_TO_CLASS ) {
102
106
const exposeMetadata = defaultMetadataStorage . findExposeMetadataByCustomName ( targetType , key ) ;
103
107
if ( exposeMetadata ) {
104
108
propertyName = exposeMetadata . propertyName ;
105
109
newValueKey = exposeMetadata . propertyName ;
106
110
}
107
111
108
- } else if ( this . transformationType === "classToPlain" || this . transformationType === "classToClass" ) {
112
+ } else if ( this . transformationType === TransformationType . CLASS_TO_PLAIN || this . transformationType === TransformationType . CLASS_TO_CLASS ) {
109
113
const exposeMetadata = defaultMetadataStorage . findExposeMetadata ( targetType , key ) ;
110
114
if ( exposeMetadata && exposeMetadata . options && exposeMetadata . options . name )
111
115
newValueKey = exposeMetadata . options . name ;
@@ -130,7 +134,7 @@ export class TransformOperationExecutor {
130
134
} else if ( targetType ) {
131
135
const metadata = defaultMetadataStorage . findTypeMetadata ( targetType , propertyName ) ;
132
136
if ( metadata ) {
133
- const options : TypeOptions = { newObject : newValue , object : value , property : propertyName } ;
137
+ const options : TypeOptions = { newObject : newValue , object : value , property : propertyName } ;
134
138
type = metadata . typeFunction ( options ) ;
135
139
isSubValueMap = isSubValueMap || metadata . reflectedType === Map ;
136
140
} else if ( this . options . targetMaps ) { // try to find a type in target maps
@@ -142,34 +146,34 @@ export class TransformOperationExecutor {
142
146
143
147
// if value is an array try to get its custom array type
144
148
const arrayType = value [ valueKey ] instanceof Array ? this . getReflectedType ( targetType , propertyName ) : undefined ;
145
- // const subValueKey = operationType === "plainToClass" && newKeyName ? newKeyName : key;
149
+ // const subValueKey = TransformationType === TransformationType.PLAIN_TO_CLASS && newKeyName ? newKeyName : key;
146
150
const subSource = source ? source [ valueKey ] : undefined ;
147
151
148
152
// if its deserialization then type if required
149
153
// if we uncomment this types like string[] will not work
150
- // if (this.transformationType === "plainToClass" && !type && subValue instanceof Object && !(subValue instanceof Date))
154
+ // if (this.transformationType === TransformationType.PLAIN_TO_CLASS && !type && subValue instanceof Object && !(subValue instanceof Date))
151
155
// throw new Error(`Cannot determine type for ${(targetType as any).name }.${propertyName}, did you forget to specify a @Type?`);
152
156
153
157
// if newValue is a source object that has method that match newKeyName then skip it
154
158
if ( newValue . constructor . prototype ) {
155
159
const descriptor = Object . getOwnPropertyDescriptor ( newValue . constructor . prototype , newValueKey ) ;
156
- if ( ( this . transformationType === "plainToClass" || this . transformationType === "classToClass" )
157
- && ( newValue [ newValueKey ] instanceof Function || ( descriptor && ! descriptor . set ) ) ) // || operationType === "classToClass"
160
+ if ( ( this . transformationType === TransformationType . PLAIN_TO_CLASS || this . transformationType === TransformationType . CLASS_TO_CLASS )
161
+ && ( newValue [ newValueKey ] instanceof Function || ( descriptor && ! descriptor . set ) ) ) // || TransformationType === TransformationType.CLASS_TO_CLASS
158
162
continue ;
159
163
}
160
164
161
165
if ( ! this . options . enableCircularCheck || ! this . isCircular ( subValue , level ) ) {
162
- let transformKey = this . transformationType === "plainToClass" ? newValueKey : key ;
166
+ let transformKey = this . transformationType === TransformationType . PLAIN_TO_CLASS ? newValueKey : key ;
163
167
let finalValue = this . transform ( subSource , subValue , type , arrayType , isSubValueMap , level + 1 ) ;
164
- finalValue = this . applyCustomTransformations ( finalValue , targetType , transformKey , value ) ;
168
+ finalValue = this . applyCustomTransformations ( finalValue , targetType , transformKey , value , this . transformationType ) ;
165
169
if ( newValue instanceof Map ) {
166
170
newValue . set ( newValueKey , finalValue ) ;
167
171
} else {
168
172
newValue [ newValueKey ] = finalValue ;
169
173
}
170
- } else if ( this . transformationType === "classToClass" ) {
174
+ } else if ( this . transformationType === TransformationType . CLASS_TO_CLASS ) {
171
175
let finalValue = subValue ;
172
- finalValue = this . applyCustomTransformations ( finalValue , targetType , key , value ) ;
176
+ finalValue = this . applyCustomTransformations ( finalValue , targetType , key , value , this . transformationType ) ;
173
177
if ( newValue instanceof Map ) {
174
178
newValue . set ( newValueKey , finalValue ) ;
175
179
} else {
@@ -185,7 +189,7 @@ export class TransformOperationExecutor {
185
189
}
186
190
}
187
191
188
- private applyCustomTransformations ( value : any , target : Function , key : string , obj : any ) {
192
+ private applyCustomTransformations ( value : any , target : Function , key : string , obj : any , transformationType : TransformationType ) {
189
193
let metadatas = defaultMetadataStorage . findTransformMetadatas ( target , key , this . transformationType ) ;
190
194
191
195
// apply versioning options
@@ -208,14 +212,12 @@ export class TransformOperationExecutor {
208
212
} ) ;
209
213
} else {
210
214
metadatas = metadatas . filter ( metadata => {
211
- return ! metadata . options ||
212
- ! metadata . options . groups ||
213
- ! metadata . options . groups . length ;
215
+ return ! metadata . options || ! metadata . options . groups || ! metadata . options . groups . length ;
214
216
} ) ;
215
217
}
216
218
217
219
metadatas . forEach ( metadata => {
218
- value = metadata . transformFn ( value , obj ) ;
220
+ value = metadata . transformFn ( value , obj , transformationType ) ;
219
221
} ) ;
220
222
221
223
return value ;
@@ -254,7 +256,7 @@ export class TransformOperationExecutor {
254
256
255
257
// add all exposed to list of keys
256
258
let exposedProperties = defaultMetadataStorage . getExposedProperties ( target , this . transformationType ) ;
257
- if ( this . transformationType === "plainToClass" ) {
259
+ if ( this . transformationType === TransformationType . PLAIN_TO_CLASS ) {
258
260
exposedProperties = exposedProperties . map ( key => {
259
261
const exposeMetadata = defaultMetadataStorage . findExposeMetadata ( target , key ) ;
260
262
if ( exposeMetadata && exposeMetadata . options && exposeMetadata . options . name ) {
@@ -297,10 +299,7 @@ export class TransformOperationExecutor {
297
299
} else {
298
300
keys = keys . filter ( key => {
299
301
const exposeMetadata = defaultMetadataStorage . findExposeMetadata ( target , key ) ;
300
- return ! exposeMetadata ||
301
- ! exposeMetadata . options ||
302
- ! exposeMetadata . options . groups ||
303
- ! exposeMetadata . options . groups . length ;
302
+ return ! exposeMetadata || ! exposeMetadata . options || ! exposeMetadata . options . groups || ! exposeMetadata . options . groups . length ;
304
303
} ) ;
305
304
}
306
305
}
@@ -337,4 +336,4 @@ export class TransformOperationExecutor {
337
336
return this . options . groups . some ( optionGroup => groups . indexOf ( optionGroup ) !== - 1 ) ;
338
337
}
339
338
340
- }
339
+ }
0 commit comments