@coderich/util 0.1.16 → 1.0.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.
Files changed (2) hide show
  1. package/package.json +5 -5
  2. package/src/index.js +35 -13
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@coderich/util",
3
3
  "main": "src/index.js",
4
- "version": "0.1.16",
4
+ "version": "1.0.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -11,15 +11,15 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "test": "jest --config=jest.config.js",
14
- "lint": "eslint --config=.eslintrc ./",
14
+ "lint": "eslint ./",
15
15
  "dev": "coderich-dev"
16
16
  },
17
17
  "dependencies": {
18
18
  "bson-objectid": "2.0.4",
19
- "lodash.isequal": "4.5.0",
20
- "lodash.set": "4.3.2"
19
+ "dot-prop": "8.0.2",
20
+ "lodash.isequal": "4.5.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@coderich/dev": "0.1.0"
23
+ "@coderich/dev": "0.2.0"
24
24
  }
25
25
  }
package/src/index.js CHANGED
@@ -2,16 +2,17 @@ const FS = require('fs');
2
2
  const Path = require('path');
3
3
  const ChildProcess = require('child_process');
4
4
  const ObjectId = require('bson-objectid');
5
- const set = require('lodash.set');
6
5
  const isEqual = require('lodash.isequal');
6
+ const { setProperty } = require('dot-prop');
7
7
 
8
- exports.set = set;
8
+ exports.set = setProperty;
9
9
  exports.isEqual = isEqual;
10
10
  exports.ObjectId = ObjectId;
11
11
 
12
- exports.push = (arr, it) => arr[arr.push(it) - 1];
12
+ exports.push = (arr, el) => arr[arr.push(el) - 1];
13
13
  exports.uvl = (...values) => values.reduce((prev, value) => (prev === undefined ? value : prev), undefined);
14
14
  exports.nvl = (...values) => values.reduce((prev, value) => (prev === null ? value : prev), null);
15
+ exports.pairs = (...values) => values.flat().reduce((prev, curr, i, arr) => (i % 2 === 0 ? prev.concat([arr.slice(i, i + 2)]) : prev), []);
15
16
  exports.filterBy = (arr, fn) => arr.filter((b, index) => index === arr.findIndex(a => fn(a, b)));
16
17
  exports.ensureArray = a => (Array.isArray(a) ? a : [a].filter(el => el !== undefined));
17
18
  exports.timeout = ms => new Promise((resolve) => { setTimeout(resolve, ms); });
@@ -19,6 +20,14 @@ exports.ucFirst = string => string.charAt(0).toUpperCase() + string.slice(1);
19
20
  exports.isScalarValue = value => value !== Object(value);
20
21
  exports.isPlainObjectOrArray = obj => Array.isArray(obj) || exports.isPlainObject(obj);
21
22
 
23
+ exports.findAndReplace = (arr, fn, ...items) => {
24
+ return arr.find((el, i, ...rest) => {
25
+ const res = fn(el, i, ...rest);
26
+ if (res) arr.splice(i, 1, ...items);
27
+ return res;
28
+ });
29
+ };
30
+
22
31
  exports.isPlainObject = (obj) => {
23
32
  if (obj == null || Array.isArray(obj)) return false;
24
33
  const proto = Object.getPrototypeOf(obj);
@@ -48,7 +57,7 @@ exports.flatten = (mixed, options = {}) => {
48
57
  return exports.map(mixed, el => (function flatten(data, obj = {}, path = [], depth = 0) {
49
58
  if (depth <= maxDepth && typeFn(data) && Object.keys(data).length) {
50
59
  return Object.entries(data).reduce((o, [key, value]) => {
51
- const $key = options.strict && key.split('.').length > 1 ? `['${key}']` : key;
60
+ const $key = options.strict ? key.replaceAll('.', '\\.') : key;
52
61
  return flatten(value, o, path.concat($key), depth + 1);
53
62
  }, obj);
54
63
  }
@@ -67,7 +76,7 @@ exports.unflatten = (data, options = {}) => {
67
76
 
68
77
  return exports.map(data, (el) => {
69
78
  return typeFn(data) ? Object.entries(el).reduce((prev, [key, value]) => {
70
- return set(prev, key, value);
79
+ return exports.set(prev, key, value);
71
80
  }, {}) : el;
72
81
  });
73
82
  };
@@ -101,27 +110,40 @@ exports.map = (mixed, fn) => {
101
110
  return isArray ? results : results[0];
102
111
  };
103
112
 
104
- exports.pathmap = (paths, mixed, fn) => {
113
+ exports.pathmap = (paths, mixed, fn = v => v) => {
105
114
  if (!exports.isPlainObjectOrArray(mixed)) return mixed;
106
115
  if (typeof paths === 'string') paths = paths.split('.');
116
+ paths = paths.filter(Boolean);
107
117
 
108
- const traverse = (keys, parent) => {
118
+ const traverse = (keys, parent, path = [], jsonpath = []) => {
109
119
  if (exports.isPlainObjectOrArray(parent)) {
110
120
  const key = keys.shift();
111
121
  const isProperty = Object.prototype.hasOwnProperty.call(parent, key);
112
122
 
123
+ // When there are more keys to go; the best we can do is traverse what's there
124
+ // Otherwise, when at the last key, we can callback and assign response value
113
125
  if (keys.length) {
114
- if (isProperty) traverse(keys, parent[key]);
115
- else if (Array.isArray(parent)) parent.forEach(el => traverse([key, ...keys], el));
116
- } else if (isProperty) {
117
- parent[key] = fn(parent[key], { key, parent });
126
+ if (isProperty) {
127
+ traverse(keys, parent[key], path.concat(key), jsonpath.concat(key));
128
+ } else if (Array.isArray(parent)) {
129
+ jsonpath.push('[*]');
130
+ parent.forEach((el, i) => traverse([key, ...keys], el, path.concat(i), jsonpath));
131
+ }
118
132
  } else if (Array.isArray(parent)) {
119
- parent.forEach(el => (el[key] = fn(el[key], { key, parent: el })));
133
+ jsonpath.push('[*]');
134
+ parent.forEach((el, i) => (el[key] = fn(el[key], { key, parent: el, path: path.concat(i, key), jsonpath: jsonpath.concat(key) })));
135
+ } else {
136
+ parent[key] = fn(parent[key], { key, parent, path: path.concat(key), jsonpath: jsonpath.concat(key) });
120
137
  }
121
138
  }
122
139
  };
123
140
 
124
- traverse(paths, mixed);
141
+ if (paths.length) {
142
+ traverse(paths, mixed);
143
+ } else {
144
+ mixed = fn(mixed, { key: '', parent: mixed, path: [], jsonpath: [] });
145
+ }
146
+
125
147
  return mixed;
126
148
  };
127
149