mapper-factory 4.0.1 → 4.1.0
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 +11 -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 | object) => 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,14 @@ const JSONObject = {
|
|
|
121
109
|
};
|
|
122
110
|
//TEST constructor
|
|
123
111
|
const u = new User().from(JSONObject);
|
|
124
|
-
const constructorTest = u.
|
|
112
|
+
const constructorTest = !!(u.id == JSONObject.id &&
|
|
113
|
+
u.username == JSONObject.username &&
|
|
125
114
|
u.name == JSONObject.firstName &&
|
|
126
115
|
u.surname == JSONObject.lastName &&
|
|
127
116
|
u.employees?.map((emp) => emp.name == emp1.name) &&
|
|
128
117
|
u.roles?.map((role) => role == "CEO") &&
|
|
129
118
|
u.boss.name == "Nello" &&
|
|
130
|
-
u.boss.surname == "Stanco";
|
|
119
|
+
u.boss.surname == "Stanco");
|
|
131
120
|
console.log("TEST CONSTRUCTOR", constructorTest ? "✅" : "❌");
|
|
132
121
|
//TEST toModel method with JS Object
|
|
133
122
|
const u1 = new User().toModel(u);
|
|
@@ -168,7 +157,6 @@ const hTest2 = new History().from({
|
|
|
168
157
|
const toModelTest4 = hTest2.toMap().test.concatenation == "resolve ";
|
|
169
158
|
console.log("TEST CONCAT WITH POINT", toModelTest4 ? "✅" : "❌");
|
|
170
159
|
let Test = class Test {
|
|
171
|
-
a;
|
|
172
160
|
};
|
|
173
161
|
__decorate([
|
|
174
162
|
MapField({
|
|
@@ -191,10 +179,10 @@ console.log("TEST TO MODEL WITH INITIALIZE", model3.a == "test to model" ? "✅"
|
|
|
191
179
|
const model4 = model3.toMap();
|
|
192
180
|
console.log("TEST TO MAP WITH INITIALIZE", model4.b.a == "test reverser" ? "✅" : "❌");
|
|
193
181
|
const model5 = model3.copy();
|
|
194
|
-
console.log("TEST COPY WITH INITIALIZE", Object.keys(model5).every((k) => model5
|
|
182
|
+
console.log("TEST COPY WITH INITIALIZE", Object.keys(model5).every((k) => model5.get(k) == model3.get(k))
|
|
183
|
+
? "✅"
|
|
184
|
+
: "❌");
|
|
195
185
|
let TestFlag = class TestFlag {
|
|
196
|
-
flTest;
|
|
197
|
-
a;
|
|
198
186
|
};
|
|
199
187
|
__decorate([
|
|
200
188
|
MapField({
|
|
@@ -217,7 +205,9 @@ TestFlag = __decorate([
|
|
|
217
205
|
MapClass()
|
|
218
206
|
], TestFlag);
|
|
219
207
|
const testFlagInitialize = new TestFlag().from();
|
|
220
|
-
console.log("TEST INITIALIZE", testFlagInitialize && testFlagInitialize.a == "test transformer"
|
|
208
|
+
console.log("TEST INITIALIZE", testFlagInitialize && testFlagInitialize.a == "test transformer"
|
|
209
|
+
? "✅"
|
|
210
|
+
: "❌");
|
|
221
211
|
const testFlag0 = new TestFlag().from();
|
|
222
212
|
const testFlag0Map = testFlag0.toMap();
|
|
223
213
|
console.log("TEST FLAG0", testFlag0.flTest === false && testFlag0Map.flTest == "0" ? "✅" : "❌");
|
|
@@ -228,8 +218,6 @@ const testFlag2 = new TestFlag().from({ flTest: "0" });
|
|
|
228
218
|
const testFlag2Map = testFlag2.toMap();
|
|
229
219
|
console.log("TEST FLAG2", !testFlag2.flTest && testFlag2Map.flTest == "0" ? "✅" : "❌");
|
|
230
220
|
let TestWithoutMapField = class TestWithoutMapField {
|
|
231
|
-
id;
|
|
232
|
-
name;
|
|
233
221
|
};
|
|
234
222
|
TestWithoutMapField = __decorate([
|
|
235
223
|
MapClass()
|
|
@@ -241,8 +229,6 @@ const JSONObject2 = {
|
|
|
241
229
|
const testWOMF = new TestWithoutMapField().from(JSONObject2);
|
|
242
230
|
console.log("TEST WITHOUT MAP FIELD", testWOMF ? "✅" : "❌");
|
|
243
231
|
let ObjDecorator = class ObjDecorator {
|
|
244
|
-
id;
|
|
245
|
-
testObject;
|
|
246
232
|
};
|
|
247
233
|
__decorate([
|
|
248
234
|
ObjectField(ObjDecorator),
|
|
@@ -252,9 +238,6 @@ ObjDecorator = __decorate([
|
|
|
252
238
|
MapClass()
|
|
253
239
|
], ObjDecorator);
|
|
254
240
|
let TestDecorators = class TestDecorators {
|
|
255
|
-
date;
|
|
256
|
-
objList;
|
|
257
|
-
obj;
|
|
258
241
|
};
|
|
259
242
|
__decorate([
|
|
260
243
|
DateField({ src: "dateSrc" }),
|
|
@@ -280,7 +263,7 @@ const JSONTestDecorators = {
|
|
|
280
263
|
obj: { id: "5", testObject: { id: "6" } },
|
|
281
264
|
};
|
|
282
265
|
const testDecorators = new TestDecorators().from(JSONTestDecorators);
|
|
283
|
-
console.log("TEST WITH DECORATORS", testDecorators.date
|
|
266
|
+
console.log("TEST WITH DECORATORS", testDecorators.date?.toISOString() &&
|
|
284
267
|
testDecorators.objList?.length === 2 &&
|
|
285
268
|
testDecorators.obj instanceof ObjDecorator &&
|
|
286
269
|
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.1.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
|
+
}
|