Skip to content

Commit e95d5ad

Browse files
committed
feat(decorator): add plainToClass decorator
1 parent 7343716 commit e95d5ad

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/decorators.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,22 @@ export function TransformClassToClass(params?: ClassTransformOptions): Function
8686
return isPromise ? result.then((data: any) => classTransformer.classToClass(data, params)) : classTransformer.classToClass(result, params);
8787
};
8888
};
89+
}
90+
91+
/**
92+
* Return the class instance only with the exposed properties.
93+
*/
94+
export function TransformPlainToClass(classType: any, params?: ClassTransformOptions): Function {
95+
96+
return function (target: Function, propertyKey: string, descriptor: PropertyDescriptor) {
97+
const classTransformer: ClassTransformer = new ClassTransformer();
98+
const originalMethod = descriptor.value;
99+
100+
descriptor.value = function(...args: any[]) {
101+
const result: any = originalMethod.apply(this, args);
102+
const isPromise = !!result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function";
103+
104+
return isPromise ? result.then((data: any) => classTransformer.plainToClass(classType, data, params)) : classTransformer.plainToClass(classType, result, params);
105+
};
106+
};
89107
}

test/functional/transformer-method.spec.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import "reflect-metadata";
22
import {defaultMetadataStorage} from "../../src/storage";
3-
import {Exclude, Expose, TransformClassToPlain, TransformClassToClass} from "../../src/decorators";
3+
import { Exclude, Expose, TransformClassToPlain, TransformClassToClass, TransformPlainToClass } from "../../src/decorators";
44
import {expect} from "chai";
55

66
describe("transformer methods decorator", () => {
@@ -50,6 +50,49 @@ describe("transformer methods decorator", () => {
5050
expect(result).to.be.instanceof(User);
5151
});
5252

53+
it("should expose non configuration properties and return User instance class instead of plain object", () => {
54+
defaultMetadataStorage.clear();
55+
56+
@Exclude()
57+
class User {
58+
59+
id: number;
60+
61+
@Expose()
62+
firstName: string;
63+
64+
@Expose()
65+
lastName: string;
66+
67+
password: string;
68+
}
69+
70+
class UserController {
71+
72+
@TransformPlainToClass(User)
73+
getUser() {
74+
const user: any = {};
75+
user.firstName = "Snir";
76+
user.lastName = "Segal";
77+
user.password = "imnosuperman";
78+
79+
return user;
80+
}
81+
}
82+
83+
const controller = new UserController();
84+
85+
const result = controller.getUser();
86+
expect(result.password).to.be.undefined;
87+
88+
const user = new User();
89+
user.firstName = "Snir";
90+
user.lastName = "Segal";
91+
92+
expect(result).to.be.eql(user);
93+
expect(result).to.be.instanceof(User);
94+
});
95+
5396
it("should expose non configuration properties", () => {
5497
defaultMetadataStorage.clear();
5598

0 commit comments

Comments
 (0)