@karmaniverous/jsonmap 0.1.0 → 0.2.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/README.md CHANGED
@@ -56,10 +56,9 @@ const map = {
56
56
  dynamic: {
57
57
  $: [
58
58
  // Each transformation object uses a special syntax to reference an
59
- // object, a method to run on it, and an array of parameters to pass.
59
+ // a method to run and an array of parameters to pass to it.
60
60
  {
61
- object: '$.lib._',
62
- method: 'get',
61
+ method: '$.lib._.get',
63
62
  params: ['$.input', 'dynamodb.NewImage.roundup.N'],
64
63
  },
65
64
  // The special syntax uses lodash-style paths. Its root object can
@@ -67,14 +66,12 @@ const map = {
67
66
  // ($.input...), the output generated so far ($.output...), or the
68
67
  // outputs of previous transformation steps ($.[0]..., $.[1]...).
69
68
  {
70
- object: '$.lib',
71
- method: 'numeral',
69
+ method: '$.lib.numeral',
72
70
  // If there is only a single param, no array is necessary.
73
71
  params: '$[0]',
74
72
  },
75
73
  {
76
- object: '$[0]',
77
- method: 'format',
74
+ method: '$[0].format',
78
75
  params: '$0,0.00',
79
76
  },
80
77
  ],
@@ -85,8 +82,7 @@ const map = {
85
82
  // previous output of the same mapping object.
86
83
  progressive: {
87
84
  $: {
88
- object: '$.lib._',
89
- method: 'toUpper',
85
+ method: '$.lib._.toUpper',
90
86
  params: '$.output.bar[0].static',
91
87
  },
92
88
  },
@@ -115,44 +111,44 @@ const output = await jsonMap.transform(input);
115
111
  ```
116
112
 
117
113
  The [unit tests](https://github.com/karmaniverous/jsonmap/blob/main/lib/JsonMap/JsonMap.test.js) demonstrate this example in action.
118
-
114
+
119
115
  # API Documentation
120
116
 
121
- <a name="JsonMap"></a>
122
-
123
- ## JsonMap
124
- JsonMap class to apply transformations to a JSON object
125
-
126
- **Kind**: global class
127
-
128
- * [JsonMap](#JsonMap)
129
- * [new JsonMap([map], [lib])](#new_JsonMap_new)
130
- * [.transform(input)](#JsonMap+transform) ⇒ <code>object</code>
131
-
132
- <a name="new_JsonMap_new"></a>
133
-
134
- ### new JsonMap([map], [lib])
135
- Creates an instance of JsonMap.
136
-
137
-
138
- | Param | Type | Description |
139
- | --- | --- | --- |
140
- | [map] | <code>object</code> | The data mapping configuration. |
141
- | [lib] | <code>object</code> | A collection of function libraries. |
142
-
143
- <a name="JsonMap+transform"></a>
144
-
145
- ### jsonMap.transform(input) ⇒ <code>object</code>
146
- Transforms the input data according to the map configuration.
147
-
148
- **Kind**: instance method of [<code>JsonMap</code>](#JsonMap)
149
- **Returns**: <code>object</code> - - The transformed data.
150
-
151
- | Param | Type | Description |
152
- | --- | --- | --- |
153
- | input | <code>object</code> | The input data to be transformed. |
154
-
155
-
117
+ <a name="JsonMap"></a>
118
+
119
+ ## JsonMap
120
+ JsonMap class to apply transformations to a JSON object
121
+
122
+ **Kind**: global class
123
+
124
+ * [JsonMap](#JsonMap)
125
+ * [new JsonMap([map], [lib])](#new_JsonMap_new)
126
+ * [.transform(input)](#JsonMap+transform) ⇒ <code>object</code>
127
+
128
+ <a name="new_JsonMap_new"></a>
129
+
130
+ ### new JsonMap([map], [lib])
131
+ Creates an instance of JsonMap.
132
+
133
+
134
+ | Param | Type | Description |
135
+ | --- | --- | --- |
136
+ | [map] | <code>object</code> | The data mapping configuration. |
137
+ | [lib] | <code>object</code> | A collection of function libraries. |
138
+
139
+ <a name="JsonMap+transform"></a>
140
+
141
+ ### jsonMap.transform(input) ⇒ <code>object</code>
142
+ Transforms the input data according to the map configuration.
143
+
144
+ **Kind**: instance method of [<code>JsonMap</code>](#JsonMap)
145
+ **Returns**: <code>object</code> - - The transformed data.
146
+
147
+ | Param | Type | Description |
148
+ | --- | --- | --- |
149
+ | input | <code>object</code> | The input data to be transformed. |
150
+
151
+
156
152
  ---
157
153
 
158
154
  See more great templates and other tools on
@@ -7,14 +7,15 @@ exports.JsonMap = void 0;
7
7
  var _lodash = _interopRequireDefault(require("lodash.castarray"));
8
8
  var _lodash2 = _interopRequireDefault(require("lodash.clonedeepwith"));
9
9
  var _lodash3 = _interopRequireDefault(require("lodash.get"));
10
- var _lodash4 = _interopRequireDefault(require("lodash.isarray"));
11
- var _lodash5 = _interopRequireDefault(require("lodash.isobject"));
12
- var _lodash6 = _interopRequireDefault(require("lodash.isplainobject"));
13
- var _lodash7 = _interopRequireDefault(require("lodash.isstring"));
14
- var _lodash8 = _interopRequireDefault(require("lodash.mapvalues"));
15
- var _lodash9 = _interopRequireDefault(require("lodash.pickby"));
16
- var _lodash10 = _interopRequireDefault(require("lodash.set"));
17
- var _lodash11 = _interopRequireDefault(require("lodash.size"));
10
+ var _lodash4 = _interopRequireDefault(require("lodash.invoke"));
11
+ var _lodash5 = _interopRequireDefault(require("lodash.isarray"));
12
+ var _lodash6 = _interopRequireDefault(require("lodash.isobject"));
13
+ var _lodash7 = _interopRequireDefault(require("lodash.isplainobject"));
14
+ var _lodash8 = _interopRequireDefault(require("lodash.isstring"));
15
+ var _lodash9 = _interopRequireDefault(require("lodash.mapvalues"));
16
+ var _lodash10 = _interopRequireDefault(require("lodash.pickby"));
17
+ var _lodash11 = _interopRequireDefault(require("lodash.set"));
18
+ var _lodash12 = _interopRequireDefault(require("lodash.size"));
18
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
20
  // npm imports
20
21
 
@@ -49,8 +50,8 @@ class JsonMap {
49
50
  // Calls the #transform method to perform the transformation
50
51
  const result = await this.#transform(this.map, this.input, this.output);
51
52
 
52
- // Recursively eliminate keys starting with $.
53
- const deep = value => (0, _lodash6.default)(value) ? (0, _lodash8.default)((0, _lodash9.default)(value, (v, k) => /^[^$]/.test(k)), value => (0, _lodash2.default)(value, deep)) : undefined;
53
+ // Recursively eliminate string keys starting with $.
54
+ const deep = value => (0, _lodash7.default)(value) ? (0, _lodash9.default)((0, _lodash10.default)(value, (v, k) => !(0, _lodash8.default)(k) || /^[^$]/.test(k)), value => (0, _lodash2.default)(value, deep)) : undefined;
54
55
  return (0, _lodash2.default)(result, deep);
55
56
  }
56
57
 
@@ -67,7 +68,7 @@ class JsonMap {
67
68
  async #transform(node, input, output) {
68
69
  let path = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
69
70
  // Checks if the current node is an object and has a '$' key
70
- if ((0, _lodash6.default)(node) && (0, _lodash11.default)(node) === 1 && '$' in node) {
71
+ if ((0, _lodash7.default)(node) && (0, _lodash12.default)(node) === 1 && '$' in node) {
71
72
  // Retrieves the transformations to be applied (can be an array or a single object)
72
73
  const transformations = (0, _lodash.default)(node['$']);
73
74
 
@@ -77,27 +78,36 @@ class JsonMap {
77
78
  // Iterates over each transformation
78
79
  for (const transformation of transformations) {
79
80
  // Resolves the object path for the transformation
80
- const object = this.#resolvePath(transformation.object, results);
81
+ const {
82
+ obj: methodObj,
83
+ path: methodPath
84
+ } = this.#resolvePath(transformation.method, results);
81
85
 
82
86
  // Resolves the parameter paths for the transformation
83
- const params = await Promise.all((0, _lodash.default)(transformation.params).map(param => this.#resolvePath(param, results)));
87
+ const params = await Promise.all((0, _lodash.default)(transformation.params).map(param => {
88
+ const {
89
+ obj: paramObj,
90
+ path: paramPath
91
+ } = this.#resolvePath(param, results);
92
+ return paramObj ? paramPath ? (0, _lodash3.default)(paramObj, paramPath) : paramObj : paramPath;
93
+ }));
84
94
 
85
95
  // Calls the specified method on the resolved object with the resolved parameters
86
- const result = await object[transformation.method](...params);
96
+ const result = await (0, _lodash4.default)(methodObj, methodPath, ...params);
87
97
 
88
98
  // Stores the result of the transformation
89
99
  results.unshift(result);
90
100
  }
91
101
 
92
102
  // Sets the output at the specified path to the last result of the transformations & returns.
93
- (0, _lodash10.default)(output, path, results[0]);
103
+ (0, _lodash11.default)(output, path, results[0]);
94
104
  return results[0];
95
105
  }
96
106
 
97
107
  // Checks if the current node is an object
98
- if ((0, _lodash5.default)(node)) {
108
+ if ((0, _lodash6.default)(node)) {
99
109
  // Creates an empty array or object based on whether the current node is an array or not
100
- const transformedNode = (0, _lodash4.default)(node) ? [] : {};
110
+ const transformedNode = (0, _lodash5.default)(node) ? [] : {};
101
111
 
102
112
  // Iterates over each key-value pair in the current node
103
113
  for (const [key, value] of Object.entries(node)) {
@@ -110,26 +120,33 @@ class JsonMap {
110
120
  }
111
121
 
112
122
  // Sets the output at the specified path to the transformedNode & returnsd.
113
- (0, _lodash10.default)(output, path, transformedNode);
123
+ (0, _lodash11.default)(output, path, transformedNode);
114
124
  return transformedNode;
115
125
  }
116
126
 
117
127
  // Sets the output at the specified path to the current node & returns.
118
- (0, _lodash10.default)(output, path, node);
128
+ (0, _lodash11.default)(output, path, node);
119
129
  return node;
120
130
  }
121
131
 
122
132
  /**
123
- * Resolves the object/method/params path for a transformation
133
+ * @typedef {object} PathResolution
134
+ * @property {object} obj - The object to be used for the transformation.
135
+ * @property {string} path - The path to the value to be used for the transformation.
136
+ * @private
137
+ */
138
+
139
+ /**
140
+ * Resolves the method/params path for a transformation
124
141
  *
125
142
  * @param {string} path - The path to be resolved.
126
143
  * @param {Array} results - The results from previous transformations.
127
- * @return {string} - The resolved path.
144
+ * @return {PathResolution} - The resolved path.
128
145
  * @private
129
146
  */
130
147
  #resolvePath(path, results) {
131
148
  // If the path is not a string, return it as is
132
- if (!(0, _lodash7.default)(path)) {
149
+ if (!(0, _lodash8.default)(path)) {
133
150
  return path;
134
151
  }
135
152
 
@@ -140,13 +157,19 @@ class JsonMap {
140
157
  obj,
141
158
  path
142
159
  } = _ref;
143
- return path.length ? (0, _lodash3.default)(this[obj], path) : this[obj];
160
+ return {
161
+ obj: this[obj],
162
+ path
163
+ };
144
164
  },
145
165
  '^\\$(?<path>\\[\\d+\\].*)': _ref2 => {
146
166
  let {
147
167
  path
148
168
  } = _ref2;
149
- return (0, _lodash3.default)(results, path);
169
+ return {
170
+ obj: results,
171
+ path
172
+ };
150
173
  }
151
174
  };
152
175
 
@@ -157,7 +180,9 @@ class JsonMap {
157
180
  }
158
181
 
159
182
  // Returns the path as is if it does not match any special patterns
160
- return path;
183
+ return {
184
+ path
185
+ };
161
186
  }
162
187
  }
163
188
 
@@ -2,6 +2,7 @@
2
2
  import castArray from 'lodash.castarray';
3
3
  import cloneDeepWith from 'lodash.clonedeepwith';
4
4
  import get from 'lodash.get';
5
+ import invoke from 'lodash.invoke';
5
6
  import isArray from 'lodash.isarray';
6
7
  import isObject from 'lodash.isobject';
7
8
  import isPlainObject from 'lodash.isplainobject';
@@ -40,11 +41,11 @@ class JsonMap {
40
41
  // Calls the #transform method to perform the transformation
41
42
  const result = await this.#transform(this.map, this.input, this.output);
42
43
 
43
- // Recursively eliminate keys starting with $.
44
+ // Recursively eliminate string keys starting with $.
44
45
  const deep = (value) =>
45
46
  isPlainObject(value)
46
47
  ? mapValues(
47
- pickBy(value, (v, k) => /^[^$]/.test(k)),
48
+ pickBy(value, (v, k) => !isString(k) || /^[^$]/.test(k)),
48
49
  (value) => cloneDeepWith(value, deep)
49
50
  )
50
51
  : undefined;
@@ -74,17 +75,28 @@ class JsonMap {
74
75
  // Iterates over each transformation
75
76
  for (const transformation of transformations) {
76
77
  // Resolves the object path for the transformation
77
- const object = this.#resolvePath(transformation.object, results);
78
+ const { obj: methodObj, path: methodPath } = this.#resolvePath(
79
+ transformation.method,
80
+ results
81
+ );
78
82
 
79
83
  // Resolves the parameter paths for the transformation
80
84
  const params = await Promise.all(
81
- castArray(transformation.params).map((param) =>
82
- this.#resolvePath(param, results)
83
- )
85
+ castArray(transformation.params).map((param) => {
86
+ const { obj: paramObj, path: paramPath } = this.#resolvePath(
87
+ param,
88
+ results
89
+ );
90
+ return paramObj
91
+ ? paramPath
92
+ ? get(paramObj, paramPath)
93
+ : paramObj
94
+ : paramPath;
95
+ })
84
96
  );
85
97
 
86
98
  // Calls the specified method on the resolved object with the resolved parameters
87
- const result = await object[transformation.method](...params);
99
+ const result = await invoke(methodObj, methodPath, ...params);
88
100
 
89
101
  // Stores the result of the transformation
90
102
  results.unshift(result);
@@ -126,11 +138,18 @@ class JsonMap {
126
138
  }
127
139
 
128
140
  /**
129
- * Resolves the object/method/params path for a transformation
141
+ * @typedef {object} PathResolution
142
+ * @property {object} obj - The object to be used for the transformation.
143
+ * @property {string} path - The path to the value to be used for the transformation.
144
+ * @private
145
+ */
146
+
147
+ /**
148
+ * Resolves the method/params path for a transformation
130
149
  *
131
150
  * @param {string} path - The path to be resolved.
132
151
  * @param {Array} results - The results from previous transformations.
133
- * @return {string} - The resolved path.
152
+ * @return {PathResolution} - The resolved path.
134
153
  * @private
135
154
  */
136
155
  #resolvePath(path, results) {
@@ -141,9 +160,14 @@ class JsonMap {
141
160
 
142
161
  // Defines special patterns and their corresponding resolution functions
143
162
  const patterns = {
144
- '^\\$\\.(?<obj>lib|input|output)\\.?(?<path>.*)': ({ obj, path }) =>
145
- path.length ? get(this[obj], path) : this[obj],
146
- '^\\$(?<path>\\[\\d+\\].*)': ({ path }) => get(results, path),
163
+ '^\\$\\.(?<obj>lib|input|output)\\.?(?<path>.*)': ({ obj, path }) => ({
164
+ obj: this[obj],
165
+ path,
166
+ }),
167
+ '^\\$(?<path>\\[\\d+\\].*)': ({ path }) => ({
168
+ obj: results,
169
+ path,
170
+ }),
147
171
  };
148
172
 
149
173
  // Iterates over the special patterns
@@ -153,7 +177,7 @@ class JsonMap {
153
177
  }
154
178
 
155
179
  // Returns the path as is if it does not match any special patterns
156
- return path;
180
+ return { path };
157
181
  }
158
182
  }
159
183
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@karmaniverous/jsonmap",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -25,6 +25,7 @@
25
25
  "lodash.castarray": "^4.4.0",
26
26
  "lodash.clonedeepwith": "^4.5.0",
27
27
  "lodash.get": "^4.4.2",
28
+ "lodash.invoke": "^4.5.2",
28
29
  "lodash.isarray": "^4.0.0",
29
30
  "lodash.isobject": "^3.0.2",
30
31
  "lodash.isplainobject": "^4.0.6",
@@ -35,26 +36,27 @@
35
36
  "lodash.size": "^4.2.0"
36
37
  },
37
38
  "devDependencies": {
38
- "@babel/cli": "^7.21.5",
39
- "@babel/core": "^7.22.1",
40
- "@babel/eslint-parser": "^7.21.8",
41
- "@babel/plugin-syntax-import-assertions": "^7.20.0",
42
- "@babel/preset-env": "^7.22.4",
43
- "@babel/register": "^7.21.0",
44
- "@karmaniverous/get-dotenv": "^2.4.1",
45
- "@types/node": "^20.2.5",
39
+ "@babel/cli": "^7.22.10",
40
+ "@babel/core": "^7.22.10",
41
+ "@babel/eslint-parser": "^7.22.10",
42
+ "@babel/plugin-syntax-import-assertions": "^7.22.5",
43
+ "@babel/preset-env": "^7.22.10",
44
+ "@babel/register": "^7.22.5",
45
+ "@karmaniverous/get-dotenv": "^3.1.13",
46
+ "@types/node": "^20.5.3",
47
+ "auto-changelog": "^2.4.0",
46
48
  "chai": "^4.3.7",
47
49
  "concat-md": "^0.5.1",
48
- "eslint": "^8.41.0",
50
+ "eslint": "^8.47.0",
49
51
  "eslint-config-standard": "^17.1.0",
50
- "eslint-plugin-jsdoc": "^46.1.0",
52
+ "eslint-plugin-jsdoc": "^46.5.0",
51
53
  "eslint-plugin-mocha": "^10.1.0",
52
54
  "jsdoc-to-markdown": "^8.0.0",
53
55
  "lodash": "^4.17.21",
54
56
  "mocha": "^10.2.0",
55
57
  "numeral": "^2.0.6",
56
- "prettier": "^2.8.8",
57
- "release-it": "^15.10.3"
58
+ "prettier": "^3.0.2",
59
+ "release-it": "^16.1.5"
58
60
  },
59
61
  "exports": {
60
62
  ".": {
@@ -75,9 +77,27 @@
75
77
  "spec": "./**/*.test.!(*.*)"
76
78
  },
77
79
  "release-it": {
80
+ "git": {
81
+ "changelog": "npx auto-changelog --stdout --commit-limit false -u --template https://raw.githubusercontent.com/release-it/release-it/main/templates/changelog-compact.hbs",
82
+ "requireBranch": "main",
83
+ "commitMessage": "chore: release v${version}"
84
+ },
78
85
  "github": {
79
86
  "release": true
80
87
  },
88
+ "hooks": {
89
+ "after:init": [
90
+ "nr lint",
91
+ "nr test",
92
+ "nr build",
93
+ "nr doc"
94
+ ],
95
+ "after:release": [
96
+ "git switch -c release/${version}",
97
+ "git push -u origin release/${version}",
98
+ "git switch main"
99
+ ]
100
+ },
81
101
  "npm": {
82
102
  "publish": true
83
103
  }
@@ -87,8 +107,8 @@
87
107
  "doc": "jsdoc2md -c doc/jsdoc.config.json -f lib/**/*.* -t doc/api-template.hbs > doc/2-api.jsdoc2.md && concat-md doc --hide-anchor-links > README.md",
88
108
  "lint": "eslint lib/**",
89
109
  "prerelease": "npm run lint && npm run test && npm run build && npm run doc",
90
- "release": "release-it",
91
- "test": "getdotenv -c \"mocha\" -p ./ ./env -d dev -y ./env/dynamic.js"
110
+ "release": "getdotenv -c \"release-it\"",
111
+ "test": "getdotenv -c \"mocha\""
92
112
  },
93
113
  "type": "module"
94
114
  }