This repository has been archived by the owner on Jan 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 112
/
mapper.js
106 lines (102 loc) · 2.25 KB
/
mapper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* The mapper will be able to map a flat document map to a complex object using a given pattern. The pattern consists of
* the structure of the desired object and the key names that are going to mapped as values.
*
* @example
*
* {
* _id: 'id',
* person: {
* name: 'name'
* },
* numerical: {
* integers: {
* levels: 'age',
* now: 'timestamp'
* }
* }
* }
*
* The input data to map to this document would look something like this:
*
* {
* id: '123456',
* name: 'Test Element',
* age: 21,
* timestamp: 1234567890
* }
*
* And the mapped end result would look like this:
*
* {
* _id: '123456',
* person: {
* name: 'Test Element'
* },
* numerical: {
* integers: {
* levels: 21,
* now: 1234567890
* }
* }
* }
*
*/
class Mapper {
/**
*
* @param {Object|string} pattern
*/
constructor(pattern) {
this._fields = {};
this._findValue([], pattern);
}
/**
*
* @param {string[]} parents
* @param {Object|string} obj
* @private
*/
_findValue(parents, obj) {
for (let i in obj) {
let newParents = parents.concat(i);
if (typeof obj[i] == 'string') {
this._fields[obj[i]] = newParents;
} else {
this._findValue(newParents, obj[i]);
}
}
}
/**
* The mapping function that will convert a flat map to a complex object.
* @param {Object|Object[]} data
* @returns {Object}
*/
map(data) {
if (Array.isArray(data)) {
return data.map(this.map.bind(this));
}
let result = {};
for (let i in data) {
this._fields[i] && this._buildObject(this._fields[i].slice(), data[i], result);
}
return result;
}
/**
*
* @param {string[]} path
* @param {Object} value
* @param {Object} result
* @private
*/
_buildObject(path, value, result) {
let field = path.shift();
if (!path.length) {
result[field] = value;
} else {
result[field] = result[field] || {};
this._buildObject(path, value, result[field]);
}
}
}
exports.Mapper = Mapper;