Skip to content

Commit a662647

Browse files
author
Geoffroy Empain
committed
Implementation
1 parent 7343716 commit a662647

File tree

4 files changed

+39
-9
lines changed

4 files changed

+39
-9
lines changed

src/TransformOperationExecutor.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {ClassTransformOptions} from "./ClassTransformOptions";
22
import {defaultMetadataStorage} from "./storage";
33
import {TypeOptions} from "./metadata/ExposeExcludeOptions";
4-
import {ExposeMetadata} from "./metadata/ExposeMetadata";
54

65
export type TransformationType = "plainToClass"|"classToPlain"|"classToClass";
76

@@ -162,15 +161,15 @@ export class TransformOperationExecutor {
162161
if (!this.options.enableCircularCheck || !this.isCircular(subValue, level)) {
163162
let transformKey = this.transformationType === "plainToClass" ? newValueKey : key;
164163
let finalValue = this.transform(subSource, subValue, type, arrayType, isSubValueMap, level + 1);
165-
finalValue = this.applyCustomTransformations(finalValue, targetType, transformKey);
164+
finalValue = this.applyCustomTransformations(finalValue, targetType, transformKey, value);
166165
if (newValue instanceof Map) {
167166
newValue.set(newValueKey, finalValue);
168167
} else {
169168
newValue[newValueKey] = finalValue;
170169
}
171170
} else if (this.transformationType === "classToClass") {
172171
let finalValue = subValue;
173-
finalValue = this.applyCustomTransformations(finalValue, targetType, key);
172+
finalValue = this.applyCustomTransformations(finalValue, targetType, key, value);
174173
if (newValue instanceof Map) {
175174
newValue.set(newValueKey, finalValue);
176175
} else {
@@ -186,7 +185,7 @@ export class TransformOperationExecutor {
186185
}
187186
}
188187

189-
private applyCustomTransformations(value: any, target: Function, key: string) {
188+
private applyCustomTransformations(value: any, target: Function, key: string, obj: any) {
190189
let metadatas = defaultMetadataStorage.findTransformMetadatas(target, key, this.transformationType);
191190

192191
// apply versioning options
@@ -216,7 +215,7 @@ export class TransformOperationExecutor {
216215
}
217216

218217
metadatas.forEach(metadata => {
219-
value = metadata.transformFn(value);
218+
value = metadata.transformFn(value, obj);
220219
});
221220

222221
return value;

src/decorators.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {ClassTransformOptions} from "./ClassTransformOptions";
1010
/**
1111
* Defines a custom logic for value transformation.
1212
*/
13-
export function Transform(transformFn: (value: any) => any, options?: TransformOptions) {
13+
export function Transform(transformFn: (value: any, obj: any) => any, options?: TransformOptions) {
1414
return function(target: any, key: string) {
1515
const metadata = new TransformMetadata(target.constructor, key, transformFn, options);
1616
defaultMetadataStorage.addTransformMetadata(metadata);

src/metadata/TransformMetadata.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ export class TransformMetadata {
44

55
constructor(public target: Function,
66
public propertyName: string,
7-
public transformFn: (value: any) => any,
7+
public transformFn: (value: any, obj: any) => any,
88
public options: TransformOptions) {
99
}
1010

11-
}
11+
}

test/functional/custom-transform.spec.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,36 @@ describe("custom transformation decorator", () => {
123123
classedUser5.lastVisitDate.should.be.equal(new Date(plainUser.lastVisitDate).toString());
124124
});
125125

126+
it("@Transform decorator callback should be given the source object as second argument", () => {
127+
defaultMetadataStorage.clear();
128+
129+
let objArgToClass: any;
130+
let objArgToPlain: any;
131+
132+
class User {
133+
@Transform((value, obj) => {
134+
objArgToPlain = obj;
135+
return value;
136+
}, {toPlainOnly: true})
137+
@Transform((value, obj) => {
138+
objArgToClass = obj;
139+
return value;
140+
}, {toClassOnly: true})
141+
name: string;
142+
}
143+
144+
let plainUser = {
145+
name: "Johny Cage",
146+
};
147+
148+
const user = new User();
149+
user.name = "Johny Cage";
150+
151+
plainToClass(User, plainUser);
152+
classToPlain(user);
153+
154+
objArgToPlain.should.be.equal(user);
155+
objArgToClass.should.be.equal(plainUser);
156+
});
126157

127-
});
158+
});

0 commit comments

Comments
 (0)