mapper-factory 3.2.0 → 4.0.1
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/dist/class.decorator.js +10 -13
- package/dist/field-decorators/array.decorator.js +3 -6
- package/dist/field-decorators/date.decorator.js +3 -6
- package/dist/field-decorators/field.decorator.d.ts +0 -1
- package/dist/field-decorators/field.decorator.js +14 -25
- package/dist/field-decorators/object.decorator.js +3 -6
- package/dist/functions.js +67 -144
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -14
- package/dist/test.js +30 -31
- package/dist/types.js +1 -2
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +43 -0
- package/package.json +9 -5
package/dist/class.decorator.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.MapClass = MapClass;
|
|
4
|
-
const functions_1 = require("./functions");
|
|
5
|
-
function MapClass() {
|
|
1
|
+
import { copy, empty, filled, from, get, objToModel, set, toMap } from "./functions";
|
|
2
|
+
export function MapClass() {
|
|
6
3
|
return function (constructor) {
|
|
7
|
-
constructor.prototype.from =
|
|
8
|
-
constructor.prototype.toMap =
|
|
9
|
-
constructor.prototype.toModel =
|
|
10
|
-
constructor.prototype.empty =
|
|
11
|
-
constructor.prototype.filled =
|
|
12
|
-
constructor.prototype.get =
|
|
13
|
-
constructor.prototype.set =
|
|
14
|
-
constructor.prototype.copy =
|
|
4
|
+
constructor.prototype.from = from;
|
|
5
|
+
constructor.prototype.toMap = toMap;
|
|
6
|
+
constructor.prototype.toModel = objToModel;
|
|
7
|
+
constructor.prototype.empty = empty;
|
|
8
|
+
constructor.prototype.filled = filled;
|
|
9
|
+
constructor.prototype.get = get;
|
|
10
|
+
constructor.prototype.set = set;
|
|
11
|
+
constructor.prototype.copy = copy;
|
|
15
12
|
};
|
|
16
13
|
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.ArrayField = ArrayField;
|
|
4
|
-
const field_decorator_1 = require("./field.decorator");
|
|
5
|
-
function ArrayField(clsFactory, opt) {
|
|
1
|
+
import { MapField } from "./field.decorator";
|
|
2
|
+
export function ArrayField(clsFactory, opt) {
|
|
6
3
|
const Ctor = clsFactory;
|
|
7
|
-
return
|
|
4
|
+
return MapField({
|
|
8
5
|
src: opt?.src,
|
|
9
6
|
transformer: (arr) => Array.isArray(arr)
|
|
10
7
|
? arr.map((item) => new Ctor().from(item))
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const field_decorator_1 = require("./field.decorator");
|
|
5
|
-
function DateField(opt) {
|
|
6
|
-
return (0, field_decorator_1.MapField)({
|
|
1
|
+
import { MapField } from "./field.decorator";
|
|
2
|
+
export function DateField(opt) {
|
|
3
|
+
return MapField({
|
|
7
4
|
src: opt?.src,
|
|
8
5
|
transformer: (dateISO) => dateISO ? new Date(dateISO) : null,
|
|
9
6
|
reverser: (date) => date?.toISOString() ?? null,
|
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.hasMapFieldMetadata = exports.getMapFieldMetadata = exports.hasMapFieldMetadataList = exports.getMapFieldMetadataList = exports.MapField = exports.MAP_FIELD = void 0;
|
|
4
|
-
exports.isClass = isClass;
|
|
5
|
-
exports.getPrototype = getPrototype;
|
|
6
|
-
require("reflect-metadata");
|
|
7
|
-
exports.MAP_FIELD = Symbol('MAP_FIELD');
|
|
8
|
-
function isClass(func) {
|
|
1
|
+
export const MAP_FIELD = Symbol('MAP_FIELD');
|
|
2
|
+
export function isClass(func) {
|
|
9
3
|
return (typeof func === 'function' &&
|
|
10
4
|
/^class\s/.test(Function.prototype.toString.call(func)));
|
|
11
5
|
}
|
|
12
|
-
function getPrototype(target) {
|
|
6
|
+
export function getPrototype(target) {
|
|
13
7
|
return isClass(target) || !target?.prototype ? !target?.constructor ? target : target?.constructor : target?.prototype;
|
|
14
8
|
}
|
|
15
|
-
const MapField = ({ transformer, reverser, src, initialize = false, } = {}) => {
|
|
9
|
+
export const MapField = ({ transformer, reverser, src, initialize = false, } = {}) => {
|
|
16
10
|
return (target, property) => {
|
|
17
11
|
const classConstructor = target.constructor;
|
|
18
12
|
const propertyName = property.toString();
|
|
19
|
-
const metadata =
|
|
13
|
+
const metadata = classConstructor[MAP_FIELD] || {};
|
|
20
14
|
// create new object reference to avoid this issue: https://github.com/rbuckton/reflect-metadata/issues/62
|
|
21
15
|
const newMetadata = { ...metadata };
|
|
22
16
|
const previousValues = metadata[propertyName];
|
|
@@ -27,28 +21,23 @@ const MapField = ({ transformer, reverser, src, initialize = false, } = {}) => {
|
|
|
27
21
|
transformer,
|
|
28
22
|
reverser,
|
|
29
23
|
};
|
|
30
|
-
|
|
24
|
+
classConstructor[MAP_FIELD] = newMetadata;
|
|
31
25
|
};
|
|
32
26
|
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return Reflect.getMetadata(exports.MAP_FIELD, getPrototype(target));
|
|
27
|
+
export const getMapFieldMetadataList = (target) => {
|
|
28
|
+
return getPrototype(target)[MAP_FIELD];
|
|
36
29
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return Reflect.hasMetadata(exports.MAP_FIELD, getPrototype(target));
|
|
30
|
+
export const hasMapFieldMetadataList = (target) => {
|
|
31
|
+
return !!getPrototype(target)[MAP_FIELD];
|
|
40
32
|
};
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
const metadata = (0, exports.getMapFieldMetadataList)(target);
|
|
33
|
+
export const getMapFieldMetadata = (target, propertyName) => {
|
|
34
|
+
const metadata = getMapFieldMetadataList(target);
|
|
44
35
|
const name = propertyName.toString();
|
|
45
36
|
if (!metadata || !metadata[name])
|
|
46
37
|
return undefined;
|
|
47
38
|
return metadata[name];
|
|
48
39
|
};
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
const metadata = Reflect.getMetadata(exports.MAP_FIELD, getPrototype(target));
|
|
40
|
+
export const hasMapFieldMetadata = (target, propertyName) => {
|
|
41
|
+
const metadata = getPrototype(target)[MAP_FIELD];
|
|
52
42
|
return metadata && !!metadata[propertyName];
|
|
53
43
|
};
|
|
54
|
-
exports.hasMapFieldMetadata = hasMapFieldMetadata;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.ObjectField = ObjectField;
|
|
4
|
-
const field_decorator_1 = require("./field.decorator");
|
|
5
|
-
function ObjectField(clsFactory, opt) {
|
|
1
|
+
import { MapField } from "./field.decorator";
|
|
2
|
+
export function ObjectField(clsFactory, opt) {
|
|
6
3
|
const Ctor = clsFactory;
|
|
7
|
-
return
|
|
4
|
+
return MapField({
|
|
8
5
|
src: opt?.src,
|
|
9
6
|
transformer: (obj) => (obj ? new Ctor().from(obj) : null),
|
|
10
7
|
reverser: (obj) => obj?.toMap?.() ?? null,
|
package/dist/functions.js
CHANGED
|
@@ -1,83 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.toMap = toMap;
|
|
4
|
-
exports.objToModel = objToModel;
|
|
5
|
-
exports.empty = empty;
|
|
6
|
-
exports.filled = filled;
|
|
7
|
-
exports.get = get;
|
|
8
|
-
exports.set = set;
|
|
9
|
-
exports.copy = copy;
|
|
10
|
-
exports.from = from;
|
|
11
|
-
const field_decorator_1 = require("./field-decorators/field.decorator");
|
|
1
|
+
import { getMapFieldMetadataList } from "./field-decorators/field.decorator";
|
|
2
|
+
import { getValueByPath, setValueByPath } from "./utils";
|
|
12
3
|
/**
|
|
13
4
|
* Convert the instance of this class to JSON Object.
|
|
14
5
|
*
|
|
15
6
|
* @returns JSON object mapped considering metadata "src" and "reverser"
|
|
16
7
|
*/
|
|
17
|
-
function toMap() {
|
|
18
|
-
const metadataList =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
let lastIndex;
|
|
22
|
-
for (let i = 0; i < propsStereoid.length; i++) {
|
|
23
|
-
const prop = propsStereoid[i];
|
|
24
|
-
if (prop.isArray) {
|
|
25
|
-
let arrIndex = prop.arrIndex
|
|
26
|
-
.split(/\[(\w+)\]/g)
|
|
27
|
-
.filter((index) => index !== "");
|
|
28
|
-
objCopy[prop.prop] = objCopy[prop.prop] || [];
|
|
29
|
-
objCopy = objCopy[prop.prop];
|
|
30
|
-
arrIndex.forEach((index, i) => {
|
|
31
|
-
objCopy[index] =
|
|
32
|
-
objCopy[index] || (i == arrIndex.length - 1 ? {} : []);
|
|
33
|
-
if (i != arrIndex.length - 1)
|
|
34
|
-
objCopy = objCopy[index];
|
|
35
|
-
else
|
|
36
|
-
lastIndex = index;
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
objCopy[prop.prop] = objCopy[prop.prop] || {};
|
|
41
|
-
if (i != propsStereoid.length - 1)
|
|
42
|
-
objCopy = objCopy[prop.prop];
|
|
43
|
-
else
|
|
44
|
-
lastIndex = prop.prop;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
objCopy[lastIndex] = reverser ? reverser(value, this) : value;
|
|
48
|
-
};
|
|
49
|
-
this &&
|
|
8
|
+
export function toMap() {
|
|
9
|
+
const metadataList = getMapFieldMetadataList(this);
|
|
10
|
+
const obj = {};
|
|
11
|
+
if (this) {
|
|
50
12
|
Object.keys(this).forEach((propertyName) => {
|
|
51
13
|
const metadata = metadataList && metadataList[propertyName];
|
|
52
14
|
const src = metadata?.src || propertyName;
|
|
15
|
+
const value = this[propertyName];
|
|
16
|
+
let finalValue;
|
|
53
17
|
if (metadata) {
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}));
|
|
63
|
-
processProperty(obj, propsStereoid, this[propertyName], metadata.reverser);
|
|
18
|
+
if (Array.isArray(value) && !metadata.reverser) {
|
|
19
|
+
finalValue = value.map((item) => item?.toMap ? item.toMap() : item);
|
|
20
|
+
}
|
|
21
|
+
else if (metadata.reverser) {
|
|
22
|
+
finalValue = metadata.reverser(value, this);
|
|
23
|
+
}
|
|
24
|
+
else if (value?.toMap) {
|
|
25
|
+
finalValue = value.toMap();
|
|
64
26
|
}
|
|
65
27
|
else {
|
|
66
|
-
|
|
67
|
-
Array.isArray(this[propertyName]) && !metadata.reverser
|
|
68
|
-
? this[propertyName].map((item) => item?.toMap ? item.toMap() : item)
|
|
69
|
-
: metadata.reverser
|
|
70
|
-
? metadata.reverser(this[propertyName], this)
|
|
71
|
-
: this[propertyName]?.toMap
|
|
72
|
-
? this[propertyName].toMap()
|
|
73
|
-
: this[propertyName];
|
|
28
|
+
finalValue = value;
|
|
74
29
|
}
|
|
75
30
|
}
|
|
76
31
|
else {
|
|
77
|
-
|
|
78
|
-
|
|
32
|
+
finalValue = value;
|
|
33
|
+
}
|
|
34
|
+
if (finalValue !== undefined) {
|
|
35
|
+
setValueByPath(obj, src, finalValue);
|
|
79
36
|
}
|
|
80
37
|
});
|
|
38
|
+
}
|
|
81
39
|
return obj;
|
|
82
40
|
}
|
|
83
41
|
/**
|
|
@@ -86,7 +44,7 @@ function toMap() {
|
|
|
86
44
|
* @param obj JSON Object
|
|
87
45
|
* @returns Instance of this class
|
|
88
46
|
*/
|
|
89
|
-
function objToModel(obj) {
|
|
47
|
+
export function objToModel(obj) {
|
|
90
48
|
if (!obj)
|
|
91
49
|
return this;
|
|
92
50
|
Object.keys(obj).forEach((propertyName) => {
|
|
@@ -102,7 +60,7 @@ function objToModel(obj) {
|
|
|
102
60
|
*
|
|
103
61
|
* @returns true or false
|
|
104
62
|
*/
|
|
105
|
-
function empty() {
|
|
63
|
+
export function empty() {
|
|
106
64
|
return !Object.keys(this).some((propertyName) => this[propertyName] !== undefined && this[propertyName] !== null);
|
|
107
65
|
}
|
|
108
66
|
/**
|
|
@@ -110,7 +68,7 @@ function empty() {
|
|
|
110
68
|
*
|
|
111
69
|
* @returns true or false
|
|
112
70
|
*/
|
|
113
|
-
function filled() {
|
|
71
|
+
export function filled() {
|
|
114
72
|
return (Object.keys(this).length > 0 &&
|
|
115
73
|
Object.keys(this).every((propertyName) => this[propertyName] !== undefined && this[propertyName] !== null));
|
|
116
74
|
}
|
|
@@ -120,9 +78,8 @@ function filled() {
|
|
|
120
78
|
* @param path String path
|
|
121
79
|
* @returns Value of the property
|
|
122
80
|
*/
|
|
123
|
-
function get(path) {
|
|
124
|
-
|
|
125
|
-
return props.reduce((acc, prop) => acc && acc[prop], this);
|
|
81
|
+
export function get(path) {
|
|
82
|
+
return getValueByPath(this, path);
|
|
126
83
|
}
|
|
127
84
|
/**
|
|
128
85
|
* SET property value from a string path.
|
|
@@ -130,20 +87,13 @@ function get(path) {
|
|
|
130
87
|
* @param path String path
|
|
131
88
|
* @param value Value of the property
|
|
132
89
|
*/
|
|
133
|
-
function set(path, value) {
|
|
134
|
-
|
|
135
|
-
let obj = this;
|
|
136
|
-
props.slice(0, -1).forEach((prop) => {
|
|
137
|
-
if (!obj[prop])
|
|
138
|
-
obj[prop] = {};
|
|
139
|
-
obj = obj[prop];
|
|
140
|
-
});
|
|
141
|
-
obj[props[props.length - 1]] = value;
|
|
90
|
+
export function set(path, value) {
|
|
91
|
+
setValueByPath(this, path, value);
|
|
142
92
|
}
|
|
143
93
|
/**
|
|
144
94
|
* Deep copy of the object caller
|
|
145
95
|
*/
|
|
146
|
-
function copy() {
|
|
96
|
+
export function copy() {
|
|
147
97
|
return this.from(this.toMap());
|
|
148
98
|
}
|
|
149
99
|
/**
|
|
@@ -151,79 +101,52 @@ function copy() {
|
|
|
151
101
|
*
|
|
152
102
|
* @param object object to be mapped considering metadata "src", "transformer" and "reverser"
|
|
153
103
|
*/
|
|
154
|
-
function from(object) {
|
|
155
|
-
const metadataList =
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
};
|
|
174
|
-
const setProperty = (metaKey, value, object) => {
|
|
175
|
-
const metaProp = metadataList?.[metaKey];
|
|
176
|
-
if (metaProp?.transformer) {
|
|
177
|
-
const valueTransformed = metaProp.transformer(value, object);
|
|
178
|
-
if (valueTransformed != undefined)
|
|
179
|
-
this[metaKey] = valueTransformed;
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
if (value != undefined)
|
|
183
|
-
this[metaKey] = value;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
object &&
|
|
187
|
-
Object.keys(object).forEach((propertyName) => {
|
|
188
|
-
let metaKeys = metadataList &&
|
|
189
|
-
Object.keys(metadataList).filter((metadata) => metadataList[metadata]?.src?.split(".")?.includes(propertyName));
|
|
190
|
-
if (metaKeys?.length) {
|
|
191
|
-
metaKeys.forEach((metaKey) => {
|
|
192
|
-
const metaProp = metadataList?.[metaKey];
|
|
193
|
-
if (metaProp) {
|
|
194
|
-
const props = metaProp.src.split(".");
|
|
195
|
-
const propsStereoid = props.map((prop) => ({
|
|
196
|
-
prop: prop.includes("[")
|
|
197
|
-
? prop.substring(0, prop.indexOf("["))
|
|
198
|
-
: prop,
|
|
199
|
-
isArray: prop.includes("[") && prop.includes("]"),
|
|
200
|
-
arrIndex: prop.substring(prop.indexOf("[")),
|
|
201
|
-
}));
|
|
202
|
-
const value = processProperty({ ...object }, propsStereoid);
|
|
203
|
-
setProperty(metaKey, value, object);
|
|
104
|
+
export function from(object) {
|
|
105
|
+
const metadataList = getMapFieldMetadataList(this);
|
|
106
|
+
const mappedSrcRoots = new Set();
|
|
107
|
+
// 1. Process Metadata
|
|
108
|
+
if (metadataList && object) {
|
|
109
|
+
Object.keys(metadataList).forEach((key) => {
|
|
110
|
+
const meta = metadataList[key];
|
|
111
|
+
const src = meta.src || key;
|
|
112
|
+
// Identify root property for this mapping to exclude it from direct copy later
|
|
113
|
+
const normalizedPath = src.replace(/\[(\w+)\]/g, ".$1");
|
|
114
|
+
const root = normalizedPath.split(".")[0];
|
|
115
|
+
mappedSrcRoots.add(root);
|
|
116
|
+
const value = getValueByPath(object, src);
|
|
117
|
+
// Only process if value exists in source (matches old behavior and avoids infinite recursion on undefined)
|
|
118
|
+
if (value !== undefined) {
|
|
119
|
+
if (meta.transformer) {
|
|
120
|
+
const transformed = meta.transformer(value, object);
|
|
121
|
+
if (transformed !== undefined) {
|
|
122
|
+
this[key] = transformed;
|
|
204
123
|
}
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
let metaKey = metadataList &&
|
|
209
|
-
Object.keys(metadataList).find((metadata) => metadataList[metadata]?.src == propertyName);
|
|
210
|
-
if (metaKey) {
|
|
211
|
-
const src = metadataList?.[metaKey].src || propertyName;
|
|
212
|
-
setProperty(metaKey, object[src], object);
|
|
213
124
|
}
|
|
214
125
|
else {
|
|
215
|
-
|
|
126
|
+
this[key] = value;
|
|
216
127
|
}
|
|
217
128
|
}
|
|
218
129
|
});
|
|
219
|
-
|
|
220
|
-
|
|
130
|
+
}
|
|
131
|
+
// 2. Process Remaining Properties (Direct Copy)
|
|
132
|
+
// Only if they are not part of a mapped source root
|
|
133
|
+
if (object) {
|
|
134
|
+
Object.keys(object).forEach(prop => {
|
|
135
|
+
if (!mappedSrcRoots.has(prop)) {
|
|
136
|
+
this[prop] = object[prop];
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// 3. Initialize properties with "initialize" metadata
|
|
141
|
+
if (metadataList) {
|
|
221
142
|
Object.keys(metadataList).forEach((metaName) => {
|
|
222
|
-
|
|
223
|
-
|
|
143
|
+
const meta = metadataList[metaName];
|
|
144
|
+
if (meta?.initialize &&
|
|
145
|
+
meta?.transformer &&
|
|
224
146
|
this[metaName] === undefined) {
|
|
225
|
-
this[metaName] =
|
|
147
|
+
this[metaName] = meta.transformer(null, object);
|
|
226
148
|
}
|
|
227
149
|
});
|
|
150
|
+
}
|
|
228
151
|
return this;
|
|
229
152
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { ClassType } from "./types";
|
|
|
7
7
|
export { ClassType, MapInterface, MapClass, MapField, DateField, ArrayField, ObjectField, };
|
|
8
8
|
/**
|
|
9
9
|
* npx tsc
|
|
10
|
-
* npx
|
|
10
|
+
* npx tsx src/test.ts
|
|
11
11
|
* npm version ( patch | minor | major )
|
|
12
12
|
* npm publish
|
|
13
13
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Object.defineProperty(exports, "MapField", { enumerable: true, get: function () { return field_decorator_1.MapField; } });
|
|
8
|
-
const array_decorator_1 = require("./field-decorators/array.decorator");
|
|
9
|
-
Object.defineProperty(exports, "ArrayField", { enumerable: true, get: function () { return array_decorator_1.ArrayField; } });
|
|
10
|
-
const date_decorator_1 = require("./field-decorators/date.decorator");
|
|
11
|
-
Object.defineProperty(exports, "DateField", { enumerable: true, get: function () { return date_decorator_1.DateField; } });
|
|
12
|
-
const object_decorator_1 = require("./field-decorators/object.decorator");
|
|
13
|
-
Object.defineProperty(exports, "ObjectField", { enumerable: true, get: function () { return object_decorator_1.ObjectField; } });
|
|
1
|
+
import { MapClass } from "./class.decorator";
|
|
2
|
+
import { MapField } from "./field-decorators/field.decorator";
|
|
3
|
+
import { ArrayField } from "./field-decorators/array.decorator";
|
|
4
|
+
import { DateField } from "./field-decorators/date.decorator";
|
|
5
|
+
import { ObjectField } from "./field-decorators/object.decorator";
|
|
6
|
+
export { MapClass, MapField, DateField, ArrayField, ObjectField, };
|
|
14
7
|
/**
|
|
15
8
|
* npx tsc
|
|
16
|
-
* npx
|
|
9
|
+
* npx tsx src/test.ts
|
|
17
10
|
* npm version ( patch | minor | major )
|
|
18
11
|
* npm publish
|
|
19
12
|
*/
|
package/dist/test.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
2
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
3
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -8,12 +7,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
//// import "reflect-metadata";
|
|
11
|
+
import { MapClass } from "./class.decorator";
|
|
12
|
+
import { ArrayField } from "./field-decorators/array.decorator";
|
|
13
|
+
import { DateField } from "./field-decorators/date.decorator";
|
|
14
|
+
import { MapField } from "./field-decorators/field.decorator";
|
|
15
|
+
import { ObjectField } from "./field-decorators/object.decorator";
|
|
17
16
|
//MAPPER FACTORY - TEST
|
|
18
17
|
console.log("\nMAPPER FACTORY - TEST");
|
|
19
18
|
console.log("\n");
|
|
@@ -25,20 +24,20 @@ let History = class History {
|
|
|
25
24
|
testConcatenation;
|
|
26
25
|
};
|
|
27
26
|
__decorate([
|
|
28
|
-
|
|
27
|
+
MapField({
|
|
29
28
|
transformer: (arr) => " TEST TRASFORMER",
|
|
30
29
|
reverser: (arr) => " TEST REVERSER",
|
|
31
30
|
}),
|
|
32
31
|
__metadata("design:type", String)
|
|
33
32
|
], History.prototype, "name", void 0);
|
|
34
33
|
__decorate([
|
|
35
|
-
|
|
34
|
+
MapField({
|
|
36
35
|
src: "control",
|
|
37
36
|
}),
|
|
38
37
|
__metadata("design:type", String)
|
|
39
38
|
], History.prototype, "testControl", void 0);
|
|
40
39
|
__decorate([
|
|
41
|
-
|
|
40
|
+
MapField({
|
|
42
41
|
initialize: true,
|
|
43
42
|
transformer: (arr, obj) => {
|
|
44
43
|
return [obj.monday, obj.tuesday];
|
|
@@ -50,13 +49,13 @@ __decorate([
|
|
|
50
49
|
__metadata("design:type", Array)
|
|
51
50
|
], History.prototype, "daysActive", void 0);
|
|
52
51
|
__decorate([
|
|
53
|
-
|
|
52
|
+
MapField({
|
|
54
53
|
src: "test.concatenation",
|
|
55
54
|
}),
|
|
56
55
|
__metadata("design:type", String)
|
|
57
56
|
], History.prototype, "testConcatenation", void 0);
|
|
58
57
|
History = __decorate([
|
|
59
|
-
|
|
58
|
+
MapClass()
|
|
60
59
|
], History);
|
|
61
60
|
let User = class User {
|
|
62
61
|
id;
|
|
@@ -69,19 +68,19 @@ let User = class User {
|
|
|
69
68
|
histories;
|
|
70
69
|
};
|
|
71
70
|
__decorate([
|
|
72
|
-
|
|
71
|
+
MapField({
|
|
73
72
|
src: "firstName",
|
|
74
73
|
}),
|
|
75
74
|
__metadata("design:type", String)
|
|
76
75
|
], User.prototype, "name", void 0);
|
|
77
76
|
__decorate([
|
|
78
|
-
|
|
77
|
+
MapField({
|
|
79
78
|
src: "lastName",
|
|
80
79
|
}),
|
|
81
80
|
__metadata("design:type", String)
|
|
82
81
|
], User.prototype, "surname", void 0);
|
|
83
82
|
__decorate([
|
|
84
|
-
|
|
83
|
+
MapField({
|
|
85
84
|
src: "rolesToMap",
|
|
86
85
|
transformer: (arr) => arr?.map((role) => role + " TEST TRASFORMER"),
|
|
87
86
|
reverser: (arr) => arr?.map((role) => role.replace(" TEST TRASFORMER", "")),
|
|
@@ -89,26 +88,26 @@ __decorate([
|
|
|
89
88
|
__metadata("design:type", Array)
|
|
90
89
|
], User.prototype, "roles", void 0);
|
|
91
90
|
__decorate([
|
|
92
|
-
|
|
91
|
+
MapField({
|
|
93
92
|
transformer: (arr) => arr?.map((user) => new User().from(user)),
|
|
94
93
|
}),
|
|
95
94
|
__metadata("design:type", Array)
|
|
96
95
|
], User.prototype, "employees", void 0);
|
|
97
96
|
__decorate([
|
|
98
|
-
|
|
97
|
+
MapField({
|
|
99
98
|
transformer: (user) => new User().from(user),
|
|
100
99
|
}),
|
|
101
100
|
__metadata("design:type", User)
|
|
102
101
|
], User.prototype, "boss", void 0);
|
|
103
102
|
__decorate([
|
|
104
|
-
|
|
103
|
+
MapField({
|
|
105
104
|
transformer: (histories) => histories?.map((hst) => new History().from(hst)),
|
|
106
105
|
reverser: (histories) => histories?.map((hst) => hst.toMap()),
|
|
107
106
|
}),
|
|
108
107
|
__metadata("design:type", Array)
|
|
109
108
|
], User.prototype, "histories", void 0);
|
|
110
109
|
User = __decorate([
|
|
111
|
-
|
|
110
|
+
MapClass()
|
|
112
111
|
], User);
|
|
113
112
|
const emp1 = new User().from({ firstName: "Summer", lastName: "Smith" });
|
|
114
113
|
const emp2 = new User().from({ firstName: "Morty", lastName: "Smith" });
|
|
@@ -172,7 +171,7 @@ let Test = class Test {
|
|
|
172
171
|
a;
|
|
173
172
|
};
|
|
174
173
|
__decorate([
|
|
175
|
-
|
|
174
|
+
MapField({
|
|
176
175
|
src: "b",
|
|
177
176
|
transformer: (value) => "test transformer",
|
|
178
177
|
reverser: (value) => ({ a: "test reverser" }),
|
|
@@ -180,7 +179,7 @@ __decorate([
|
|
|
180
179
|
__metadata("design:type", String)
|
|
181
180
|
], Test.prototype, "a", void 0);
|
|
182
181
|
Test = __decorate([
|
|
183
|
-
|
|
182
|
+
MapClass()
|
|
184
183
|
], Test);
|
|
185
184
|
const testEmpty = new Test().from();
|
|
186
185
|
const testFilled = new Test().from({ b: "filled" });
|
|
@@ -198,7 +197,7 @@ let TestFlag = class TestFlag {
|
|
|
198
197
|
a;
|
|
199
198
|
};
|
|
200
199
|
__decorate([
|
|
201
|
-
|
|
200
|
+
MapField({
|
|
202
201
|
transformer: (num) => num == "1",
|
|
203
202
|
reverser: (bool) => (bool ? "1" : "0"),
|
|
204
203
|
initialize: true,
|
|
@@ -206,7 +205,7 @@ __decorate([
|
|
|
206
205
|
__metadata("design:type", Boolean)
|
|
207
206
|
], TestFlag.prototype, "flTest", void 0);
|
|
208
207
|
__decorate([
|
|
209
|
-
|
|
208
|
+
MapField({
|
|
210
209
|
src: "b",
|
|
211
210
|
transformer: (value) => "test transformer",
|
|
212
211
|
reverser: (value) => ({ a: "test reverser" }),
|
|
@@ -215,7 +214,7 @@ __decorate([
|
|
|
215
214
|
__metadata("design:type", String)
|
|
216
215
|
], TestFlag.prototype, "a", void 0);
|
|
217
216
|
TestFlag = __decorate([
|
|
218
|
-
|
|
217
|
+
MapClass()
|
|
219
218
|
], TestFlag);
|
|
220
219
|
const testFlagInitialize = new TestFlag().from();
|
|
221
220
|
console.log("TEST INITIALIZE", testFlagInitialize && testFlagInitialize.a == "test transformer" ? "✅" : "❌");
|
|
@@ -233,7 +232,7 @@ let TestWithoutMapField = class TestWithoutMapField {
|
|
|
233
232
|
name;
|
|
234
233
|
};
|
|
235
234
|
TestWithoutMapField = __decorate([
|
|
236
|
-
|
|
235
|
+
MapClass()
|
|
237
236
|
], TestWithoutMapField);
|
|
238
237
|
const JSONObject2 = {
|
|
239
238
|
id: "1",
|
|
@@ -246,11 +245,11 @@ let ObjDecorator = class ObjDecorator {
|
|
|
246
245
|
testObject;
|
|
247
246
|
};
|
|
248
247
|
__decorate([
|
|
249
|
-
|
|
248
|
+
ObjectField(ObjDecorator),
|
|
250
249
|
__metadata("design:type", ObjDecorator)
|
|
251
250
|
], ObjDecorator.prototype, "testObject", void 0);
|
|
252
251
|
ObjDecorator = __decorate([
|
|
253
|
-
|
|
252
|
+
MapClass()
|
|
254
253
|
], ObjDecorator);
|
|
255
254
|
let TestDecorators = class TestDecorators {
|
|
256
255
|
date;
|
|
@@ -258,19 +257,19 @@ let TestDecorators = class TestDecorators {
|
|
|
258
257
|
obj;
|
|
259
258
|
};
|
|
260
259
|
__decorate([
|
|
261
|
-
|
|
260
|
+
DateField({ src: "dateSrc" }),
|
|
262
261
|
__metadata("design:type", Date)
|
|
263
262
|
], TestDecorators.prototype, "date", void 0);
|
|
264
263
|
__decorate([
|
|
265
|
-
|
|
264
|
+
ArrayField(ObjDecorator),
|
|
266
265
|
__metadata("design:type", Array)
|
|
267
266
|
], TestDecorators.prototype, "objList", void 0);
|
|
268
267
|
__decorate([
|
|
269
|
-
|
|
268
|
+
ObjectField(ObjDecorator),
|
|
270
269
|
__metadata("design:type", ObjDecorator)
|
|
271
270
|
], TestDecorators.prototype, "obj", void 0);
|
|
272
271
|
TestDecorators = __decorate([
|
|
273
|
-
|
|
272
|
+
MapClass()
|
|
274
273
|
], TestDecorators);
|
|
275
274
|
const JSONTestDecorators = {
|
|
276
275
|
dateSrc: "2023-10-01T00:00:00Z",
|
package/dist/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieve a value from an object using a string path (dot notation).
|
|
3
|
+
* Supports array indexing e.g. "users[0].name" or "users.0.name".
|
|
4
|
+
*/
|
|
5
|
+
export declare function getValueByPath(obj: any, path: string): any;
|
|
6
|
+
/**
|
|
7
|
+
* Set a value on an object using a string path (dot notation).
|
|
8
|
+
* Creates nested objects/arrays if they don't exist.
|
|
9
|
+
*/
|
|
10
|
+
export declare function setValueByPath(obj: any, path: string, value: any): void;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieve a value from an object using a string path (dot notation).
|
|
3
|
+
* Supports array indexing e.g. "users[0].name" or "users.0.name".
|
|
4
|
+
*/
|
|
5
|
+
export function getValueByPath(obj, path) {
|
|
6
|
+
if (obj == null || !path)
|
|
7
|
+
return undefined;
|
|
8
|
+
// Normalize path: "a[0].b" -> "a.0.b"
|
|
9
|
+
const normalizedPath = path.replace(/\[(\w+)\]/g, ".$1");
|
|
10
|
+
const parts = normalizedPath.split(".");
|
|
11
|
+
let current = obj;
|
|
12
|
+
for (const part of parts) {
|
|
13
|
+
if (current == null)
|
|
14
|
+
return undefined;
|
|
15
|
+
current = current[part];
|
|
16
|
+
}
|
|
17
|
+
return current;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Set a value on an object using a string path (dot notation).
|
|
21
|
+
* Creates nested objects/arrays if they don't exist.
|
|
22
|
+
*/
|
|
23
|
+
export function setValueByPath(obj, path, value) {
|
|
24
|
+
if (obj == null || !path)
|
|
25
|
+
return;
|
|
26
|
+
const normalizedPath = path.replace(/\[(\w+)\]/g, ".$1");
|
|
27
|
+
const parts = normalizedPath.split(".");
|
|
28
|
+
let current = obj;
|
|
29
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
30
|
+
const part = parts[i];
|
|
31
|
+
// If the property doesn't exist, create it.
|
|
32
|
+
// Look ahead to decide if we need an array or an object.
|
|
33
|
+
if (current[part] == null) {
|
|
34
|
+
const nextPart = parts[i + 1];
|
|
35
|
+
// If next part is an integer, assume array.
|
|
36
|
+
const isNextIndex = !isNaN(parseInt(nextPart)) && isFinite(parseInt(nextPart));
|
|
37
|
+
current[part] = isNextIndex ? [] : {};
|
|
38
|
+
}
|
|
39
|
+
current = current[part];
|
|
40
|
+
}
|
|
41
|
+
const lastPart = parts[parts.length - 1];
|
|
42
|
+
current[lastPart] = value;
|
|
43
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapper-factory",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "mapper for typescript object",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
7
14
|
"files": [
|
|
8
15
|
"/dist",
|
|
9
16
|
"/images"
|
|
@@ -11,7 +18,7 @@
|
|
|
11
18
|
"scripts": {
|
|
12
19
|
"build": "npx tsc",
|
|
13
20
|
"dev": "npx tsc --watch",
|
|
14
|
-
"test": "npx
|
|
21
|
+
"test": "npx tsx src/test.ts",
|
|
15
22
|
"patch": "npm version patch",
|
|
16
23
|
"minor": "npm version minor",
|
|
17
24
|
"major": "npm version major",
|
|
@@ -34,9 +41,6 @@
|
|
|
34
41
|
"url": "https://github.com/lucaAngrisani/mapper-factory/issues"
|
|
35
42
|
},
|
|
36
43
|
"homepage": "https://github.com/lucaAngrisani/mapper-factory#readme",
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"reflect-metadata": "^0.2.2"
|
|
39
|
-
},
|
|
40
44
|
"devDependencies": {
|
|
41
45
|
"typescript": "^5.7.3"
|
|
42
46
|
}
|