mapper-factory 4.0.1 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -215
- package/dist/class.decorator.js +1 -1
- package/dist/field-decorators/array.decorator.d.ts +1 -1
- package/dist/field-decorators/array.decorator.js +1 -3
- package/dist/field-decorators/date.decorator.d.ts +1 -1
- package/dist/field-decorators/field.decorator.d.ts +2 -2
- package/dist/field-decorators/field.decorator.js +7 -3
- package/dist/field-decorators/object.decorator.d.ts +1 -1
- package/dist/functions.d.ts +13 -8
- package/dist/functions.js +15 -4
- package/dist/test.js +16 -28
- package/package.json +47 -47
package/README.md
CHANGED
|
@@ -1,215 +1,215 @@
|
|
|
1
|
-
# Mapper-Factory
|
|
2
|
-
|
|
3
|
-
Mapper-Factory is a fully documented TypeScript library that provides a simple and easy-to-use way to map objects from one type to another. With just a few lines of code, you can convert complex, nested objects into the desired format.
|
|
4
|
-
|
|
5
|
-
Work well on data structure and after enjoy the coding process :)
|
|
6
|
-
|
|
7
|
-
## Installation
|
|
8
|
-
|
|
9
|
-
To install the package, you can use npm by running the following command:
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
npm i mapper-factory
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Or using yarn
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
yarn add mapper-factory
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Problem to solve
|
|
22
|
-
|
|
23
|
-
We want to solve the problem to trasform a JSON object to a specific JS object adding custom properties, with integrated mapping. As example this JSON object:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
{
|
|
27
|
-
firstName: 'Rick',
|
|
28
|
-
lastName: 'Sanchez',
|
|
29
|
-
employees: [
|
|
30
|
-
{ firstName: 'Summer', lastName: 'Smith' },
|
|
31
|
-
{ firstName: 'Morty', lastName: 'Smith' }
|
|
32
|
-
],
|
|
33
|
-
rolesToMap: [ 'CEO', 'EMPLOYEE' ],
|
|
34
|
-
boss: { firstName: 'Jesus', lastName: 'Christ' }
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
must became a JS object:
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
User {
|
|
42
|
-
name: 'Rick',
|
|
43
|
-
surname: 'Sanchez',
|
|
44
|
-
employees: [
|
|
45
|
-
User { name: 'Summer', surname: 'Smith' },
|
|
46
|
-
User { name: 'Morty', surname: 'Smith' }
|
|
47
|
-
],
|
|
48
|
-
roles: [ 'CEO TEST TRASFORMER', 'EMPLOYEE TEST TRASFORMER' ],
|
|
49
|
-
boss: User { name: 'Jesus', surname: 'Christ' }
|
|
50
|
-
/** maybe some methods... */
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Usage V2
|
|
55
|
-
|
|
56
|
-
### Mapping simple objects
|
|
57
|
-
|
|
58
|
-
Your class must use _MapClass_ decorator and set an interface that extends _MapInterface<T>_
|
|
59
|
-
In this way your class could extend another, but continue using intellisense methods for YourClass
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
@MapClass()
|
|
63
|
-
class YourClass extends YourCustomClassToExtend {
|
|
64
|
-
/** YOUR PROPERTIES */
|
|
65
|
-
}
|
|
66
|
-
interface YourClass extends MapInterface<YourClass> { }
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
To get new _YourClass_ instance it's simple as always:
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
new YourClass();
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
but now you can easly mapping an object just using _MapInterface_ method _from_:
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
const yourInstance: YourClass = new YourClass().from(/** YOUR OBJECT TO MAP HERE*/);
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
and reverse your mapping using using _MapInterface_ method _toMap_:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
const reversedMapping: Object = yourInstance.toMap();
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
With _MapInterface_ you can use on your class instance also other methods:
|
|
88
|
-
|
|
89
|
-
- **_from_**: Create a new instance using model to map
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
const yourInstance: YourClass = new YourClass().from(/** YOUR OBJECT TO MAP HERE */);
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
- **_toMap_**: Create a JSON object using reverse mapping
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
const reverseMappedObject: Object = yourInstance.toMap();
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
- **_toModel_**: Create a new instance using same model of final JS object
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
const anotherInstance: YourClass = new YourClass.toModel(yourInstance);
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
- **_empty_**: Check if the object is empty
|
|
108
|
-
|
|
109
|
-
```
|
|
110
|
-
const isEmpty: boolean = yourInstance.empty();
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
- **_filled_**: Check if the object is filled
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
const isFilled: boolean = yourInstance.filled();
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
- **_get_**: Get specific property of the object
|
|
120
|
-
|
|
121
|
-
```
|
|
122
|
-
const specificProp: T = yourInstance.get('specificProp') as T;
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
- **_set_**: Set specific property of the object
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
yourInstance.set('specificProp', /** NEW VALUE FOR 'specificProp' */);
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
- **_copy_**: Deep copy of the object
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
const yourInstanceCopy: YourClass = yourInstance.copy();
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
After that, you can use _@MapField_ decorator over single property to specify the mapping. Let's dive into an example:
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
@MapClass()
|
|
141
|
-
class User {
|
|
142
|
-
|
|
143
|
-
@MapField({
|
|
144
|
-
src: 'firstName'
|
|
145
|
-
})
|
|
146
|
-
name: string;
|
|
147
|
-
|
|
148
|
-
@MapField({
|
|
149
|
-
src: 'obj.obj[0][1]',
|
|
150
|
-
transformer: (arr) => arr.map(role => role + " TEST TRASFORMER"),
|
|
151
|
-
reverser: (arr) => arr.map(role => role.replace(" TEST TRASFORMER", "")),
|
|
152
|
-
})
|
|
153
|
-
roles?: string[];
|
|
154
|
-
|
|
155
|
-
@MapField({
|
|
156
|
-
transformer: (user) => new User(user)
|
|
157
|
-
})
|
|
158
|
-
boss: User;
|
|
159
|
-
}
|
|
160
|
-
interface User extends MapInterface<User> { }
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
Inside _@MapField_ you can use:
|
|
164
|
-
|
|
165
|
-
- **_src_**: define a string of original field name (also using a path like _"obj.obj[0][1]"_)
|
|
166
|
-
- **_transform_**: function to transform data input in _constructor_ of the class
|
|
167
|
-
- **_reverse_**: function to transform data input in _toMap_ method of the class
|
|
168
|
-
|
|
169
|
-
In this example:
|
|
170
|
-
|
|
171
|
-
```
|
|
172
|
-
@MapClass()
|
|
173
|
-
class User {
|
|
174
|
-
|
|
175
|
-
id: string;
|
|
176
|
-
username: string;
|
|
177
|
-
|
|
178
|
-
@MapField({
|
|
179
|
-
src: 'firstName'
|
|
180
|
-
})
|
|
181
|
-
name: string;
|
|
182
|
-
|
|
183
|
-
@MapField({
|
|
184
|
-
src: 'lastName'
|
|
185
|
-
})
|
|
186
|
-
surname: string;
|
|
187
|
-
|
|
188
|
-
@MapField({
|
|
189
|
-
src: 'rolesToMap',
|
|
190
|
-
transformer: (arr) => arr.map(role => role + " TEST TRASFORMER"),
|
|
191
|
-
reverser: (arr) => arr.map(role => role.replace(" TEST TRASFORMER", "")),
|
|
192
|
-
})
|
|
193
|
-
roles?: string[];
|
|
194
|
-
|
|
195
|
-
@MapField({
|
|
196
|
-
transformer: (arr) => arr.map(user => new User(user))
|
|
197
|
-
})
|
|
198
|
-
employees?: User[];
|
|
199
|
-
|
|
200
|
-
@MapField({
|
|
201
|
-
transformer: (user) => new User(user)
|
|
202
|
-
})
|
|
203
|
-
boss?: User;
|
|
204
|
-
}
|
|
205
|
-
interface User extends MapInterface<User> { }
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
You can define a new User **_u_**, using two employees (using the same User model here but for a different object is the same):
|
|
209
|
-
|
|
210
|
-
```
|
|
211
|
-
let emp1: User = new User().from({ firstName: "Summer", lastName: "Smith" });
|
|
212
|
-
let emp2: User = new User().from({ firstName: "Morty", lastName: "Smith" });
|
|
213
|
-
|
|
214
|
-
let u = new User().from({ firstName: "Rick", lastName: "Sanchez", employees: [emp1.toMap(), emp2.toMap()], rolesToMap: ["CEO", "EMPLOYEE"] });
|
|
215
|
-
```
|
|
1
|
+
# Mapper-Factory
|
|
2
|
+
|
|
3
|
+
Mapper-Factory is a fully documented TypeScript library that provides a simple and easy-to-use way to map objects from one type to another. With just a few lines of code, you can convert complex, nested objects into the desired format.
|
|
4
|
+
|
|
5
|
+
Work well on data structure and after enjoy the coding process :)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
To install the package, you can use npm by running the following command:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
npm i mapper-factory
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or using yarn
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
yarn add mapper-factory
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Problem to solve
|
|
22
|
+
|
|
23
|
+
We want to solve the problem to trasform a JSON object to a specific JS object adding custom properties, with integrated mapping. As example this JSON object:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
{
|
|
27
|
+
firstName: 'Rick',
|
|
28
|
+
lastName: 'Sanchez',
|
|
29
|
+
employees: [
|
|
30
|
+
{ firstName: 'Summer', lastName: 'Smith' },
|
|
31
|
+
{ firstName: 'Morty', lastName: 'Smith' }
|
|
32
|
+
],
|
|
33
|
+
rolesToMap: [ 'CEO', 'EMPLOYEE' ],
|
|
34
|
+
boss: { firstName: 'Jesus', lastName: 'Christ' }
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
must became a JS object:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
User {
|
|
42
|
+
name: 'Rick',
|
|
43
|
+
surname: 'Sanchez',
|
|
44
|
+
employees: [
|
|
45
|
+
User { name: 'Summer', surname: 'Smith' },
|
|
46
|
+
User { name: 'Morty', surname: 'Smith' }
|
|
47
|
+
],
|
|
48
|
+
roles: [ 'CEO TEST TRASFORMER', 'EMPLOYEE TEST TRASFORMER' ],
|
|
49
|
+
boss: User { name: 'Jesus', surname: 'Christ' }
|
|
50
|
+
/** maybe some methods... */
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Usage V2
|
|
55
|
+
|
|
56
|
+
### Mapping simple objects
|
|
57
|
+
|
|
58
|
+
Your class must use _MapClass_ decorator and set an interface that extends _MapInterface<T>_
|
|
59
|
+
In this way your class could extend another, but continue using intellisense methods for YourClass
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
@MapClass()
|
|
63
|
+
class YourClass extends YourCustomClassToExtend {
|
|
64
|
+
/** YOUR PROPERTIES */
|
|
65
|
+
}
|
|
66
|
+
interface YourClass extends MapInterface<YourClass> { }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
To get new _YourClass_ instance it's simple as always:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
new YourClass();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
but now you can easly mapping an object just using _MapInterface_ method _from_:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
const yourInstance: YourClass = new YourClass().from(/** YOUR OBJECT TO MAP HERE*/);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
and reverse your mapping using using _MapInterface_ method _toMap_:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
const reversedMapping: Object = yourInstance.toMap();
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
With _MapInterface_ you can use on your class instance also other methods:
|
|
88
|
+
|
|
89
|
+
- **_from_**: Create a new instance using model to map
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
const yourInstance: YourClass = new YourClass().from(/** YOUR OBJECT TO MAP HERE */);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- **_toMap_**: Create a JSON object using reverse mapping
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
const reverseMappedObject: Object = yourInstance.toMap();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- **_toModel_**: Create a new instance using same model of final JS object
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
const anotherInstance: YourClass = new YourClass.toModel(yourInstance);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- **_empty_**: Check if the object is empty
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
const isEmpty: boolean = yourInstance.empty();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- **_filled_**: Check if the object is filled
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
const isFilled: boolean = yourInstance.filled();
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- **_get_**: Get specific property of the object
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
const specificProp: T = yourInstance.get('specificProp') as T;
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- **_set_**: Set specific property of the object
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
yourInstance.set('specificProp', /** NEW VALUE FOR 'specificProp' */);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- **_copy_**: Deep copy of the object
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
const yourInstanceCopy: YourClass = yourInstance.copy();
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
After that, you can use _@MapField_ decorator over single property to specify the mapping. Let's dive into an example:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
@MapClass()
|
|
141
|
+
class User {
|
|
142
|
+
|
|
143
|
+
@MapField({
|
|
144
|
+
src: 'firstName'
|
|
145
|
+
})
|
|
146
|
+
name: string;
|
|
147
|
+
|
|
148
|
+
@MapField({
|
|
149
|
+
src: 'obj.obj[0][1]',
|
|
150
|
+
transformer: (arr) => arr.map(role => role + " TEST TRASFORMER"),
|
|
151
|
+
reverser: (arr) => arr.map(role => role.replace(" TEST TRASFORMER", "")),
|
|
152
|
+
})
|
|
153
|
+
roles?: string[];
|
|
154
|
+
|
|
155
|
+
@MapField({
|
|
156
|
+
transformer: (user) => new User(user)
|
|
157
|
+
})
|
|
158
|
+
boss: User;
|
|
159
|
+
}
|
|
160
|
+
interface User extends MapInterface<User> { }
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Inside _@MapField_ you can use:
|
|
164
|
+
|
|
165
|
+
- **_src_**: define a string of original field name (also using a path like _"obj.obj[0][1]"_)
|
|
166
|
+
- **_transform_**: function to transform data input in _constructor_ of the class
|
|
167
|
+
- **_reverse_**: function to transform data input in _toMap_ method of the class
|
|
168
|
+
|
|
169
|
+
In this example:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
@MapClass()
|
|
173
|
+
class User {
|
|
174
|
+
|
|
175
|
+
id: string;
|
|
176
|
+
username: string;
|
|
177
|
+
|
|
178
|
+
@MapField({
|
|
179
|
+
src: 'firstName'
|
|
180
|
+
})
|
|
181
|
+
name: string;
|
|
182
|
+
|
|
183
|
+
@MapField({
|
|
184
|
+
src: 'lastName'
|
|
185
|
+
})
|
|
186
|
+
surname: string;
|
|
187
|
+
|
|
188
|
+
@MapField({
|
|
189
|
+
src: 'rolesToMap',
|
|
190
|
+
transformer: (arr) => arr.map(role => role + " TEST TRASFORMER"),
|
|
191
|
+
reverser: (arr) => arr.map(role => role.replace(" TEST TRASFORMER", "")),
|
|
192
|
+
})
|
|
193
|
+
roles?: string[];
|
|
194
|
+
|
|
195
|
+
@MapField({
|
|
196
|
+
transformer: (arr) => arr.map(user => new User(user))
|
|
197
|
+
})
|
|
198
|
+
employees?: User[];
|
|
199
|
+
|
|
200
|
+
@MapField({
|
|
201
|
+
transformer: (user) => new User(user)
|
|
202
|
+
})
|
|
203
|
+
boss?: User;
|
|
204
|
+
}
|
|
205
|
+
interface User extends MapInterface<User> { }
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
You can define a new User **_u_**, using two employees (using the same User model here but for a different object is the same):
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
let emp1: User = new User().from({ firstName: "Summer", lastName: "Smith" });
|
|
212
|
+
let emp2: User = new User().from({ firstName: "Morty", lastName: "Smith" });
|
|
213
|
+
|
|
214
|
+
let u = new User().from({ firstName: "Rick", lastName: "Sanchez", employees: [emp1.toMap(), emp2.toMap()], rolesToMap: ["CEO", "EMPLOYEE"] });
|
|
215
|
+
```
|
package/dist/class.decorator.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { copy, empty, filled, from, get, objToModel, set, toMap } from "./functions";
|
|
1
|
+
import { copy, empty, filled, from, get, objToModel, set, toMap, } from "./functions";
|
|
2
2
|
export function MapClass() {
|
|
3
3
|
return function (constructor) {
|
|
4
4
|
constructor.prototype.from = from;
|
|
@@ -3,9 +3,7 @@ export function ArrayField(clsFactory, opt) {
|
|
|
3
3
|
const Ctor = clsFactory;
|
|
4
4
|
return MapField({
|
|
5
5
|
src: opt?.src,
|
|
6
|
-
transformer: (arr) => Array.isArray(arr)
|
|
7
|
-
? arr.map((item) => new Ctor().from(item))
|
|
8
|
-
: [],
|
|
6
|
+
transformer: (arr) => Array.isArray(arr) ? arr.map((item) => new Ctor().from(item)) : [],
|
|
9
7
|
reverser: (arr) => Array.isArray(arr) ? arr.map((item) => item.toMap()) : [],
|
|
10
8
|
});
|
|
11
9
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClassType } from
|
|
1
|
+
import { ClassType } from "../types";
|
|
2
2
|
export declare const MAP_FIELD: unique symbol;
|
|
3
3
|
export interface MapperMetadata<T = any> {
|
|
4
4
|
src?: keyof T;
|
|
@@ -12,7 +12,7 @@ export interface MapperMetadata<T = any> {
|
|
|
12
12
|
}
|
|
13
13
|
export declare function isClass(func: any): func is ClassType;
|
|
14
14
|
export declare function getPrototype(target: Record<string, unknown> | ClassType): any;
|
|
15
|
-
export declare const MapField: <T = any>({ transformer, reverser, src, initialize, }?: MapperMetadata<T>) =>
|
|
15
|
+
export declare const MapField: <T = any>({ transformer, reverser, src, initialize, }?: MapperMetadata<T>) => ((target: unknown, propertyKey: string | symbol) => void);
|
|
16
16
|
export declare const getMapFieldMetadataList: (target: Record<string, unknown> | ClassType | any) => {
|
|
17
17
|
[key: string]: MapperMetadata;
|
|
18
18
|
} | undefined;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
export const MAP_FIELD = Symbol(
|
|
1
|
+
export const MAP_FIELD = Symbol("MAP_FIELD");
|
|
2
2
|
export function isClass(func) {
|
|
3
|
-
return (typeof func ===
|
|
3
|
+
return (typeof func === "function" &&
|
|
4
4
|
/^class\s/.test(Function.prototype.toString.call(func)));
|
|
5
5
|
}
|
|
6
6
|
export function getPrototype(target) {
|
|
7
|
-
return isClass(target) || !target?.prototype
|
|
7
|
+
return isClass(target) || !target?.prototype
|
|
8
|
+
? !target?.constructor
|
|
9
|
+
? target
|
|
10
|
+
: target?.constructor
|
|
11
|
+
: target?.prototype;
|
|
8
12
|
}
|
|
9
13
|
export const MapField = ({ transformer, reverser, src, initialize = false, } = {}) => {
|
|
10
14
|
return (target, property) => {
|
package/dist/functions.d.ts
CHANGED
|
@@ -1,49 +1,54 @@
|
|
|
1
|
+
export interface MapperTarget {
|
|
2
|
+
[key: string]: any;
|
|
3
|
+
from?(obj: unknown): MapperTarget;
|
|
4
|
+
toMap?(): Record<string, unknown>;
|
|
5
|
+
}
|
|
1
6
|
/**
|
|
2
7
|
* Convert the instance of this class to JSON Object.
|
|
3
8
|
*
|
|
4
9
|
* @returns JSON object mapped considering metadata "src" and "reverser"
|
|
5
10
|
*/
|
|
6
|
-
export declare function toMap():
|
|
11
|
+
export declare function toMap(this: MapperTarget): Record<string, unknown>;
|
|
7
12
|
/**
|
|
8
13
|
* Convert a JSON Object to an instance of this class.
|
|
9
14
|
*
|
|
10
15
|
* @param obj JSON Object
|
|
11
16
|
* @returns Instance of this class
|
|
12
17
|
*/
|
|
13
|
-
export declare function objToModel(obj:
|
|
18
|
+
export declare function objToModel(this: MapperTarget, obj: Record<string, any>): MapperTarget;
|
|
14
19
|
/**
|
|
15
20
|
* Check if this instance is empty.
|
|
16
21
|
*
|
|
17
22
|
* @returns true or false
|
|
18
23
|
*/
|
|
19
|
-
export declare function empty(): boolean;
|
|
24
|
+
export declare function empty(this: MapperTarget): boolean;
|
|
20
25
|
/**
|
|
21
26
|
* Check if this instance is filled.
|
|
22
27
|
*
|
|
23
28
|
* @returns true or false
|
|
24
29
|
*/
|
|
25
|
-
export declare function filled(): boolean;
|
|
30
|
+
export declare function filled(this: MapperTarget): boolean;
|
|
26
31
|
/**
|
|
27
32
|
* GET property value from a string path.
|
|
28
33
|
*
|
|
29
34
|
* @param path String path
|
|
30
35
|
* @returns Value of the property
|
|
31
36
|
*/
|
|
32
|
-
export declare function get<T>(path: string): T;
|
|
37
|
+
export declare function get<T>(this: MapperTarget, path: string): T;
|
|
33
38
|
/**
|
|
34
39
|
* SET property value from a string path.
|
|
35
40
|
*
|
|
36
41
|
* @param path String path
|
|
37
42
|
* @param value Value of the property
|
|
38
43
|
*/
|
|
39
|
-
export declare function set(path: string, value:
|
|
44
|
+
export declare function set(this: MapperTarget, path: string, value: unknown): void;
|
|
40
45
|
/**
|
|
41
46
|
* Deep copy of the object caller
|
|
42
47
|
*/
|
|
43
|
-
export declare function copy<T>(): T;
|
|
48
|
+
export declare function copy<T extends MapperTarget>(this: T): T;
|
|
44
49
|
/**
|
|
45
50
|
* Constructor of the mapper.
|
|
46
51
|
*
|
|
47
52
|
* @param object object to be mapped considering metadata "src", "transformer" and "reverser"
|
|
48
53
|
*/
|
|
49
|
-
export declare function from(object: any):
|
|
54
|
+
export declare function from(this: MapperTarget, object: Record<string, any>): MapperTarget;
|
package/dist/functions.js
CHANGED
|
@@ -16,7 +16,7 @@ export function toMap() {
|
|
|
16
16
|
let finalValue;
|
|
17
17
|
if (metadata) {
|
|
18
18
|
if (Array.isArray(value) && !metadata.reverser) {
|
|
19
|
-
finalValue = value.map((item) => item?.toMap ? item.toMap() : item);
|
|
19
|
+
finalValue = value.map((item) => (item?.toMap ? item.toMap() : item));
|
|
20
20
|
}
|
|
21
21
|
else if (metadata.reverser) {
|
|
22
22
|
finalValue = metadata.reverser(value, this);
|
|
@@ -29,7 +29,15 @@ export function toMap() {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
else {
|
|
32
|
-
|
|
32
|
+
if (Array.isArray(value)) {
|
|
33
|
+
finalValue = value.map((item) => (item?.toMap ? item.toMap() : item));
|
|
34
|
+
}
|
|
35
|
+
else if (value?.toMap) {
|
|
36
|
+
finalValue = value.toMap();
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
finalValue = value;
|
|
40
|
+
}
|
|
33
41
|
}
|
|
34
42
|
if (finalValue !== undefined) {
|
|
35
43
|
setValueByPath(obj, src, finalValue);
|
|
@@ -94,7 +102,10 @@ export function set(path, value) {
|
|
|
94
102
|
* Deep copy of the object caller
|
|
95
103
|
*/
|
|
96
104
|
export function copy() {
|
|
97
|
-
|
|
105
|
+
if (this.from && this.toMap) {
|
|
106
|
+
return this.from(this.toMap());
|
|
107
|
+
}
|
|
108
|
+
return this;
|
|
98
109
|
}
|
|
99
110
|
/**
|
|
100
111
|
* Constructor of the mapper.
|
|
@@ -131,7 +142,7 @@ export function from(object) {
|
|
|
131
142
|
// 2. Process Remaining Properties (Direct Copy)
|
|
132
143
|
// Only if they are not part of a mapped source root
|
|
133
144
|
if (object) {
|
|
134
|
-
Object.keys(object).forEach(prop => {
|
|
145
|
+
Object.keys(object).forEach((prop) => {
|
|
135
146
|
if (!mappedSrcRoots.has(prop)) {
|
|
136
147
|
this[prop] = object[prop];
|
|
137
148
|
}
|
package/dist/test.js
CHANGED
|
@@ -17,11 +17,6 @@ import { ObjectField } from "./field-decorators/object.decorator";
|
|
|
17
17
|
console.log("\nMAPPER FACTORY - TEST");
|
|
18
18
|
console.log("\n");
|
|
19
19
|
let History = class History {
|
|
20
|
-
id;
|
|
21
|
-
name;
|
|
22
|
-
testControl;
|
|
23
|
-
daysActive;
|
|
24
|
-
testConcatenation;
|
|
25
20
|
};
|
|
26
21
|
__decorate([
|
|
27
22
|
MapField({
|
|
@@ -58,14 +53,6 @@ History = __decorate([
|
|
|
58
53
|
MapClass()
|
|
59
54
|
], History);
|
|
60
55
|
let User = class User {
|
|
61
|
-
id;
|
|
62
|
-
username;
|
|
63
|
-
name;
|
|
64
|
-
surname;
|
|
65
|
-
roles;
|
|
66
|
-
employees;
|
|
67
|
-
boss;
|
|
68
|
-
histories;
|
|
69
56
|
};
|
|
70
57
|
__decorate([
|
|
71
58
|
MapField({
|
|
@@ -112,6 +99,7 @@ User = __decorate([
|
|
|
112
99
|
const emp1 = new User().from({ firstName: "Summer", lastName: "Smith" });
|
|
113
100
|
const emp2 = new User().from({ firstName: "Morty", lastName: "Smith" });
|
|
114
101
|
const JSONObject = {
|
|
102
|
+
id: "0",
|
|
115
103
|
username: "god",
|
|
116
104
|
firstName: "Rick",
|
|
117
105
|
lastName: "Sanchez",
|
|
@@ -121,13 +109,19 @@ const JSONObject = {
|
|
|
121
109
|
};
|
|
122
110
|
//TEST constructor
|
|
123
111
|
const u = new User().from(JSONObject);
|
|
124
|
-
|
|
112
|
+
console.log("\n\n\n");
|
|
113
|
+
console.log(u);
|
|
114
|
+
console.log("\n\n\n");
|
|
115
|
+
console.log(JSONObject);
|
|
116
|
+
console.log("\n\n\n");
|
|
117
|
+
const constructorTest = !!(u.id == JSONObject.id &&
|
|
118
|
+
u.username == JSONObject.username &&
|
|
125
119
|
u.name == JSONObject.firstName &&
|
|
126
120
|
u.surname == JSONObject.lastName &&
|
|
127
121
|
u.employees?.map((emp) => emp.name == emp1.name) &&
|
|
128
122
|
u.roles?.map((role) => role == "CEO") &&
|
|
129
123
|
u.boss.name == "Nello" &&
|
|
130
|
-
u.boss.surname == "Stanco";
|
|
124
|
+
u.boss.surname == "Stanco");
|
|
131
125
|
console.log("TEST CONSTRUCTOR", constructorTest ? "✅" : "❌");
|
|
132
126
|
//TEST toModel method with JS Object
|
|
133
127
|
const u1 = new User().toModel(u);
|
|
@@ -168,7 +162,6 @@ const hTest2 = new History().from({
|
|
|
168
162
|
const toModelTest4 = hTest2.toMap().test.concatenation == "resolve ";
|
|
169
163
|
console.log("TEST CONCAT WITH POINT", toModelTest4 ? "✅" : "❌");
|
|
170
164
|
let Test = class Test {
|
|
171
|
-
a;
|
|
172
165
|
};
|
|
173
166
|
__decorate([
|
|
174
167
|
MapField({
|
|
@@ -191,10 +184,10 @@ console.log("TEST TO MODEL WITH INITIALIZE", model3.a == "test to model" ? "✅"
|
|
|
191
184
|
const model4 = model3.toMap();
|
|
192
185
|
console.log("TEST TO MAP WITH INITIALIZE", model4.b.a == "test reverser" ? "✅" : "❌");
|
|
193
186
|
const model5 = model3.copy();
|
|
194
|
-
console.log("TEST COPY WITH INITIALIZE", Object.keys(model5).every((k) => model5
|
|
187
|
+
console.log("TEST COPY WITH INITIALIZE", Object.keys(model5).every((k) => model5.get(k) == model3.get(k))
|
|
188
|
+
? "✅"
|
|
189
|
+
: "❌");
|
|
195
190
|
let TestFlag = class TestFlag {
|
|
196
|
-
flTest;
|
|
197
|
-
a;
|
|
198
191
|
};
|
|
199
192
|
__decorate([
|
|
200
193
|
MapField({
|
|
@@ -217,7 +210,9 @@ TestFlag = __decorate([
|
|
|
217
210
|
MapClass()
|
|
218
211
|
], TestFlag);
|
|
219
212
|
const testFlagInitialize = new TestFlag().from();
|
|
220
|
-
console.log("TEST INITIALIZE", testFlagInitialize && testFlagInitialize.a == "test transformer"
|
|
213
|
+
console.log("TEST INITIALIZE", testFlagInitialize && testFlagInitialize.a == "test transformer"
|
|
214
|
+
? "✅"
|
|
215
|
+
: "❌");
|
|
221
216
|
const testFlag0 = new TestFlag().from();
|
|
222
217
|
const testFlag0Map = testFlag0.toMap();
|
|
223
218
|
console.log("TEST FLAG0", testFlag0.flTest === false && testFlag0Map.flTest == "0" ? "✅" : "❌");
|
|
@@ -228,8 +223,6 @@ const testFlag2 = new TestFlag().from({ flTest: "0" });
|
|
|
228
223
|
const testFlag2Map = testFlag2.toMap();
|
|
229
224
|
console.log("TEST FLAG2", !testFlag2.flTest && testFlag2Map.flTest == "0" ? "✅" : "❌");
|
|
230
225
|
let TestWithoutMapField = class TestWithoutMapField {
|
|
231
|
-
id;
|
|
232
|
-
name;
|
|
233
226
|
};
|
|
234
227
|
TestWithoutMapField = __decorate([
|
|
235
228
|
MapClass()
|
|
@@ -241,8 +234,6 @@ const JSONObject2 = {
|
|
|
241
234
|
const testWOMF = new TestWithoutMapField().from(JSONObject2);
|
|
242
235
|
console.log("TEST WITHOUT MAP FIELD", testWOMF ? "✅" : "❌");
|
|
243
236
|
let ObjDecorator = class ObjDecorator {
|
|
244
|
-
id;
|
|
245
|
-
testObject;
|
|
246
237
|
};
|
|
247
238
|
__decorate([
|
|
248
239
|
ObjectField(ObjDecorator),
|
|
@@ -252,9 +243,6 @@ ObjDecorator = __decorate([
|
|
|
252
243
|
MapClass()
|
|
253
244
|
], ObjDecorator);
|
|
254
245
|
let TestDecorators = class TestDecorators {
|
|
255
|
-
date;
|
|
256
|
-
objList;
|
|
257
|
-
obj;
|
|
258
246
|
};
|
|
259
247
|
__decorate([
|
|
260
248
|
DateField({ src: "dateSrc" }),
|
|
@@ -280,7 +268,7 @@ const JSONTestDecorators = {
|
|
|
280
268
|
obj: { id: "5", testObject: { id: "6" } },
|
|
281
269
|
};
|
|
282
270
|
const testDecorators = new TestDecorators().from(JSONTestDecorators);
|
|
283
|
-
console.log("TEST WITH DECORATORS", testDecorators.date
|
|
271
|
+
console.log("TEST WITH DECORATORS", testDecorators.date?.toISOString() &&
|
|
284
272
|
testDecorators.objList?.length === 2 &&
|
|
285
273
|
testDecorators.obj instanceof ObjDecorator &&
|
|
286
274
|
testDecorators.objList[0] instanceof ObjDecorator &&
|
package/package.json
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mapper-factory",
|
|
3
|
-
"version": "4.0.
|
|
4
|
-
"description": "mapper for typescript object",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./dist/index.d.ts",
|
|
11
|
-
"import": "./dist/index.js"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"files": [
|
|
15
|
-
"/dist",
|
|
16
|
-
"/images"
|
|
17
|
-
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "npx tsc",
|
|
20
|
-
"dev": "npx tsc --watch",
|
|
21
|
-
"test": "npx tsx src/test.ts",
|
|
22
|
-
"patch": "npm version patch",
|
|
23
|
-
"minor": "npm version minor",
|
|
24
|
-
"major": "npm version major",
|
|
25
|
-
"deploy": "npm publish"
|
|
26
|
-
},
|
|
27
|
-
"repository": {
|
|
28
|
-
"type": "git",
|
|
29
|
-
"url": "git+https://github.com/lucaAngrisani/mapper-factory.git"
|
|
30
|
-
},
|
|
31
|
-
"keywords": [
|
|
32
|
-
"mapper-ts",
|
|
33
|
-
"mapper-factory",
|
|
34
|
-
"mapper",
|
|
35
|
-
"factory",
|
|
36
|
-
"mapper factory"
|
|
37
|
-
],
|
|
38
|
-
"author": "lucaAngrisani Angrigo",
|
|
39
|
-
"license": "ISC",
|
|
40
|
-
"bugs": {
|
|
41
|
-
"url": "https://github.com/lucaAngrisani/mapper-factory/issues"
|
|
42
|
-
},
|
|
43
|
-
"homepage": "https://github.com/lucaAngrisani/mapper-factory#readme",
|
|
44
|
-
"devDependencies": {
|
|
45
|
-
"typescript": "^5.7.3"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "mapper-factory",
|
|
3
|
+
"version": "4.0.2",
|
|
4
|
+
"description": "mapper for typescript object",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"/dist",
|
|
16
|
+
"/images"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "npx tsc",
|
|
20
|
+
"dev": "npx tsc --watch",
|
|
21
|
+
"test": "npx tsx src/test.ts",
|
|
22
|
+
"patch": "npm version patch",
|
|
23
|
+
"minor": "npm version minor",
|
|
24
|
+
"major": "npm version major",
|
|
25
|
+
"deploy": "npm publish"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/lucaAngrisani/mapper-factory.git"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"mapper-ts",
|
|
33
|
+
"mapper-factory",
|
|
34
|
+
"mapper",
|
|
35
|
+
"factory",
|
|
36
|
+
"mapper factory"
|
|
37
|
+
],
|
|
38
|
+
"author": "lucaAngrisani Angrigo",
|
|
39
|
+
"license": "ISC",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/lucaAngrisani/mapper-factory/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/lucaAngrisani/mapper-factory#readme",
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"typescript": "^5.7.3"
|
|
46
|
+
}
|
|
47
|
+
}
|