@karmaniverous/jsonmap 0.0.2 → 0.0.4
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 +18 -6
- package/dist/default/lib/JsonMap/JsonMap.js +23 -23
- package/lib/JsonMap/JsonMap.js +25 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,14 +41,15 @@ The transformation output will reflect the structure of your `map` object and in
|
|
|
41
41
|
|
|
42
42
|
```js
|
|
43
43
|
const map = {
|
|
44
|
-
|
|
44
|
+
foo: 'static value passed directly to output',
|
|
45
45
|
// Structure passed directly to output.
|
|
46
|
-
|
|
46
|
+
bar: [
|
|
47
47
|
{
|
|
48
|
-
|
|
49
|
-
// Value defined by mapping rule
|
|
50
|
-
// If there is only a single transformation object, no array is
|
|
51
|
-
|
|
48
|
+
static: 'another static value',
|
|
49
|
+
// Value defined by a mapping rule expressing an array of transformation
|
|
50
|
+
// objects. If there is only a single transformation object, no array is
|
|
51
|
+
// necessary.
|
|
52
|
+
dynamic: {
|
|
52
53
|
$: [
|
|
53
54
|
// Each transformation object uses a special syntax to reference an
|
|
54
55
|
// object, a method to run on it, and an array of parameters to pass.
|
|
@@ -76,6 +77,15 @@ const map = {
|
|
|
76
77
|
},
|
|
77
78
|
},
|
|
78
79
|
],
|
|
80
|
+
// Value defined by a single mapping rule executing a method against a
|
|
81
|
+
// previous output of the same mapping object.
|
|
82
|
+
progressive: {
|
|
83
|
+
$: {
|
|
84
|
+
object: '$.lib._',
|
|
85
|
+
method: 'toUpper',
|
|
86
|
+
params: '$.output.bar[0].static',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
79
89
|
};
|
|
80
90
|
```
|
|
81
91
|
|
|
@@ -98,6 +108,8 @@ const jsonMap = new JsonMap(lib, map);
|
|
|
98
108
|
// Assumes some input data object is already defined.
|
|
99
109
|
const output = await jsonMap.transform(input);
|
|
100
110
|
```
|
|
111
|
+
|
|
112
|
+
The [unit tests](https://github.com/karmaniverous/jsonmap/blob/main/lib/JsonMap/JsonMap.test.js) demonstrate this example in action.
|
|
101
113
|
|
|
102
114
|
# API Documentation
|
|
103
115
|
|
|
@@ -4,15 +4,15 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.JsonMap = void 0;
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
15
|
-
var
|
|
7
|
+
var _castArray = _interopRequireDefault(require("lodash/castArray.js"));
|
|
8
|
+
var _get = _interopRequireDefault(require("lodash/get.js"));
|
|
9
|
+
var _isArray = _interopRequireDefault(require("lodash/isArray.js"));
|
|
10
|
+
var _isNil = _interopRequireDefault(require("lodash/isNil.js"));
|
|
11
|
+
var _isObject = _interopRequireDefault(require("lodash/isObject.js"));
|
|
12
|
+
var _isString = _interopRequireDefault(require("lodash/isString.js"));
|
|
13
|
+
var _last = _interopRequireDefault(require("lodash/last.js"));
|
|
14
|
+
var _parseInt = _interopRequireDefault(require("lodash/parseInt.js"));
|
|
15
|
+
var _set = _interopRequireDefault(require("lodash/set.js"));
|
|
16
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
17
|
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
18
18
|
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
@@ -68,9 +68,9 @@ exports.JsonMap = JsonMap;
|
|
|
68
68
|
async function _transform2(node, input, output) {
|
|
69
69
|
let path = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
|
|
70
70
|
// Checks if the current node is an object and has a '$' key
|
|
71
|
-
if ((0,
|
|
71
|
+
if ((0, _isObject.default)(node) && '$' in node) {
|
|
72
72
|
// Retrieves the transformations to be applied (can be an array or a single object)
|
|
73
|
-
const transformations = (0,
|
|
73
|
+
const transformations = (0, _isArray.default)(node['$']) ? node['$'] : [node['$']];
|
|
74
74
|
|
|
75
75
|
// Array to store the results of the transformations
|
|
76
76
|
let results = [];
|
|
@@ -81,7 +81,7 @@ async function _transform2(node, input, output) {
|
|
|
81
81
|
const object = _classPrivateMethodGet(this, _resolvePath, _resolvePath2).call(this, transformation.object, results);
|
|
82
82
|
|
|
83
83
|
// Resolves the parameter paths for the transformation
|
|
84
|
-
const params = await Promise.all((0,
|
|
84
|
+
const params = await Promise.all((0, _castArray.default)(transformation.params).map(param => _classPrivateMethodGet(this, _resolvePath, _resolvePath2).call(this, param, results)));
|
|
85
85
|
|
|
86
86
|
// Calls the specified method on the resolved object with the resolved parameters
|
|
87
87
|
const result = await object[transformation.method](...params);
|
|
@@ -91,15 +91,15 @@ async function _transform2(node, input, output) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// Sets the output at the specified path to the last result of the transformations & returns.
|
|
94
|
-
const
|
|
95
|
-
(0,
|
|
96
|
-
return
|
|
94
|
+
const lastResult = (0, _last.default)(results);
|
|
95
|
+
(0, _set.default)(output, path, lastResult);
|
|
96
|
+
return lastResult;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// Checks if the current node is an object
|
|
100
|
-
if ((0,
|
|
100
|
+
if ((0, _isObject.default)(node)) {
|
|
101
101
|
// Creates an empty array or object based on whether the current node is an array or not
|
|
102
|
-
const transformedNode = (0,
|
|
102
|
+
const transformedNode = (0, _isArray.default)(node) ? [] : {};
|
|
103
103
|
|
|
104
104
|
// Iterates over each key-value pair in the current node
|
|
105
105
|
for (const [key, value] of Object.entries(node)) {
|
|
@@ -112,17 +112,17 @@ async function _transform2(node, input, output) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
// Sets the output at the specified path to the transformedNode & returnsd.
|
|
115
|
-
(0,
|
|
115
|
+
(0, _set.default)(output, path, transformedNode);
|
|
116
116
|
return transformedNode;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
// Sets the output at the specified path to the current node & returns.
|
|
120
|
-
(0,
|
|
120
|
+
(0, _set.default)(output, path, node);
|
|
121
121
|
return node;
|
|
122
122
|
}
|
|
123
123
|
function _resolvePath2(path, results) {
|
|
124
124
|
// If the path is not a string, return it as is
|
|
125
|
-
if (!(0,
|
|
125
|
+
if (!(0, _isString.default)(path)) {
|
|
126
126
|
return path;
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -139,7 +139,7 @@ function _resolvePath2(path, results) {
|
|
|
139
139
|
// Retrieves the value from the previous results based on the index and any remaining path
|
|
140
140
|
if (match) {
|
|
141
141
|
const [, index, rest] = match;
|
|
142
|
-
const value = (0,
|
|
142
|
+
const value = (0, _get.default)(results, [results.length - 1 - (0, _parseInt.default)(index), ...(rest.length ? rest.split('.') : [])]);
|
|
143
143
|
|
|
144
144
|
// Returns the value if it exists, otherwise returns the original path
|
|
145
145
|
return value != null ? value : path;
|
|
@@ -151,10 +151,10 @@ function _resolvePath2(path, results) {
|
|
|
151
151
|
const p = path.slice(pattern.length + 1);
|
|
152
152
|
|
|
153
153
|
// Retrieves the value from the replacement object based on the remaining path
|
|
154
|
-
const value = p.length ? (0,
|
|
154
|
+
const value = p.length ? (0, _get.default)(replacement, p) : replacement;
|
|
155
155
|
|
|
156
156
|
// Returns the value if it exists, otherwise returns the original path
|
|
157
|
-
return (0,
|
|
157
|
+
return (0, _isNil.default)(value) ? path : value;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
// Returns the path as is if it does not match any special patterns
|
package/lib/JsonMap/JsonMap.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
// npm imports
|
|
2
|
+
import castArray from 'lodash/castArray.js';
|
|
3
|
+
import get from 'lodash/get.js';
|
|
4
|
+
import isArray from 'lodash/isArray.js';
|
|
5
|
+
import isNil from 'lodash/isNil.js';
|
|
6
|
+
import isObject from 'lodash/isObject.js';
|
|
7
|
+
import isString from 'lodash/isString.js';
|
|
8
|
+
import last from 'lodash/last.js';
|
|
9
|
+
import parseInt from 'lodash/parseInt.js';
|
|
10
|
+
import set from 'lodash/set.js';
|
|
2
11
|
|
|
3
12
|
/**
|
|
4
13
|
* JsonMap class to apply transformations to a JSON object
|
|
@@ -42,9 +51,9 @@ class JsonMap {
|
|
|
42
51
|
*/
|
|
43
52
|
async #transform(node, input, output, path = '') {
|
|
44
53
|
// Checks if the current node is an object and has a '$' key
|
|
45
|
-
if (
|
|
54
|
+
if (isObject(node) && '$' in node) {
|
|
46
55
|
// Retrieves the transformations to be applied (can be an array or a single object)
|
|
47
|
-
const transformations =
|
|
56
|
+
const transformations = isArray(node['$']) ? node['$'] : [node['$']];
|
|
48
57
|
|
|
49
58
|
// Array to store the results of the transformations
|
|
50
59
|
let results = [];
|
|
@@ -56,7 +65,7 @@ class JsonMap {
|
|
|
56
65
|
|
|
57
66
|
// Resolves the parameter paths for the transformation
|
|
58
67
|
const params = await Promise.all(
|
|
59
|
-
|
|
68
|
+
castArray(transformation.params).map((param) =>
|
|
60
69
|
this.#resolvePath(param, results)
|
|
61
70
|
)
|
|
62
71
|
);
|
|
@@ -69,15 +78,15 @@ class JsonMap {
|
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
// Sets the output at the specified path to the last result of the transformations & returns.
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
return
|
|
81
|
+
const lastResult = last(results);
|
|
82
|
+
set(output, path, lastResult);
|
|
83
|
+
return lastResult;
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
// Checks if the current node is an object
|
|
78
|
-
if (
|
|
87
|
+
if (isObject(node)) {
|
|
79
88
|
// Creates an empty array or object based on whether the current node is an array or not
|
|
80
|
-
const transformedNode =
|
|
89
|
+
const transformedNode = isArray(node) ? [] : {};
|
|
81
90
|
|
|
82
91
|
// Iterates over each key-value pair in the current node
|
|
83
92
|
for (const [key, value] of Object.entries(node)) {
|
|
@@ -95,12 +104,12 @@ class JsonMap {
|
|
|
95
104
|
}
|
|
96
105
|
|
|
97
106
|
// Sets the output at the specified path to the transformedNode & returnsd.
|
|
98
|
-
|
|
107
|
+
set(output, path, transformedNode);
|
|
99
108
|
return transformedNode;
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
// Sets the output at the specified path to the current node & returns.
|
|
103
|
-
|
|
112
|
+
set(output, path, node);
|
|
104
113
|
return node;
|
|
105
114
|
}
|
|
106
115
|
|
|
@@ -114,7 +123,7 @@ class JsonMap {
|
|
|
114
123
|
*/
|
|
115
124
|
#resolvePath(path, results) {
|
|
116
125
|
// If the path is not a string, return it as is
|
|
117
|
-
if (!
|
|
126
|
+
if (!isString(path)) {
|
|
118
127
|
return path;
|
|
119
128
|
}
|
|
120
129
|
|
|
@@ -131,8 +140,8 @@ class JsonMap {
|
|
|
131
140
|
// Retrieves the value from the previous results based on the index and any remaining path
|
|
132
141
|
if (match) {
|
|
133
142
|
const [, index, rest] = match;
|
|
134
|
-
const value =
|
|
135
|
-
results.length - 1 -
|
|
143
|
+
const value = get(results, [
|
|
144
|
+
results.length - 1 - parseInt(index),
|
|
136
145
|
...(rest.length ? rest.split('.') : []),
|
|
137
146
|
]);
|
|
138
147
|
|
|
@@ -147,10 +156,10 @@ class JsonMap {
|
|
|
147
156
|
const p = path.slice(pattern.length + 1);
|
|
148
157
|
|
|
149
158
|
// Retrieves the value from the replacement object based on the remaining path
|
|
150
|
-
const value = p.length ?
|
|
159
|
+
const value = p.length ? get(replacement, p) : replacement;
|
|
151
160
|
|
|
152
161
|
// Returns the value if it exists, otherwise returns the original path
|
|
153
|
-
return
|
|
162
|
+
return isNil(value) ? path : value;
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
// Returns the path as is if it does not match any special patterns
|