Skip to content

Commit dff90ca

Browse files
authored
feat: expose current property name to transform function (#393)
1 parent 232ccce commit dff90ca

File tree

7 files changed

+38
-26
lines changed

7 files changed

+38
-26
lines changed

src/TransformOperationExecutor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ export class TransformOperationExecutor {
368368
}
369369

370370
metadatas.forEach(metadata => {
371-
value = metadata.transformFn(value, obj, transformationType);
371+
value = metadata.transformFn({ value, key, obj, type: transformationType });
372372
});
373373

374374
return value;

src/decorators/transform.decorator.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { defaultMetadataStorage } from '../storage';
2-
import { TransformOptions } from '../interfaces';
3-
import { TransformationType } from '../enums';
2+
import { TransformFnParams, TransformOptions } from '../interfaces';
43

54
/**
65
* Defines a custom logic for value transformation.
76
*
87
* Can be applied to properties only.
98
*/
109
export function Transform(
11-
transformFn: (value: any, obj: any, transformationType: TransformationType) => any,
10+
transformFn: (params: TransformFnParams) => any,
1211
options: TransformOptions = {}
1312
): PropertyDecorator {
1413
return function (target: any, propertyName: string | Symbol): void {

src/interfaces/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from './decorator-options/type-options.interface';
66
export * from './metadata/exclude-metadata.interface';
77
export * from './metadata/expose-metadata.interface';
88
export * from './metadata/transform-metadata.interface';
9+
export * from './metadata/transform-fn-params.interface';
910
export * from './metadata/type-metadata.interface';
1011
export * from './class-constructor.type';
1112
export * from './class-transformer-options.interface';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { TransformationType } from '../../enums';
2+
3+
export interface TransformFnParams {
4+
value: any;
5+
key: string;
6+
obj: any;
7+
type: TransformationType;
8+
}

src/interfaces/metadata/transform-metadata.interface.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { TransformationType } from '../../enums';
21
import { TransformOptions } from '..';
2+
import { TransformFnParams } from './transform-fn-params.interface';
33

44
/**
55
* This object represents metadata assigned to a property via the @Transform decorator.
@@ -15,7 +15,7 @@ export interface TransformMetadata {
1515
/**
1616
* The custom transformation function provided by the user in the @Transform decorator.
1717
*/
18-
transformFn: (value: any, obj: any, transformationType: TransformationType) => any;
18+
transformFn: (params: TransformFnParams) => any;
1919

2020
/**
2121
* Options passed to the @Transform operator for this property.

test/functional/custom-transform.spec.ts

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable @typescript-eslint/camelcase */
22
import 'reflect-metadata';
3-
import { classToClass, classToPlain, plainToClass } from '../../src/index';
3+
import { classToClass, classToPlain, plainToClass, TransformFnParams } from '../../src/index';
44
import { defaultMetadataStorage } from '../../src/storage';
55
import { Expose, Transform, Type } from '../../src/decorators';
66
import { TransformationType } from '../../src/enums';
@@ -12,7 +12,7 @@ describe('custom transformation decorator', () => {
1212

1313
class User {
1414
@Expose({ name: 'user_name' })
15-
@Transform(value => value.toUpperCase())
15+
@Transform(({ value }) => value.toUpperCase())
1616
name: string;
1717
}
1818

@@ -31,8 +31,8 @@ describe('custom transformation decorator', () => {
3131
id: number;
3232
name: string;
3333

34-
@Transform(value => value.toString(), { toPlainOnly: true })
35-
@Transform(value => dayjs(value), { toClassOnly: true })
34+
@Transform(({ value }) => value.toString(), { toPlainOnly: true })
35+
@Transform(({ value }) => dayjs(value), { toClassOnly: true })
3636
date: Date;
3737
}
3838

@@ -70,11 +70,11 @@ describe('custom transformation decorator', () => {
7070
name: string;
7171

7272
@Type(() => Date)
73-
@Transform(value => dayjs(value), { since: 1, until: 2 })
73+
@Transform(({ value }) => dayjs(value), { since: 1, until: 2 })
7474
date: Date;
7575

7676
@Type(() => Date)
77-
@Transform(value => value.toString(), { groups: ['user'] })
77+
@Transform(({ value }) => value.toString(), { groups: ['user'] })
7878
lastVisitDate: Date;
7979
}
8080

@@ -119,10 +119,12 @@ describe('custom transformation decorator', () => {
119119
it('@Transform decorator callback should be given correct arguments', () => {
120120
defaultMetadataStorage.clear();
121121

122+
let keyArg: string;
122123
let objArg: any;
123124
let typeArg: TransformationType;
124125

125-
function transformCallback(value: any, obj: any, type: TransformationType): any {
126+
function transformCallback({ value, key, obj, type }: TransformFnParams): any {
127+
keyArg = key;
126128
objArg = obj;
127129
typeArg = type;
128130
return value;
@@ -139,13 +141,15 @@ describe('custom transformation decorator', () => {
139141
};
140142

141143
plainToClass(User, plainUser);
144+
expect(keyArg).toBe('name');
142145
expect(objArg).toEqual(plainUser);
143146
expect(typeArg).toEqual(TransformationType.PLAIN_TO_CLASS);
144147

145148
const user = new User();
146149
user.name = 'Johny Cage';
147150

148151
classToPlain(user);
152+
expect(keyArg).toBe('name');
149153
expect(objArg).toEqual(user);
150154
expect(typeArg).toEqual(TransformationType.CLASS_TO_PLAIN);
151155
});
@@ -191,7 +195,7 @@ describe('custom transformation decorator', () => {
191195
public address: Address;
192196

193197
@Type(() => Hobby)
194-
@Transform(value => value.filter((hobby: any) => hobby.type === 'sport'), { toClassOnly: true })
198+
@Transform(({ value }) => value.filter((hobby: any) => hobby.type === 'sport'), { toClassOnly: true })
195199
public hobbies: Hobby[];
196200

197201
public age: number;
@@ -224,7 +228,7 @@ describe('custom transformation decorator', () => {
224228
}
225229

226230
class Programming extends Hobby {
227-
@Transform((value: string) => value.toUpperCase())
231+
@Transform(({ value }) => value.toUpperCase())
228232
specialAbility: string;
229233
}
230234

@@ -278,7 +282,7 @@ describe('custom transformation decorator', () => {
278282
}
279283

280284
class Programming extends Hobby {
281-
@Transform((value: string) => value.toUpperCase())
285+
@Transform(({ value }) => value.toUpperCase())
282286
specialAbility: string;
283287
}
284288

@@ -330,7 +334,7 @@ describe('custom transformation decorator', () => {
330334
}
331335

332336
class Programming extends Hobby {
333-
@Transform((value: string) => value.toUpperCase())
337+
@Transform(({ value }) => value.toUpperCase())
334338
specialAbility: string;
335339
}
336340

@@ -383,7 +387,7 @@ describe('custom transformation decorator', () => {
383387
}
384388

385389
class Programming extends Hobby {
386-
@Transform((value: string) => value.toUpperCase())
390+
@Transform(({ value }) => value.toUpperCase())
387391
specialAbility: string;
388392
}
389393

@@ -431,7 +435,7 @@ describe('custom transformation decorator', () => {
431435
}
432436

433437
class Programming extends Hobby {
434-
@Transform((value: string) => value.toUpperCase())
438+
@Transform(({ value }) => value.toUpperCase())
435439
specialAbility: string;
436440
}
437441

@@ -479,7 +483,7 @@ describe('custom transformation decorator', () => {
479483
}
480484

481485
class Programming extends Hobby {
482-
@Transform((value: string) => value.toUpperCase())
486+
@Transform(({ value }) => value.toUpperCase())
483487
specialAbility: string;
484488
}
485489

@@ -530,7 +534,7 @@ describe('custom transformation decorator', () => {
530534
}
531535

532536
class Programming extends Hobby {
533-
@Transform((value: string) => value.toUpperCase())
537+
@Transform(({ value }) => value.toUpperCase())
534538
specialAbility: string;
535539
}
536540

@@ -578,7 +582,7 @@ describe('custom transformation decorator', () => {
578582
}
579583

580584
class Programming extends Hobby {
581-
@Transform((value: string) => value.toUpperCase())
585+
@Transform(({ value }) => value.toUpperCase())
582586
specialAbility: string;
583587
}
584588

@@ -634,7 +638,7 @@ describe('custom transformation decorator', () => {
634638
}
635639

636640
class Programming extends Hobby {
637-
@Transform((value: string) => value.toUpperCase())
641+
@Transform(({ value }) => value.toUpperCase())
638642
specialAbility: string;
639643
}
640644

@@ -682,7 +686,7 @@ describe('custom transformation decorator', () => {
682686
}
683687

684688
class Programming extends Hobby {
685-
@Transform((value: string) => value.toUpperCase())
689+
@Transform(({ value }) => value.toUpperCase())
686690
specialAbility: string;
687691
}
688692

test/functional/inheritence.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe('inheritence', () => {
77
defaultMetadataStorage.clear();
88

99
class Contact {
10-
@Transform(value => value.toUpperCase())
10+
@Transform(({ value }) => value.toUpperCase())
1111
name: string;
1212
@Type(() => Date)
1313
birthDate: Date;
@@ -20,7 +20,7 @@ describe('inheritence', () => {
2020
}
2121

2222
class Student extends User {
23-
@Transform(value => value.toUpperCase())
23+
@Transform(({ value }) => value.toUpperCase())
2424
university: string;
2525
}
2626

0 commit comments

Comments
 (0)