1 | ;
|
2 |
|
3 | var R = require('ramda');
|
4 | var Result = require('folktale/result');
|
5 | var Rm = require('ramda-maybe');
|
6 |
|
7 | function _typeof(obj) {
|
8 | "@babel/helpers - typeof";
|
9 |
|
10 | if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
11 | _typeof = function (obj) {
|
12 | return typeof obj;
|
13 | };
|
14 | } else {
|
15 | _typeof = function (obj) {
|
16 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
17 | };
|
18 | }
|
19 |
|
20 | return _typeof(obj);
|
21 | }
|
22 |
|
23 | function _defineProperty(obj, key, value) {
|
24 | if (key in obj) {
|
25 | Object.defineProperty(obj, key, {
|
26 | value: value,
|
27 | enumerable: true,
|
28 | configurable: true,
|
29 | writable: true
|
30 | });
|
31 | } else {
|
32 | obj[key] = value;
|
33 | }
|
34 |
|
35 | return obj;
|
36 | }
|
37 |
|
38 | function _setPrototypeOf(o, p) {
|
39 | _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
40 | o.__proto__ = p;
|
41 | return o;
|
42 | };
|
43 |
|
44 | return _setPrototypeOf(o, p);
|
45 | }
|
46 |
|
47 | function isNativeReflectConstruct() {
|
48 | if (typeof Reflect === "undefined" || !Reflect.construct) return false;
|
49 | if (Reflect.construct.sham) return false;
|
50 | if (typeof Proxy === "function") return true;
|
51 |
|
52 | try {
|
53 | Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
|
54 | return true;
|
55 | } catch (e) {
|
56 | return false;
|
57 | }
|
58 | }
|
59 |
|
60 | function _construct(Parent, args, Class) {
|
61 | if (isNativeReflectConstruct()) {
|
62 | _construct = Reflect.construct;
|
63 | } else {
|
64 | _construct = function _construct(Parent, args, Class) {
|
65 | var a = [null];
|
66 | a.push.apply(a, args);
|
67 | var Constructor = Function.bind.apply(Parent, a);
|
68 | var instance = new Constructor();
|
69 | if (Class) _setPrototypeOf(instance, Class.prototype);
|
70 | return instance;
|
71 | };
|
72 | }
|
73 |
|
74 | return _construct.apply(null, arguments);
|
75 | }
|
76 |
|
77 | function _slicedToArray(arr, i) {
|
78 | return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
|
79 | }
|
80 |
|
81 | function _toArray(arr) {
|
82 | return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();
|
83 | }
|
84 |
|
85 | function _toConsumableArray(arr) {
|
86 | return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
|
87 | }
|
88 |
|
89 | function _arrayWithoutHoles(arr) {
|
90 | if (Array.isArray(arr)) {
|
91 | for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
|
92 |
|
93 | return arr2;
|
94 | }
|
95 | }
|
96 |
|
97 | function _arrayWithHoles(arr) {
|
98 | if (Array.isArray(arr)) return arr;
|
99 | }
|
100 |
|
101 | function _iterableToArray(iter) {
|
102 | if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
|
103 | }
|
104 |
|
105 | function _iterableToArrayLimit(arr, i) {
|
106 | if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
|
107 | return;
|
108 | }
|
109 |
|
110 | var _arr = [];
|
111 | var _n = true;
|
112 | var _d = false;
|
113 | var _e = undefined;
|
114 |
|
115 | try {
|
116 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
|
117 | _arr.push(_s.value);
|
118 |
|
119 | if (i && _arr.length === i) break;
|
120 | }
|
121 | } catch (err) {
|
122 | _d = true;
|
123 | _e = err;
|
124 | } finally {
|
125 | try {
|
126 | if (!_n && _i["return"] != null) _i["return"]();
|
127 | } finally {
|
128 | if (_d) throw _e;
|
129 | }
|
130 | }
|
131 |
|
132 | return _arr;
|
133 | }
|
134 |
|
135 | function _nonIterableSpread() {
|
136 | throw new TypeError("Invalid attempt to spread non-iterable instance");
|
137 | }
|
138 |
|
139 | function _nonIterableRest() {
|
140 | throw new TypeError("Invalid attempt to destructure non-iterable instance");
|
141 | }
|
142 |
|
143 | var regexToMatchARegex = /\/((?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+)\/((?:g(?:im?|mi?)?|i(?:gm?|mg?)?|m(?:gi?|ig?)?)?)/;
|
144 | /**
|
145 | * We use this instead of isObject since it's possible to have something that is an object without
|
146 | * a prototype to make it an object type
|
147 | * @param {*} obj value to test
|
148 | * @return {boolean} True if R.is(Object, obj) or is not null and it a typeof 'object'
|
149 | */
|
150 |
|
151 | var isObject = function isObject(obj) {
|
152 | return R.is(Object, obj) || obj !== null && _typeof(obj) === 'object';
|
153 | };
|
154 | /**
|
155 | * Return an empty string if the given entity is falsy
|
156 | * @param {Object} entity The entity to check
|
157 | * @returns {String|Object} The empty string or the Object
|
158 | * @sig orEmpty:: a -> a
|
159 | * :: a -> String
|
160 | */
|
161 |
|
162 | var orEmpty = function orEmpty(entity) {
|
163 | return entity || '';
|
164 | };
|
165 | /**
|
166 | * Removed null or undefined items from an iterable
|
167 | * @param [a] items Items that might have falsy values to remove
|
168 | * @returns The compacted items
|
169 | * @sig compact:: [a] -> [a]
|
170 | * @sig compact:: {k,v} -> {k,v}
|
171 | */
|
172 |
|
173 | var compact = R.reject(R.isNil);
|
174 | /**
|
175 | * Remove empty strings
|
176 | * @param [a] items Items that might have empty or null strings to remove
|
177 | * @returns The compacted items
|
178 | * @sig compactEmpty:: [a] -> [a]
|
179 | */
|
180 |
|
181 | var compactEmpty = R.reject(R.either(R.isNil, R.isEmpty));
|
182 | /**
|
183 | * Convert an empty value to null
|
184 | * @param a item Item that might be empty according to isEmpty
|
185 | * @returns the
|
186 | * @sig emptyToNull:: a -> a
|
187 | * :: a -> null
|
188 | */
|
189 |
|
190 | var emptyToNull = R.when(R.isEmpty, function () {
|
191 | return null;
|
192 | });
|
193 | /**
|
194 | * Join elements, first remove null items and empty strings. If the result is empty make it null
|
195 | * @param connector Join connector string
|
196 | * @param [a] items Items to join that might be removed
|
197 | * @sig compactEmpty:: [a] -> String
|
198 | * :: [a] -> null
|
199 | */
|
200 |
|
201 | var compactJoin = R.compose(function (connector, items) {
|
202 | return R.pipe(compactEmpty, R.join(connector), emptyToNull)(items);
|
203 | });
|
204 | /**
|
205 | * Creates a partial mapping function that expects an iterable and maps each item of the iterable to the given property
|
206 | * @param {String} prop The prop of each object to map
|
207 | * @param {[Object]} items The objects to map
|
208 | * @returns {[Object]} The mapped objects
|
209 | * @sig mapProp :: String -> [{k, v}] -> [a]
|
210 | */
|
211 |
|
212 | var mapProp = R.curry(function (prop, objs) {
|
213 | return R.pipe(R.prop, R.map)(prop)(objs);
|
214 | });
|
215 | /**
|
216 | * Creates a partial function that maps an array of objects to an object keyed by the given prop of the object's
|
217 | * of the array, valued by the item. If the item is not an array, it leaves it alone, assuming it is already indexed
|
218 | * @param {String} prop The prop of each object to use as the key
|
219 | * @param {[Object]} items The items to map
|
220 | * @returns {Object} The returned object
|
221 | * @sig mapPropValueAsIndex:: String -> [{k, v}] -> {j, {k, v}}
|
222 | * @sig mapPropValueAsIndex:: String -> {k, v} -> {k, v}
|
223 | */
|
224 |
|
225 | var mapPropValueAsIndex = R.curry(function (prop, obj) {
|
226 | return R.when(Array.isArray, R.pipe(R.prop, R.indexBy)(prop))(obj);
|
227 | });
|
228 | /**
|
229 | * Merges a list of objects by the given key and returns the values, meaning all items that are
|
230 | * duplicate prop key value are removed from the final list
|
231 | * @returns {[Object]} The items without the duplicates
|
232 | * @sig removeDuplicateObjectsByProp:: String -> [{k, v}] -> [{k, v}]
|
233 | */
|
234 |
|
235 | var removeDuplicateObjectsByProp = R.curry(function (prop, list) {
|
236 | return R.pipe(mapPropValueAsIndex(prop), R.values)(list);
|
237 | });
|
238 | /**
|
239 | * Returns the id of the given value if it is an object or the value itself if it is not.
|
240 | * @param {Object|String|Number} objOrId
|
241 | * @returns {String|Number} an id
|
242 | * @sig idOrIdFromObj:: a -> a
|
243 | * :: {k, v} -> a
|
244 | */
|
245 |
|
246 | var idOrIdFromObj = R.when(function (objOrId) {
|
247 | return _typeof(objOrId) === 'object' && objOrId !== null;
|
248 | }, R.prop('id'));
|
249 | /**
|
250 | * Deep merge values that are objects but not arrays
|
251 | * based on https://github.com/ramda/ramda/pull/1088
|
252 | * @params {Object} l the 'left' side object to merge
|
253 | * @params {Object} r the 'right' side object to merge
|
254 | * @type {Immutable.Map<string, V>|__Cursor.Cursor|List<T>|Map<K, V>|*}
|
255 | * @returns {Object} The deep-merged object
|
256 | * @sig mergeDeep:: (<k, v>, <k, v>) -> <k, v>
|
257 | */
|
258 |
|
259 | var mergeDeep = R.mergeWith(function (l, r) {
|
260 | // If either (hopefully both) items are arrays or not both objects
|
261 | // accept the right value
|
262 | return (// If either is a function take the last
|
263 | R.is(Function, l) || R.is(Function, r) || // If either is an array take the last
|
264 | l && l.concat && Array.isArray(l) || r && r.concat && Array.isArray(r) || !(R.is(Object, l) && R.is(Object, r)) ? r : mergeDeep(l, r)
|
265 | ); // tail recursive
|
266 | });
|
267 | /**
|
268 | * mergeDeep any number of objects
|
269 | * @params {[Object]} objs Array of objects to reduce
|
270 | * @returns {Object} The deep-merged objects
|
271 | */
|
272 |
|
273 | var mergeDeepAll = R.reduce(mergeDeep, {});
|
274 | /**
|
275 | * Deep merge values with a custom function that are objects
|
276 | * based on https://github.com/ramda/ramda/pull/1088
|
277 | * @params {Function} fn The merge function left l, right r:: l -> r -> a
|
278 | * @params {Object} left the 'left' side object to merge
|
279 | * @params {Object} right the 'right' side object to morge
|
280 | * @returns {Object} The deep-merged objeck
|
281 | * @sig mergeDeep:: (<k, v>, <k, v>) -> <k, v>
|
282 | */
|
283 |
|
284 | var mergeDeepWith = R.curry(function (fn, left, right) {
|
285 | return R.mergeWith(function (l, r) {
|
286 | // If either (hopefully both) items are arrays or not both objects
|
287 | // accept the right value
|
288 | return l && l.concat && Array.isArray(l) || r && r.concat && Array.isArray(r) || !R.all(isObject)([l, r]) || R.any(R.is(Function))([l, r]) ? fn(l, r) : mergeDeepWith(fn, l, r); // tail recursive
|
289 | })(left, right);
|
290 | });
|
291 | /**
|
292 | * Merge Deep that concats arrays of matching keys
|
293 | * @params {Object} left the 'left' side object to merge
|
294 | * @params {Object} right the 'right' side object to morge
|
295 | * @returns {Object} The deep-merged object
|
296 | * @sig mergeDeep:: (<k, v>, <k, v>) -> <k, v>
|
297 | */
|
298 |
|
299 | var mergeDeepWithConcatArrays = R.curry(function (left, right) {
|
300 | return mergeDeepWith(function (l, r) {
|
301 | return R.cond([[R.all(R.allPass([R.identity, R.prop('concat'), Array.isArray])), R.apply(R.concat)], [R.complement(R.all)(isObject), R.last], [R.T, R.apply(mergeDeepWithConcatArrays)] // tail recursive
|
302 | ])([l, r]);
|
303 | })(left, right);
|
304 | });
|
305 | /**
|
306 | * Merge Deep and also apply the given function to array items with the same index
|
307 | * @params {Function} fn The merge function left l, right r, string k:: l -> r -> k -> a
|
308 | * @params {Object} left the 'left' side object to merge
|
309 | * @params {Object} right the 'right' side object to morge
|
310 | * @returns {Object} The deep-merged object
|
311 | * @sig mergeDeepWithRecurseArrayItems:: (<k, v>, <k, v>, k) -> <k, v>
|
312 | */
|
313 |
|
314 | var mergeDeepWithRecurseArrayItems = R.curry(function (fn, left, right) {
|
315 | return R.cond([// Arrays
|
316 | [R.all(R.allPass([R.identity, R.prop('concat'), Array.isArray])), function (_ref) {
|
317 | var _ref2 = _slicedToArray(_ref, 2),
|
318 | l = _ref2[0],
|
319 | r = _ref2[1];
|
320 |
|
321 | return R.zipWith(function (a, b) {
|
322 | return mergeDeepWithRecurseArrayItems(fn, a, b);
|
323 | }, l, r);
|
324 | }], // Primitives
|
325 | [R.complement(R.all)(isObject), function (_ref3) {
|
326 | var _ref4 = _slicedToArray(_ref3, 2),
|
327 | l = _ref4[0],
|
328 | r = _ref4[1];
|
329 |
|
330 | return fn(l, r);
|
331 | }], // Objects
|
332 | [R.T, function (_ref5) {
|
333 | var _ref6 = _slicedToArray(_ref5, 2),
|
334 | l = _ref6[0],
|
335 | r = _ref6[1];
|
336 |
|
337 | return R.mergeWith(mergeDeepWithRecurseArrayItems(fn), l, r);
|
338 | }]])([left, right]);
|
339 | });
|
340 | /**
|
341 | * Like mergeDeepWithRecurseArrayItems but merges array items with a function itemMatchBy that determines
|
342 | * if an item from each array of left and right represents the same objects. The right object's array
|
343 | * items are returned but any left object item matching by itemMatchBy is deep merged with the matching right item.
|
344 | * There is no merge function for primitives, r is always returned
|
345 | * @params {Function} fn The item matching function, Arrays deep items in left and right. Called with the
|
346 | * item and current key/index
|
347 | * are merged. For example
|
348 | * item => R.when(isObject, R.propOr(v, 'id'))(item)
|
349 | * would match on id if item is an object and has an id
|
350 | * @params {Object} left the 'left' side object to merge
|
351 | * @params {Object} right the 'right' side object to merge
|
352 | * @params {String} [key] Optional key or index of the parent object/array item
|
353 | * @returns {Object} The deep-merged object
|
354 | */
|
355 |
|
356 | var mergeDeepWithRecurseArrayItemsByRight = R.curry(function (itemMatchBy, left, right) {
|
357 | return _mergeDeepWithRecurseArrayItemsByRight(itemMatchBy, null, left, right, null);
|
358 | });
|
359 | /**
|
360 | * Like mergeDeepWithRecurseArrayItemsByRight but takes mergeObject to merge objects, rather than just taking the
|
361 | * right value. Primitives still resolve to the right value. the mergeObject function should handle internal array
|
362 | * merging by recursing on this function or similar
|
363 | * @params {Function} fn The item matching function, Arrays deep items in left and right. Called with the
|
364 | * item and current key/index
|
365 | * are merged. For example
|
366 | * item => R.when(isObject, R.propOr(v, 'id'))(item)
|
367 | * would match on id if item is an object and has an id
|
368 | * @params {Function} itemMatchBy Expects the left and right object that need to be merged
|
369 | * @params {Function} mergeObject Expects left and right when they are objects. mergeObject typically recurses
|
370 | * with mergeDeepWithRecurseArrayItemsByAndMergeObjectByRight on each item of left and right after doing something
|
371 | * special. This function was designed with the idea of being used in Apollo InMemory Cache Type Policy merge functions
|
372 | * to continue calling Apollowing merge function on objects, which in tern delegates back to this function
|
373 | * @params {Object} left the 'left' side object to merge
|
374 | * @params {Object} right the 'right' side object to merge
|
375 | * @params {String} [key] Optional key or index of the parent object/array item
|
376 | * @returns {Object} The deep-merged object
|
377 | */
|
378 |
|
379 | var mergeDeepWithRecurseArrayItemsByAndMergeObjectByRight = R.curry(function (itemMatchBy, mergeObject, left, right) {
|
380 | return _mergeDeepWithRecurseArrayItemsByRight(itemMatchBy, mergeObject, left, right, null);
|
381 | });
|
382 | var _mergeDeepWithRecurseArrayItemsByRight = function _mergeDeepWithRecurseArrayItemsByRight(itemMatchBy, mergeObject, left, right, key) {
|
383 | return R.cond([// Arrays
|
384 | [function (_ref7) {
|
385 | var _ref8 = _slicedToArray(_ref7, 2),
|
386 | l = _ref8[0],
|
387 | r = _ref8[1];
|
388 |
|
389 | return R.any(R.allPass([R.identity, R.prop('concat'), Array.isArray]))([l, r]);
|
390 | }, function (_ref9) {
|
391 | var _ref10 = _slicedToArray(_ref9, 2),
|
392 | l = _ref10[0],
|
393 | r = _ref10[1];
|
394 |
|
395 | // Null case, return the only array
|
396 | if (!l || !r) {
|
397 | return l || r;
|
398 | } // Create a lookup of l items
|
399 |
|
400 |
|
401 | var lItemsByValue = R.indexBy(function (li) {
|
402 | return itemMatchBy(li, key);
|
403 | }, l || []); // Map each item of r
|
404 |
|
405 | return R.addIndex(R.map)(function (rItem, i) {
|
406 | // If the lookup of the r item matches one of l items' itemMatchBy value,
|
407 | // recurse with both items. Else just return r
|
408 | var rItemValue = itemMatchBy(rItem, key);
|
409 | var hasMatchingLItem = R.has(rItemValue, lItemsByValue);
|
410 | return R.when(function () {
|
411 | return hasMatchingLItem;
|
412 | }, function () {
|
413 | // Pass the index as a key
|
414 | return _mergeDeepWithRecurseArrayItemsByRight(itemMatchBy, mergeObject, R.prop(rItemValue, lItemsByValue), rItem, i);
|
415 | })(rItem);
|
416 | }, r || []);
|
417 | }], // Primitives. If either is an object skip, it means 1 is null
|
418 | [R.none(isObject), function (_ref11) {
|
419 | var _ref12 = _slicedToArray(_ref11, 2),
|
420 | l = _ref12[0],
|
421 | r = _ref12[1];
|
422 |
|
423 | return r;
|
424 | }], // Objects and nulls
|
425 | [R.T, function (_ref13) {
|
426 | var _ref14 = _slicedToArray(_ref13, 2),
|
427 | l = _ref14[0],
|
428 | r = _ref14[1];
|
429 |
|
430 | return mergeObject ? mergeObject(l, r) : R.mergeWithKey(function (kk, ll, rr) {
|
431 | return _mergeDeepWithRecurseArrayItemsByRight(itemMatchBy, mergeObject, ll, rr, kk);
|
432 | }, l || {}, r || {});
|
433 | }]])([left, right]);
|
434 | };
|
435 | /**
|
436 | * mergeDeepWithRecurseArrayItems but passes obj as left and right so fn is called on every key
|
437 | * @params {Function} fn The merge function left l, right r, string k:: l -> r -> k -> a
|
438 | * @params {Object} left the 'left' side object to merge
|
439 | * @params {Object} right the 'right' side object to morge
|
440 | * @returns {Object} The deep-merged object
|
441 | * @sig mergeDeepWithRecurseArrayItems:: (<k, v>, <k, v>, k) -> <k, v>
|
442 | */
|
443 |
|
444 | var applyDeep = R.curry(function (fn, obj) {
|
445 | return mergeDeepWithRecurseArrayItems(fn, obj, obj);
|
446 | });
|
447 | /**
|
448 | * Merge Deep and also apply the given function to array items with the same index.
|
449 | * This adds another function that maps the object results to something else after the objects are recursed upon
|
450 | * @params {Function} fn The merge function left l, right r, string k:: l -> r -> k -> a
|
451 | * @params {Function} applyObj Function called with the current key and the result of each recursion that is an object.
|
452 | * @params {Object} left the 'left' side object to merge
|
453 | * @params {Object} right the 'right' side object to morge
|
454 | * @returns {Object} The deep-merged object
|
455 | * @sig mergeDeepWithRecurseArrayItems:: (<k, v>, <k, v>, k) -> <k, v>
|
456 | */
|
457 |
|
458 | var mergeDeepWithRecurseArrayItemsAndMapObjs = R.curry(function (fn, applyObj, left, right) {
|
459 | return _mergeDeepWithRecurseArrayItemsAndMapObjs(fn, applyObj, null, left, right);
|
460 | });
|
461 | /**
|
462 | * Same as mergeDeepWithRecurseArrayItemsAndMapObjs but sends the same left and right value so fn is called on every key
|
463 | * of ob * @params {Function} fn The merge function left l, right r, string k:: l -> r -> k -> a
|
464 | * @params {Function} applyObj Function called with the current key and the result of each recursion that is an object.
|
465 | * @params {Object} left the 'left' side object to merge
|
466 | * @params {Object} right the 'right' side object to morge
|
467 | * @returns {Object} The deep-merged object
|
468 | * @sig applyDeepAndMapObjs:: (<k, v>, <k, v>, k) -> <k, v>j
|
469 | */
|
470 |
|
471 | var applyDeepAndMapObjs = R.curry(function (fn, applyObj, obj) {
|
472 | return mergeDeepWithRecurseArrayItemsAndMapObjs(fn, applyObj, obj, obj);
|
473 | });
|
474 |
|
475 | var _mergeDeepWithRecurseArrayItemsAndMapObjs = R.curry(function (fn, applyObj, key, left, right) {
|
476 | return R.cond([// Arrays
|
477 | [R.all(Array.isArray), // Recurse on each array item. We pass the key without the index
|
478 | function (lr) {
|
479 | return R.apply(R.zipWith(function (l, r) {
|
480 | return R.compose( // For array items, take key and the result and call the applyObj func, but only if res is an Object
|
481 | function (v) {
|
482 | return R.when( // When it's an object and not an array call applyObj
|
483 | // typeof x === 'object' check because sometimes values that are objects are not returning true
|
484 | R.both(function (vv) {
|
485 | return _typeof(vv) === 'object';
|
486 | }, R.complement(R.is)(Array)), function (res) {
|
487 | return applyObj(key, res);
|
488 | })(v);
|
489 | }, function (_ref15) {
|
490 | var _ref16 = _slicedToArray(_ref15, 3),
|
491 | kk = _ref16[0],
|
492 | ll = _ref16[1],
|
493 | rr = _ref16[2];
|
494 |
|
495 | return _mergeDeepWithRecurseArrayItemsAndMapObjs(fn, applyObj, kk, ll, rr);
|
496 | })([key, l, r]);
|
497 | }))(lr);
|
498 | }], // Primitives: call the function with left and right as the first two args and key as the last
|
499 | [R.complement(R.all)(function (x) {
|
500 | return isObject(x);
|
501 | }), function (lr) {
|
502 | return fn.apply(void 0, _toConsumableArray(lr).concat([key]));
|
503 | }], // Always leave functions alone.
|
504 | [function (lr) {
|
505 | return R.all(R.is(Function), lr);
|
506 | }, function (_ref17) {
|
507 | var _ref18 = _slicedToArray(_ref17, 2),
|
508 | l = _ref18[0],
|
509 | _ = _ref18[1];
|
510 |
|
511 | return l;
|
512 | }], // Objects
|
513 | [R.T, function (lr) {
|
514 | return R.apply(R.mergeWithKey(function (k, l, r) {
|
515 | return R.compose( // Take key and the result and call the applyObj func, but only if res is an Object
|
516 | function (v) {
|
517 | return R.when( // When it's an object and not an array call applyObj
|
518 | // typeof x === 'object' check because sometimes values that are objects are not returning true
|
519 | R.both(function (x) {
|
520 | return _typeof(x) === 'object';
|
521 | }, R.complement(R.is)(Array)), function (res) {
|
522 | return applyObj(k, res);
|
523 | })(v);
|
524 | }, // First recurse on l and r
|
525 | function (_ref19) {
|
526 | var _ref20 = _slicedToArray(_ref19, 3),
|
527 | kk = _ref20[0],
|
528 | ll = _ref20[1],
|
529 | rr = _ref20[2];
|
530 |
|
531 | return R.apply(_mergeDeepWithRecurseArrayItemsAndMapObjs(fn, applyObj), [kk, ll, rr]);
|
532 | })([k, l, r]);
|
533 | }), lr);
|
534 | }]])([left, right]);
|
535 | });
|
536 | /**
|
537 | * http://stackoverflow.com/questions/40011725/point-free-style-capitalize-function-with-ramda
|
538 | * Capitalize the first letter
|
539 | * @param {String} str The string to capitalize
|
540 | * @returns {String} The capitalized string
|
541 | * @sig capitalize:: String -> String
|
542 | */
|
543 |
|
544 |
|
545 | var capitalize = function capitalize(str) {
|
546 | return R.compose(R.join(''), R.juxt([R.compose(R.toUpper, R.head), R.tail]))(str);
|
547 | };
|
548 | /**
|
549 | * http://stackoverflow.com/questions/40011725/point-free-style-capitalize-function-with-ramda
|
550 | * Lowercase the first letter
|
551 | * @param {String} str The string to lowercase
|
552 | * @returns {String} The capitalized string
|
553 | * @sig capitalize:: String -> String
|
554 | */
|
555 |
|
556 | var lowercase = function lowercase(str) {
|
557 | return R.compose(R.join(''), R.juxt([R.compose(R.toLower, R.head), R.tail]))(str);
|
558 | };
|
559 | /**
|
560 | * From https://github.com/substack/camelize/blob/master/index.js
|
561 | * @param {String} str The string to camelCase
|
562 | * @returns {String} The camel-cased string
|
563 | */
|
564 |
|
565 | var camelCase = function camelCase(str) {
|
566 | return R.toLower(str).replace(/[_.-](\w|$)/g, function (_, x) {
|
567 | return x.toUpperCase();
|
568 | });
|
569 | };
|
570 | /**
|
571 | * Merge a list of objects using the given concat function
|
572 | * [{k: v}] → {k: v}
|
573 | * @returns {Object} The merged object
|
574 | * @sig mergeAllWithKey:: (String → a → a → a) → [{a}] → {a}
|
575 | */
|
576 |
|
577 | var mergeAllWithKey = R.curry(function (fn, _ref21) {
|
578 | var _ref22 = _toArray(_ref21),
|
579 | head = _ref22[0],
|
580 | rest = _ref22.slice(1);
|
581 |
|
582 | return R.mergeWithKey( // call mergeWithKey on two objects at a time
|
583 | fn, head || {}, // first object is always the head
|
584 | R.ifElse( // second object is the merged object of the recursion
|
585 | R.isEmpty, // if no rest
|
586 | function () {
|
587 | return R.empty({});
|
588 | }, // end case empty object
|
589 | mergeAllWithKey(fn) // else recurse with the rest
|
590 | )(rest));
|
591 | });
|
592 | /**
|
593 | * Get a required path or return a helpful Error if it fails
|
594 | * @param {String} path A lensPath, e.g. ['a', 'b'] or ['a', 2, 'b']
|
595 | * @param {Object} obj The object to inspect
|
596 | * @returns {Result} Result the resolved value or an Error
|
597 | * @sig reqPath:: String -> {k: v} → Result
|
598 | */
|
599 |
|
600 | var reqPath = R.curry(function (path, obj) {
|
601 | return R.compose(R.ifElse( // If path doesn't resolve
|
602 | function (maybe) {
|
603 | return maybe.isNothing;
|
604 | }, // Create a useful Error message
|
605 | function () {
|
606 | return Result.Error({
|
607 | resolved: R.reduceWhile( // Stop if the accumulated segments can't be resolved
|
608 | function (segments, segment) {
|
609 | return R.not(R.isNil(R.path(R.concat(segments, [segment]), obj)));
|
610 | }, // Accumulate segments
|
611 | function (segments, segment) {
|
612 | return R.concat(segments, [segment]);
|
613 | }, [], path),
|
614 | path: path
|
615 | });
|
616 | }, // Return the resolved value
|
617 | function (res) {
|
618 | return Result.Ok(res.value);
|
619 | }), // Try to resolve the value using the path and obj, returning Maybe
|
620 | Rm.path(path))(obj);
|
621 | });
|
622 | /**
|
623 | * Expects a prop path and returns a function expecting props,
|
624 | * which resolves the prop indicated by the string. Returns Result.Error if there is not match
|
625 | * @param {String} str dot-separated prop path
|
626 | * @param {Object} props Object to resolve the path in
|
627 | * @return {Result} Result.Ok with the resolved value or Result.Error if the path doesn't exist or the
|
628 | * value is null
|
629 | */
|
630 |
|
631 | var reqStrPath = R.curry(function (str, props) {
|
632 | return reqPath(R.split('.', str), props);
|
633 | });
|
634 | /**
|
635 | * Expects a prop path and returns a function expecting props,
|
636 | * which resolves the prop indicated by the string. If not match is found it returns undefined
|
637 | * @param {String} str dot-separated prop path
|
638 | * @param {Object} props Object to resolve the path in
|
639 | * @return {Object} The resolved object or undefined
|
640 | */
|
641 |
|
642 | var strPath = R.curry(function (str, props) {
|
643 | return R.view(R.lensPath(R.split('.', str)), props);
|
644 | });
|
645 | /**
|
646 | * Like strPath but defaults the given value
|
647 | * @param {Object} defaultValue. Default value if value is null undefined.
|
648 | * @param {String} str dot-separated prop path
|
649 | * @param {Object} props Object to resolve the path in
|
650 | * @return {function(*=)}
|
651 | */
|
652 |
|
653 | var strPathOr = R.curry(function (defaultValue, str, props) {
|
654 | var result = R.view(R.lensPath(R.split('.', str)), props);
|
655 | return R.when(R.isNil, R.always(defaultValue))(result);
|
656 | });
|
657 | var strPathOrNullOk = R.curry(function (defaultValue, str, props) {
|
658 | var segments = R.split('.', str);
|
659 | var result = R.view(R.lensPath(R.init(segments)), props);
|
660 | return R.ifElse(R.isNil, R.always(defaultValue), function (r) {
|
661 | try {
|
662 | return R.when(function (v) {
|
663 | return typeof v === 'undefined';
|
664 | }, function () {
|
665 | return defaultValue;
|
666 | })(R.prop(R.last(segments), r));
|
667 | } catch (_unused) {
|
668 | return defaultValue;
|
669 | }
|
670 | })(result);
|
671 | });
|
672 | /**
|
673 | * Returns true if the given string path is non-null
|
674 | * @param {String} str dot-separated prop path
|
675 | * @param {Object} props Object to resolve the path in
|
676 | * @returns {Boolean} true
|
677 | */
|
678 |
|
679 | var hasStrPath = R.curry(function (str, props) {
|
680 | return R.complement(R.isNil)(R.view(R.lensPath(R.split('.', str)), props));
|
681 | });
|
682 | /**
|
683 | * Uses reqPath to resolve the path of an object and compares it to val
|
684 | * @param {String} path A lensPath, e.g. ['a', 'b'] or ['a', 2, 'b']
|
685 | * @param {*} val The val to do an equality check on
|
686 | * @param {Object} obj The object to inspect
|
687 | * @returns {Result} Result the resolved value or an Error
|
688 | * @sig reqPath:: String -> {k: v} → Result
|
689 | */
|
690 |
|
691 | var reqPathPropEq = R.curry(function (path, val, obj) {
|
692 | return (// If the reqPath is valid map it to a comparison with val
|
693 | reqPath(path, obj).map(R.equals(val))
|
694 | );
|
695 | });
|
696 | /**
|
697 | * From the cookbook: https://github.com/ramda/ramda/wiki/Cookbook#map-keys-of-an-object
|
698 | * Maps keys according to the given function
|
699 | * @returns {Object} The mapped keys of the object
|
700 | * @sig mapKeys :: (String -> String) -> Object -> Object
|
701 | */
|
702 |
|
703 | var mapKeys = R.curry(function (fn, obj) {
|
704 | return R.compose(R.fromPairs, function (pairs) {
|
705 | return R.map( // Apply fn to index 0 of pair
|
706 | function (pair) {
|
707 | return R.adjust(0, fn, pair);
|
708 | }, pairs);
|
709 | }, R.toPairs)(obj);
|
710 | });
|
711 | /**
|
712 | * Uses a lens to map keys that are embedded in a data structure
|
713 | * The lens must indicate an object whose keys shall be mapped
|
714 | * @returns {Object} Object with the keys indicated by the given lens mapped
|
715 | * @sig mapKeysForLens :: Lens -> ((String -> String) -> Object -> Object
|
716 | */
|
717 |
|
718 | var mapKeysForLens = R.curry(function (lens, fn, obj) {
|
719 | return (// Sets the lens-focused objects to a new object with keys mapped according to the function
|
720 | R.set(lens, mapKeys(fn, R.view(lens, obj)), obj)
|
721 | );
|
722 | });
|
723 | /**
|
724 | * Converts default to desired name. Used for requiring defaults
|
725 | * @param {String} keyName The desired rename of 'default'
|
726 | * @param {Object} module A required module with a default key
|
727 | * @returns {Object} The import module with key default changed to keyName
|
728 | * @sig mapDefault :: String -> <k,v> -> <k,v>
|
729 | */
|
730 |
|
731 | var mapDefault = function mapDefault(keyName, module) {
|
732 | return mapKeys(function (key) {
|
733 | return key === 'default' ? keyName : key;
|
734 | }, module);
|
735 | };
|
736 | /**
|
737 | * Converts default to desired name and prefixes others.
|
738 | * Used for requiring defaults and renaming others
|
739 | * @param {String} defaultName The desired rename of 'default'
|
740 | * @param {String} prefix The desired prefix for others. Camel Case maintained
|
741 | * @param {Object} module A required module with a default key
|
742 | * @returns {Object} The import module with key default changed to keyName
|
743 | * @sig mapDefault :: String -> <k,v> -> <k,v>
|
744 | */
|
745 |
|
746 | var mapDefaultAndPrefixOthers = function mapDefaultAndPrefixOthers(defaultName, prefix, module) {
|
747 | return mapKeys(function (key) {
|
748 | return key === 'default' ? defaultName : "".concat(prefix).concat(capitalize(key));
|
749 | }, module);
|
750 | };
|
751 | /**
|
752 | * Maps an object with a function that returns pairs and create and object therefrom
|
753 | * Like R.mapObjIndexed, the function's first argument is the value of each item, and the seconds is the key if
|
754 | * iterating over objects
|
755 | * @params {Functor} f The mapping function
|
756 | * @params {Container} container Anything that can be mapped
|
757 | * @returns {Object} The mapped pairs made into key values
|
758 | * @sig mapKeysAndValues :: Functor F = (a -> [b,c]) -> F -> <k,v>
|
759 | */
|
760 |
|
761 | var mapKeysAndValues = R.curry(function (f, container) {
|
762 | return R.fromPairs(mapObjToValues(f, container));
|
763 | });
|
764 | /**
|
765 | * https://github.com/ramda/ramda/wiki/Cookbook
|
766 | * Filter objects with values and keys. Null objs return as null
|
767 | * @param {Function} pred (value, key) => True|False
|
768 | * @param {Object} obj The object to filter
|
769 | * @returns {Object} The filtered object
|
770 | * @sig filterWithKeys:: (v -> k -> True|False) -> <k,v> -> <k,v>
|
771 | */
|
772 |
|
773 | var filterWithKeys = R.curry(function (pred, obj) {
|
774 | if (!obj) {
|
775 | return obj;
|
776 | }
|
777 |
|
778 | return R.compose(R.fromPairs, R.filter(function (pair) {
|
779 | return R.apply(pred, R.reverse(pair));
|
780 | }), R.toPairs)(obj);
|
781 | });
|
782 | /**
|
783 | * Transforms the keys of the given object with the given func
|
784 | * @param {Function} func The mapping function that expects the key
|
785 | * @param {Object} The object to map
|
786 | * @returns {Object} The object with transformed keys and the original values
|
787 | */
|
788 |
|
789 | var transformKeys = R.curry(function (func, obj) {
|
790 | return R.compose(R.fromPairs, R.map(function (_ref23) {
|
791 | var _ref24 = _slicedToArray(_ref23, 2),
|
792 | key = _ref24[0],
|
793 | value = _ref24[1];
|
794 |
|
795 | return [func(key), value];
|
796 | }), R.toPairs)(obj);
|
797 | });
|
798 | /**
|
799 | * Renames the key of the object specified by the lens
|
800 | * @param {Function} lens A ramda lens that points to the object containing the key, not the key itself.
|
801 | * Use R.lensPath([]) to operate directly on obj
|
802 | * @param {String} from Key to rename
|
803 | * @param {String} to New name for the key
|
804 | * @param {Object} obj Object to traverse with the lens
|
805 | */
|
806 |
|
807 | var renameKey = R.curry(function (lens, from, to, obj) {
|
808 | return R.over(lens, function (target) {
|
809 | return mapKeys(R.when(R.equals(from), R.always(to)), target);
|
810 | }, obj);
|
811 | });
|
812 | /**
|
813 | * Duplicates the key of the object specified by the lens and key, to the given list of keys or single key.
|
814 | * A duplicate of the value at key will be added at each of the toKeys using R.clone
|
815 | * @param {Function} lens A ramda lens that points to the object containing the key, not the key itself
|
816 | * @param {String} key Key to duplicate the value of
|
817 | * @param {String|[String]} toKeys Array of new keys to make. New keys overwrite existing keys
|
818 | * @param {Object} obj Object to traverse with the lens
|
819 | */
|
820 |
|
821 | var duplicateKey = R.curry(function (lens, key, toKeys, obj) {
|
822 | return R.over(lens, // convert the target of the lens to a merge of the target with copies of target[key]
|
823 | function (target) {
|
824 | return R.merge(target, R.fromPairs(R.map(function (toKey) {
|
825 | return [toKey, R.clone(target[key])];
|
826 | }, toArrayIfNot(toKeys))));
|
827 | }, // take the lens of this obj
|
828 | obj);
|
829 | });
|
830 | /**
|
831 | * Converts a scalar value (!Array.isArray) to array an array
|
832 | * @param {*|[*]} arrayOrScalar An array or scalar
|
833 | * @returns {[*]} The scalar as an array or the untouched array
|
834 | */
|
835 |
|
836 | var toArrayIfNot = function toArrayIfNot(arrayOrScalar) {
|
837 | return R.unless(Array.isArray, Array.of)(arrayOrScalar);
|
838 | };
|
839 | /**
|
840 | * Like duplicateKey but removes the original key
|
841 | * @param {Function} lens A ramda lens that points to the object containing the key, not the key itself
|
842 | * @param {String} key Key to duplicate the value of
|
843 | * @param [{String}] toKeys Array of new keys to make. New keys overwrite existing keys
|
844 | * @param {Object} obj Object to traverse with the lens
|
845 | */
|
846 |
|
847 | var moveToKeys = R.curry(function (lens, key, toKeys, obj) {
|
848 | return R.over(lens, // convert the target of the lens to a merge of the target with copies of target[key]
|
849 | // and with target[key] itself removed
|
850 | function (target) {
|
851 | return R.merge(R.omit([key], target), R.fromPairs(R.map(function (toKey) {
|
852 | return [toKey, R.clone(target[key])];
|
853 | }, toKeys)));
|
854 | }, // take the lens of this obj
|
855 | obj);
|
856 | });
|
857 | /**
|
858 | * Like R.find but expects only one match and works on both arrays and objects
|
859 | * Note this still iterates through the whole list or object, so this should be rewritten to quit when one is found
|
860 | * @param {Function} predicate
|
861 | * @param {Array|Object} obj Container that should only match once with predicate
|
862 | * @returns {Result} Result.Error if no matches or more than one, otherwise Result.Ok with the single matching item in an array/object
|
863 | */
|
864 |
|
865 | var findOne = R.curry(function (predicate, obj) {
|
866 | return R.ifElse( // If path doesn't resolve
|
867 | function (items) {
|
868 | return R.equals(R.length(R.keys(items)), 1);
|
869 | }, // Return the resolved single key/value object
|
870 | function (items) {
|
871 | return Result.Ok(items);
|
872 | }, // Create a useful Error message
|
873 | function (items) {
|
874 | return Result.Error({
|
875 | all: obj,
|
876 | matching: items
|
877 | });
|
878 | })(R.filter(predicate, obj));
|
879 | });
|
880 | /**
|
881 | * Version of find one that accepts all items of the given Container
|
882 | * @param {Array|Object} obj Container
|
883 | * @returns {Result} Result.Error if no items or more than one, otherwise Result.Ok with the single item in an array/object
|
884 | */
|
885 |
|
886 | var onlyOne = findOne(R.T);
|
887 | /**
|
888 | * Like onlyOne but extracts the value
|
889 | * @param {Array|Object|Result} obj Container that should have one value to extract. This currently expects
|
890 | * and array or object or Result, but it could be expanded to take Result, Maybe, or any other container where
|
891 | * the value can be extracted. Types like Tasks and Streams can't extract, I suppose
|
892 | * @returns {Result} Result.Error if no items or more than one, otherwise Result.Ok with the single value
|
893 | */
|
894 |
|
895 | var onlyOneValue = R.compose( // Use R.map to operate on the value of Result without extracting it
|
896 | R.map(R.head), R.map(R.values), findOne(R.T));
|
897 | /**
|
898 | * Curryable Maps container values to the key and values of an object, applying f to each to make the value
|
899 | * @param {Function} f Transforms each item to a value
|
900 | * @param {Array} list Container to map to an object.
|
901 | * @sig mapToObjValue:: Functor a => (b -> c) -> <b, c>
|
902 | */
|
903 |
|
904 | var mapToObjValue = R.curry(function (f, obj) {
|
905 | return R.compose(R.fromPairs, R.map(function (v) {
|
906 | return [v, f(v)];
|
907 | }))(obj);
|
908 | });
|
909 | /**
|
910 | * Finds an item that matches all the given props in params
|
911 | * @param {Object} params object key values to match
|
912 | * @param {Object|Array} items Object or Array that can produce values to search
|
913 | * @returns {Result} An Result.Ok containing the value or an Result.Error if no value is found
|
914 | */
|
915 |
|
916 | var findOneValueByParams = function findOneValueByParams(params, items) {
|
917 | return findOne( // Compare all the eqProps against each item
|
918 | R.allPass( // Create a eqProps for each prop of params
|
919 | R.map(function (prop) {
|
920 | return R.eqProps(prop, params);
|
921 | }, R.keys(params))), R.values(items)).map(R.head);
|
922 | };
|
923 | /**
|
924 | * Returns the items matching all param key values
|
925 | * @param {Object} params Key values to match to items
|
926 | * @param {Object|Array} items Object with values of objects or array of objects that can produce values to search
|
927 | * @returns {[Object]} items that pass
|
928 | */
|
929 |
|
930 | var findByParams = function findByParams(params, items) {
|
931 | return R.filter( // Compare all the eqProps against each item
|
932 | R.allPass( // Create a eqProps for each prop of params
|
933 | R.map(function (prop) {
|
934 | return R.eqProps(prop, params);
|
935 | }, R.keys(params))), items);
|
936 | };
|
937 | /**
|
938 | * Returns the first mapped item that is not null
|
939 | * @param {Function} f The mapping function
|
940 | * @param {[*]} items The items
|
941 | * @returns {*} The first mapped item value that is not nil
|
942 | */
|
943 |
|
944 | var findMapped = function findMapped(f, items) {
|
945 | return R.reduceWhile(R.isNil, function (_, i) {
|
946 | return f(i);
|
947 | }, null, items);
|
948 | };
|
949 | /**
|
950 | * Converts the given value to an always function (that ignores all arguments) unless already a function
|
951 | * @param {Function} maybeFunc A function or something else
|
952 | * @return {Function} a function that always returns the non funcion value of maybeFunc, or maybeFunc
|
953 | * itself if maybeFunc is a functon
|
954 | */
|
955 |
|
956 | var alwaysFunc = function alwaysFunc(maybeFunc) {
|
957 | return R.unless(R.is(Function), R.always)(maybeFunc);
|
958 | };
|
959 | /**
|
960 | * Map the object with a function accepting a key, value, and the obj but return just the mapped values,
|
961 | * not the object
|
962 | * @param {Function} f Expects value, key, and obj
|
963 | * @param {Object} obj The object to map
|
964 | * @return {[Object]} Mapped values
|
965 | */
|
966 |
|
967 | var mapObjToValues = R.curry(function (f, obj) {
|
968 | return R.values(R.mapObjIndexed(f, obj));
|
969 | });
|
970 | /**
|
971 | * Filter the given object and return the values, discarding the keys
|
972 | * @param {Function} f Receives each value and key
|
973 | * @param {Object} obj The object to filter
|
974 | * @return {Object} The filtered object values
|
975 | */
|
976 |
|
977 | var filterObjToValues = R.curry(function (f, obj) {
|
978 | return R.values(filterWithKeys(f, obj));
|
979 | });
|
980 | /**
|
981 | * Like mapObjToValues but chains the values when an array is returned for each mapping
|
982 | * @param {Function} f Expects key, value, and obj
|
983 | * @param {Object} obj The object to chain
|
984 | * @return {[Object]} Mapped flattened values
|
985 | */
|
986 |
|
987 | var chainObjToValues = R.curry(function (f, obj) {
|
988 | return R.chain(R.identity, mapObjToValues(f, obj));
|
989 | });
|
990 | /**
|
991 | *
|
992 | * This is a deep fromPairs. If it encounters a two element array it assumes it's a pair if the first
|
993 | * element is a string. If an array is not a pair it is iterated over and each element is recursed upon.
|
994 | * The 2nd element of each pair is also recursed upon. The end case for recursion is that an element is not an array.
|
995 | *
|
996 | * This method doesn't currently expect objects but could be easily modified to handle them
|
997 | * @param {[*]} deepPairs An array of deep pairs, with possibly other arrays at the top or lower levels
|
998 | * that aren't pairs but might contain them
|
999 | * @returns {Array|Object} All arrays of pairs are converted to objects. Arrays of non pairs are left as arrays
|
1000 | */
|
1001 |
|
1002 | var fromPairsDeep = function fromPairsDeep(deepPairs) {
|
1003 | return R.cond([// It's array of pairs or some other array
|
1004 | [Array.isArray, function (list) {
|
1005 | return R.ifElse( // Is the first item a two element array whose first item is a string?
|
1006 | function (_ref25) {
|
1007 | var _ref26 = _slicedToArray(_ref25, 1),
|
1008 | first = _ref26[0];
|
1009 |
|
1010 | return R.allPass([Array.isArray, function (x) {
|
1011 | return R.compose(R.equals(2), R.length)(x);
|
1012 | }, function (x) {
|
1013 | return R.compose(R.is(String), R.head)(x);
|
1014 | }])(first);
|
1015 | }, // Yes, return an object whose keys are the first element and values are the result of recursing on the second
|
1016 | function (l) {
|
1017 | return R.compose(R.fromPairs, R.map(function (_ref27) {
|
1018 | var _ref28 = _slicedToArray(_ref27, 2),
|
1019 | k = _ref28[0],
|
1020 | v = _ref28[1];
|
1021 |
|
1022 | return [k, fromPairsDeep(v)];
|
1023 | }))(l);
|
1024 | }, // No, recurse on each array item
|
1025 | function (l) {
|
1026 | return R.map(function (v) {
|
1027 | return fromPairsDeep(v);
|
1028 | }, l);
|
1029 | })(list);
|
1030 | }], // End case, return the given value unadulterated
|
1031 | [R.T, R.identity]])(deepPairs);
|
1032 | };
|
1033 | /**
|
1034 | * At the given depth, object and array values are converted to the replacementString.
|
1035 | * @param {Number} n Depth to replace at.
|
1036 | * Depth 3 converts {a: {b: {c: 1}}} to {a: {b: {c: '...'}}}
|
1037 | * Depth 2 converts {a: {b: {c: 1}}} to {a: {b: '...'}}
|
1038 | * Depth 1 converts {a: {b: {c: 1}}} to {a: '...'}
|
1039 | * Depth 0 converts {a: {b: {c: 1}}} to '...'
|
1040 | * @param {String|Function} replaceStringOrFunc String such as '...' or a unary function that replaces the value
|
1041 | * e.g. R.when(isObject, R.length(R.keys)) will count objects and arrays but leave primitives alone
|
1042 | * @param {Object} obj Object to process
|
1043 | * @returns {Object} with the above transformation. Use replaceValuesAtDepthAndStringify to get a string
|
1044 | */
|
1045 |
|
1046 | function replaceValuesAtDepth(n, replaceStringOrFunc, obj) {
|
1047 | return R.ifElse( // If we are above level 0 and we have an object
|
1048 | R.both(R.always(R.lt(0, n)), isObject), // Then recurse on each object or array value
|
1049 | function (o) {
|
1050 | return R.map(function (oo) {
|
1051 | return replaceValuesAtDepth(n - 1, replaceStringOrFunc, oo);
|
1052 | }, o);
|
1053 | }, // If at level 0 replace the value. If not an object or not at level 0, leave it alone
|
1054 | function (o) {
|
1055 | return R.when(R.always(R.equals(0, n)), alwaysFunc(replaceStringOrFunc))(o);
|
1056 | })(obj);
|
1057 | }
|
1058 | /** *
|
1059 | * replaceValuesAtDepth but stringifies result
|
1060 | * @param {Number} n Depth to replace at.
|
1061 | * Depth 3 converts {a: {b: {c: 1}}} to {a: {b: {c: '...'}}}
|
1062 | * Depth 2 converts {a: {b: {c: 1}}} to {a: {b: '...'}}
|
1063 | * Depth 1 converts {a: {b: {c: 1}}} to {a: '...'}
|
1064 | * Depth 0 converts {a: {b: {c: 1}}} to '...'
|
1065 | * @param {String|Function} replaceString String such as '...' or a unary function that replaces the value
|
1066 | * e.g. R.when(isObject, R.length(R.keys)) will count objects and arrays but leave primitives alone
|
1067 | * @param {Object} obj Object to process
|
1068 | * @returns {String} after the above replacement
|
1069 | */
|
1070 |
|
1071 | var replaceValuesAtDepthAndStringify = function replaceValuesAtDepthAndStringify(n, replaceString, obj) {
|
1072 | return JSON.stringify(replaceValuesAtDepth(n, replaceString, obj));
|
1073 | };
|
1074 | /**
|
1075 | * Convenient method to count objects and lists at the given depth but leave primitives alone
|
1076 | * @param {Number} n Depth to replace at.
|
1077 | * @param {Object} obj Object to process
|
1078 | * @returns {Object} after the above replacement
|
1079 | */
|
1080 |
|
1081 | var replaceValuesWithCountAtDepth = function replaceValuesWithCountAtDepth(n, obj) {
|
1082 | return replaceValuesAtDepth(n, R.when(isObject, function (o) {
|
1083 | return R.compose( // Show arrays and objs different
|
1084 | R.ifElse(R.always(Array.isArray(o)), function (c) {
|
1085 | return "[...".concat(c, "]");
|
1086 | }, function (c) {
|
1087 | return "{...".concat(c, "}");
|
1088 | }), R.length, R.keys)(o);
|
1089 | }), obj);
|
1090 | };
|
1091 | /**
|
1092 | * Convenient method to count objects and lists at the given depth but leave primitives alone and stringify result
|
1093 | * @param {Number} n Depth to replace at.
|
1094 | * @param {Object} obj Object to process
|
1095 | * @returns {String} after the above replacement
|
1096 | */
|
1097 |
|
1098 | var replaceValuesWithCountAtDepthAndStringify = function replaceValuesWithCountAtDepthAndStringify(n, obj) {
|
1099 | return JSON.stringify(replaceValuesWithCountAtDepth(n, obj));
|
1100 | };
|
1101 | /**
|
1102 | * Flattens an objects so deep keys and array indices become concatinated strings
|
1103 | * E.g. {a: {b: [1, 3]}} => {'a.b.0': 1, 'a.b.1': 2}
|
1104 | * @param {Object} obj The object to flattened
|
1105 | * @returns {Object} The 1-D version of the object
|
1106 | */
|
1107 |
|
1108 | var flattenObj = function flattenObj(obj) {
|
1109 | return R.fromPairs(_flattenObj({}, obj));
|
1110 | };
|
1111 | /**
|
1112 | * Flatten objs until the predicate returns false. This is called recursively on each object and array
|
1113 | * @param {Function} predicate Expects object, returns true when we should stop flatting on the current object
|
1114 | * @param {Object} obj The object to flatten
|
1115 | * @return {Object} The flattened object
|
1116 | */
|
1117 |
|
1118 | var flattenObjUntil = function flattenObjUntil(predicate, obj) {
|
1119 | return R.fromPairs(_flattenObj({
|
1120 | predicate: predicate
|
1121 | }, obj));
|
1122 | };
|
1123 |
|
1124 | var _flattenObj = function _flattenObj(config, obj) {
|
1125 | var keys = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
1126 | var predicate = R.propOr(null, 'predicate', config);
|
1127 | return R.ifElse( // If we have an object
|
1128 | function (o) {
|
1129 | return R.both(isObject, function (oo) {
|
1130 | return R.when(function () {
|
1131 | return predicate;
|
1132 | }, function (ooo) {
|
1133 | return R.complement(predicate)(ooo);
|
1134 | })(oo);
|
1135 | })(o);
|
1136 | }, // Then recurse on each object or array value
|
1137 | function (o) {
|
1138 | return chainObjToValues(function (oo, k) {
|
1139 | return _flattenObj(config, oo, R.concat(keys, [k]));
|
1140 | }, o);
|
1141 | }, // If not an object return flat pair
|
1142 | function (o) {
|
1143 | return [[R.join('.', keys), o]];
|
1144 | })(obj);
|
1145 | };
|
1146 | /**
|
1147 | * Converts a key string like 'foo.bar.0.wopper' to ['foo', 'bar', 0, 'wopper']
|
1148 | * @param {String} keyString The dot-separated key string
|
1149 | * @returns {[String]} The lens array containing string or integers
|
1150 | */
|
1151 |
|
1152 |
|
1153 | var keyStringToLensPath = function keyStringToLensPath(keyString) {
|
1154 | return R.map(R.when(R.compose(R.complement(R.equals)(NaN), parseInt), parseInt), R.split('.', keyString));
|
1155 | };
|
1156 | /**
|
1157 | * Undoes the work of flattenObj. Does not allow number keys to become array indices
|
1158 | * @param {Object} obj 1-D object in the form returned by flattenObj
|
1159 | * @returns {Object} The original
|
1160 | */
|
1161 |
|
1162 | var unflattenObjNoArrays = function unflattenObjNoArrays(obj) {
|
1163 | return _unflattenObj({
|
1164 | allowArrays: false
|
1165 | }, obj);
|
1166 | };
|
1167 | /**
|
1168 | * Undoes the work of flattenObj
|
1169 | * @param {Object} obj 1-D object in the form returned by flattenObj
|
1170 | * @returns {Object} The original
|
1171 | */
|
1172 |
|
1173 | var unflattenObj = function unflattenObj(obj) {
|
1174 | return _unflattenObj({
|
1175 | allowArrays: true
|
1176 | }, obj);
|
1177 | };
|
1178 | var _unflattenObj = function _unflattenObj(config, obj) {
|
1179 | return R.compose(R.reduce(function (accum, _ref29) {
|
1180 | var _ref30 = _slicedToArray(_ref29, 2),
|
1181 | keyString = _ref30[0],
|
1182 | value = _ref30[1];
|
1183 |
|
1184 | // Don't allow indices if allowArrays is false
|
1185 | var itemKeyPath = R.map(function (key) {
|
1186 | return R.when(function () {
|
1187 | return R.not(R.prop('allowArrays', config));
|
1188 | }, function (k) {
|
1189 | return k.toString();
|
1190 | })(key);
|
1191 | }, keyStringToLensPath(keyString)); // Current item lens
|
1192 |
|
1193 | var itemLensPath = R.lensPath(itemKeyPath); // All but the last segment gives us the item container len
|
1194 |
|
1195 | var constainerKeyPath = R.init(itemKeyPath);
|
1196 | var container = R.unless( // If the path has any length (not []) and the value is set, don't do anything
|
1197 | R.both(R.always(R.length(constainerKeyPath)), R.view(R.lensPath(constainerKeyPath))), // Else we are at the top level, so use the existing accum or create a [] or {}
|
1198 | // depending on if our item key is a number or not
|
1199 | function (x) {
|
1200 | return R.defaultTo(R.ifElse(function (v) {
|
1201 | return R.both(function () {
|
1202 | return R.prop('allowArrays', config);
|
1203 | }, R.is(Number))(v);
|
1204 | }, R.always([]), R.always({}))(R.head(itemKeyPath)))(x);
|
1205 | })(accum); // Finally set the container at the itemLensPath
|
1206 |
|
1207 | return R.set(itemLensPath, value, container);
|
1208 | }, // null initial value
|
1209 | null), R.toPairs)(obj);
|
1210 | };
|
1211 | /**
|
1212 | * Does something to every object
|
1213 | * @param {Function} func Called on each object that is the child of another object. Called with the key that
|
1214 | * points at it from the parent object and the object itself
|
1215 | * @param {Object} obj The object to process
|
1216 | */
|
1217 |
|
1218 | var overDeep = R.curry(function (func, obj) {
|
1219 | return mergeDeepWithRecurseArrayItemsAndMapObjs( // We are using a mergeDeepWithRecurseArrayItemsAndMapObjs but we only need the second function
|
1220 | function (l, r, k) {
|
1221 | return l;
|
1222 | }, func, // Use obj twice so that all keys match and get called with the merge function
|
1223 | obj, obj);
|
1224 | });
|
1225 | /**
|
1226 | * Omit the given keys anywhere in a data structure. Objects and arrays are recursed and omit_deep is called
|
1227 | * on each dictionary that hasn't been removed by omit_deep at a higher level
|
1228 | */
|
1229 |
|
1230 | var omitDeep = R.curry(function (omit_keys, obj) {
|
1231 | return omitDeepBy(function (k, v) {
|
1232 | return R.includes(k, omit_keys);
|
1233 | }, obj);
|
1234 | });
|
1235 | /**
|
1236 | * Omit by the given function that is called with key and value. You can ignore the value if you only want to test the key
|
1237 | * Objects and arrays are recursed and omit_deep is called
|
1238 | * on each dictionary that hasn't been removed by omit_deep at a higher level
|
1239 | * @param {Function} f Binary function accepting each key, value. Return non-nil to omit and false or nil to keep
|
1240 | */
|
1241 |
|
1242 | var omitDeepBy = R.curry(function (f, obj) {
|
1243 | return R.compose(function (o) {
|
1244 | return applyDeepAndMapObjs( // If k is in omit_keys return {} to force the applyObj function to call. Otherwise take l since l and r are always the same
|
1245 | // l and r are always the same value
|
1246 | function (l, r, kk) {
|
1247 | return R.ifElse( // Reject any function return value that isn't null or false
|
1248 | function (k) {
|
1249 | return R.anyPass([R.isNil, R.equals(false)])(f(k, l));
|
1250 | }, R.always(l), function () {
|
1251 | return {};
|
1252 | })(kk);
|
1253 | }, // Called as the result of each recursion. Removes the keys at any level except the topmost level
|
1254 | function (key, result) {
|
1255 | return filterWithKeys(function (v, k) {
|
1256 | return R.anyPass([R.isNil, R.equals(false)])(f(k, v));
|
1257 | }, result);
|
1258 | }, o);
|
1259 | }, // Omit at the top level. We have to do this because applyObj of applyDeepAndMapObjs only gets called starting
|
1260 | // on the object of each key
|
1261 | // Reject any function return value that isn't null or false
|
1262 | function (o) {
|
1263 | return filterWithKeys(function (v, k) {
|
1264 | return R.anyPass([R.isNil, R.equals(false)])(f(k, v));
|
1265 | }, o);
|
1266 | })(obj);
|
1267 | });
|
1268 | /**
|
1269 | * Given a predicate for eliminating an item based on paths, return the paths of item that don't pass the predicate.
|
1270 | * keyOrIndex is the object key or array index that the item came from. We use it for the eliminateItemPredicate
|
1271 | * test. If each paths current first segment matches keyOrIndex or equals '*', we consider that path.
|
1272 | * With the considered paths
|
1273 | * @param {Function} eliminateItemPredicate Accepts the remaining paths and optional item as a second argument.
|
1274 | * Returns true if the item shall be eliminated
|
1275 | * @param {[String]} paths Paths to caculate if they match the item
|
1276 | * @param {*} item Item to test
|
1277 | * @param {String|Number} keyOrIndex The key or index that the item belonged to of an object or array
|
1278 | * @return {Object} {item: the item, paths: remaining paths with first segment removed}. Or null if eliminateItemPredicate
|
1279 | * returns true
|
1280 | * @private
|
1281 | */
|
1282 |
|
1283 | var _calculateRemainingPaths = function _calculateRemainingPaths(eliminateItemPredicate, paths, item, keyOrIndex) {
|
1284 | // Keep paths that match keyOrIndex as the first item. Remove other paths
|
1285 | // since they can't match item or its descendants
|
1286 | var tailPathsStillMatchingItemPath = compact(R.map(R.compose(R.ifElse(R.compose(function (aKeyOrIndex) {
|
1287 | return R.ifElse( // if keyOrIndex is a string and matches the shape of a regex: /.../[gim]
|
1288 | function (possibleRegex) {
|
1289 | return R.both(R.is(String), function (str) {
|
1290 | return R.test(regexToMatchARegex, str);
|
1291 | })(possibleRegex);
|
1292 | }, // Construct the regex with one or two, the expression and options (gim)
|
1293 | function (provenRegex) {
|
1294 | var args = compactEmpty(R.split('/', provenRegex));
|
1295 | return _construct(RegExp, _toConsumableArray(args)).test(keyOrIndex);
|
1296 | }, // If aKeyOrIndex is '*' or equals keyOrIndex always return true
|
1297 | function (str) {
|
1298 | return R.includes(str, ['*', keyOrIndex]);
|
1299 | })(aKeyOrIndex);
|
1300 | }, R.head), // Matches the keyOrIndex at the head. Return the tail
|
1301 | R.tail, // Mark null to remove from list
|
1302 | R.always(null)), // Convert path to array with string keys and number indexes
|
1303 | keyStringToLensPath), paths)); // For omit:
|
1304 | // If any path matches the path to the item return null so we can throw away the item
|
1305 | // If no path is down to zero length return the item and the paths
|
1306 | // For pick:
|
1307 | // If no path matches the path to the item return null so we can throw away the item
|
1308 | // If any path is not down to zero return the item and the paths, unless item is a primitive meaning it can't match
|
1309 | // a path
|
1310 |
|
1311 | return R.ifElse(function (tailPaths) {
|
1312 | return eliminateItemPredicate(tailPaths, item);
|
1313 | }, R.always(null), function (p) {
|
1314 | return {
|
1315 | item: item,
|
1316 | paths: R.map(R.join('.'), p)
|
1317 | };
|
1318 | })(tailPathsStillMatchingItemPath);
|
1319 | }; // This predicate looks for any path that's zero length, meaning it matches the path to an item and we should
|
1320 | // omit that item
|
1321 |
|
1322 |
|
1323 | var _omitDeepPathsEliminateItemPredicate = function _omitDeepPathsEliminateItemPredicate(paths) {
|
1324 | return R.any(R.compose(R.equals(0), R.length), paths);
|
1325 | };
|
1326 | /**
|
1327 | * Omit matching paths in a a structure. For instance omitDeepPaths(['a.b.c', 'a.0.1']) will omit keys
|
1328 | * c in {a: {b: c: ...}}} and 'y' in {a: [['x', 'y']]}
|
1329 | */
|
1330 |
|
1331 |
|
1332 | var omitDeepPaths = R.curry(function (pathSet, obj) {
|
1333 | return R.cond([// Arrays
|
1334 | [function (o) {
|
1335 | return Array.isArray(o);
|
1336 | }, function (list) {
|
1337 | // Recurse on each array item that doesn't match the paths.
|
1338 | // We pass the key without the index
|
1339 | // If any path matches the path to the value we return the item and the matching paths
|
1340 | var survivingItems = compact(R.addIndex(R.map)(function (item, index) {
|
1341 | return _calculateRemainingPaths(_omitDeepPathsEliminateItemPredicate, pathSet, item, index);
|
1342 | }, list));
|
1343 | return R.map(function (_ref31) {
|
1344 | var paths = _ref31.paths,
|
1345 | item = _ref31.item;
|
1346 | return omitDeepPaths(paths, item);
|
1347 | }, survivingItems);
|
1348 | }], // Primitives always pass.
|
1349 | [R.complement(isObject), function (primitive) {
|
1350 | return primitive;
|
1351 | }], // Objects
|
1352 | [R.T, function (o) {
|
1353 | // Recurse on each object value that doesn't match the paths.
|
1354 | var survivingItems = compact(R.mapObjIndexed( // If any path matches the path to the value we return the value and the matching paths
|
1355 | // If no path matches it we know the value shouldn't be omitted so we don't recurse on it below
|
1356 | function (value, key) {
|
1357 | return _calculateRemainingPaths(_omitDeepPathsEliminateItemPredicate, pathSet, value, key);
|
1358 | }, o)); // Only recurse on items from the object that are still eligible for omitting
|
1359 |
|
1360 | return R.map(function (_ref32) {
|
1361 | var paths = _ref32.paths,
|
1362 | item = _ref32.item;
|
1363 | return omitDeepPaths(paths, item);
|
1364 | }, survivingItems);
|
1365 | }]])(obj);
|
1366 | }); // This eliminate predicate returns true if no path is left matching the item's path so the item should not
|
1367 | // be picked. It also returns true if the there are paths with length greater than 0
|
1368 | // but item is a primitive, meaning it can't match a path
|
1369 |
|
1370 | var _pickDeepPathsEliminateItemPredicate = function _pickDeepPathsEliminateItemPredicate(paths, item) {
|
1371 | return R.either(R.compose(R.equals(0), R.length), function (pths) {
|
1372 | return R.both( // Item is not an object
|
1373 | function () {
|
1374 | return R.complement(R.is)(Object, item);
|
1375 | }, function (ps) {
|
1376 | return R.any(R.compose(R.lt(0), R.length), ps);
|
1377 | })(pths);
|
1378 | })(paths);
|
1379 | };
|
1380 | /**
|
1381 | * Pick matching paths in a a structure. For instance pickDeepPaths(['a.b.c', 'a.0.1']) will pick only keys
|
1382 | * c in {a: {b: c: ...}}} and 'y' in {a: [['x', 'y']]}.
|
1383 | * Use * in the path to capture all array items or keys, e.g. ['a.*.c./1|3/']
|
1384 | * to get all items 0 or 3 of c that is in all items of a, whether a is an object or array
|
1385 | */
|
1386 |
|
1387 |
|
1388 | var pickDeepPaths = R.curry(function (pathSet, obj) {
|
1389 | return R.cond([// Arrays
|
1390 | [function (o) {
|
1391 | return Array.isArray(o);
|
1392 | }, function (list) {
|
1393 | // Recurse on each array item that doesn't match the paths. We pass the key without the index
|
1394 | // We pass the key without the index
|
1395 | // If any path matches the path to the value we return the item and the matching paths
|
1396 | var survivingItemsEachWithRemainingPaths = compact(R.addIndex(R.map)(function (item, index) {
|
1397 | return _calculateRemainingPaths(_pickDeepPathsEliminateItemPredicate, pathSet, item, index);
|
1398 | }, list));
|
1399 | return R.map(R.ifElse( // If the only paths are now empty we have a match with the items path and keep the item.
|
1400 | // Otherwise we pick recursively
|
1401 | function (_ref33) {
|
1402 | var paths = _ref33.paths;
|
1403 | return R.all(R.compose(R.equals(0), R.length), paths);
|
1404 | }, function (_ref34) {
|
1405 | var item = _ref34.item;
|
1406 | return item;
|
1407 | }, function (_ref35) {
|
1408 | var item = _ref35.item,
|
1409 | paths = _ref35.paths;
|
1410 | return pickDeepPaths(paths, item);
|
1411 | }), survivingItemsEachWithRemainingPaths);
|
1412 | }], // Primitives never match because we'd only get here if we have pathSets remaining and no path can match a primitive
|
1413 | [R.complement(isObject), function () {
|
1414 | throw new Error('pickDeepPaths encountered a value that is not an object or array at the top level. This should never happens and suggests a bug in this function');
|
1415 | }], // Objects
|
1416 | [R.T, function (o) {
|
1417 | // Recurse on each array item that doesn't match the paths. We pass the key without the index
|
1418 | // If any path matches the path to the value we return the value and the matching paths
|
1419 | // If no path matches it we know the value shouldn't be picked so we don't recurse on it below
|
1420 | var survivingItems = compact(R.mapObjIndexed(function (item, key) {
|
1421 | return _calculateRemainingPaths(_pickDeepPathsEliminateItemPredicate, pathSet, item, key);
|
1422 | }, o));
|
1423 | return R.map(R.ifElse( // If the only path is now empty we have a match with the items path and keep the item.
|
1424 | // Otherwise we pick recursively
|
1425 | function (_ref36) {
|
1426 | var item = _ref36.item,
|
1427 | paths = _ref36.paths;
|
1428 | return R.all(R.compose(R.equals(0), R.length), paths);
|
1429 | }, R.prop('item'), function (_ref37) {
|
1430 | var item = _ref37.item,
|
1431 | paths = _ref37.paths;
|
1432 | return pickDeepPaths(paths, item);
|
1433 | }), survivingItems);
|
1434 | }]])(obj);
|
1435 | });
|
1436 | /**
|
1437 | * splitAt that gives the split point item to both sides of the split
|
1438 | * @param {Number} index The index
|
1439 | * @param {String|[Object]} list A string or list
|
1440 | * @returns {[Object]} A pair of results
|
1441 | */
|
1442 |
|
1443 | var splitAtInclusive = function splitAtInclusive(index, list) {
|
1444 | var pair = R.splitAt(index, list);
|
1445 | return [R.concat(R.head(pair), R.slice(0, 1, R.last(pair))), R.last(pair)];
|
1446 | };
|
1447 | /**
|
1448 | * Whether the objects are equal at the given propStr. Null objects are never equal
|
1449 | * @param {String} stringPath Path of props separated by dots
|
1450 | * @param {Object|Array} obj1 The object to compare to obj2 at the propStr
|
1451 | * @param {Object|Array} obj2 The object to compare to obj1 at the propStr
|
1452 | * @returns {Boolean} True or false
|
1453 | */
|
1454 |
|
1455 | var eqStrPath = R.curry(function (stringPath, obj1, obj2) {
|
1456 | return R.apply(R.equals, R.map(strPathOr(null, stringPath), [obj1, obj2]));
|
1457 | });
|
1458 | /**
|
1459 | * Whether the objects are equal at the given strPaths. Null objects are never equal
|
1460 | * @param [{String}] strPaths Paths of props separated by dots
|
1461 | * @param {Object|Array} obj1 The object to compare to obj2 at the propStr
|
1462 | * @param {Object|Array} obj2 The object to compare to obj1 at the propStr
|
1463 | * @returns {Boolean} True or false
|
1464 | */
|
1465 |
|
1466 | var eqStrPathsAll = R.curry(function (strPaths, obj1, obj2) {
|
1467 | return R.all(function (prop) {
|
1468 | return eqStrPath(prop, obj1, obj2);
|
1469 | }, strPaths);
|
1470 | });
|
1471 |
|
1472 | exports._defineProperty = _defineProperty;
|
1473 | exports._mergeDeepWithRecurseArrayItemsByRight = _mergeDeepWithRecurseArrayItemsByRight;
|
1474 | exports._slicedToArray = _slicedToArray;
|
1475 | exports._toConsumableArray = _toConsumableArray;
|
1476 | exports._typeof = _typeof;
|
1477 | exports._unflattenObj = _unflattenObj;
|
1478 | exports.alwaysFunc = alwaysFunc;
|
1479 | exports.applyDeep = applyDeep;
|
1480 | exports.applyDeepAndMapObjs = applyDeepAndMapObjs;
|
1481 | exports.camelCase = camelCase;
|
1482 | exports.capitalize = capitalize;
|
1483 | exports.chainObjToValues = chainObjToValues;
|
1484 | exports.compact = compact;
|
1485 | exports.compactEmpty = compactEmpty;
|
1486 | exports.compactJoin = compactJoin;
|
1487 | exports.duplicateKey = duplicateKey;
|
1488 | exports.emptyToNull = emptyToNull;
|
1489 | exports.eqStrPath = eqStrPath;
|
1490 | exports.eqStrPathsAll = eqStrPathsAll;
|
1491 | exports.filterObjToValues = filterObjToValues;
|
1492 | exports.filterWithKeys = filterWithKeys;
|
1493 | exports.findByParams = findByParams;
|
1494 | exports.findMapped = findMapped;
|
1495 | exports.findOne = findOne;
|
1496 | exports.findOneValueByParams = findOneValueByParams;
|
1497 | exports.flattenObj = flattenObj;
|
1498 | exports.flattenObjUntil = flattenObjUntil;
|
1499 | exports.fromPairsDeep = fromPairsDeep;
|
1500 | exports.hasStrPath = hasStrPath;
|
1501 | exports.idOrIdFromObj = idOrIdFromObj;
|
1502 | exports.isObject = isObject;
|
1503 | exports.keyStringToLensPath = keyStringToLensPath;
|
1504 | exports.lowercase = lowercase;
|
1505 | exports.mapDefault = mapDefault;
|
1506 | exports.mapDefaultAndPrefixOthers = mapDefaultAndPrefixOthers;
|
1507 | exports.mapKeys = mapKeys;
|
1508 | exports.mapKeysAndValues = mapKeysAndValues;
|
1509 | exports.mapKeysForLens = mapKeysForLens;
|
1510 | exports.mapObjToValues = mapObjToValues;
|
1511 | exports.mapProp = mapProp;
|
1512 | exports.mapPropValueAsIndex = mapPropValueAsIndex;
|
1513 | exports.mapToObjValue = mapToObjValue;
|
1514 | exports.mergeAllWithKey = mergeAllWithKey;
|
1515 | exports.mergeDeep = mergeDeep;
|
1516 | exports.mergeDeepAll = mergeDeepAll;
|
1517 | exports.mergeDeepWith = mergeDeepWith;
|
1518 | exports.mergeDeepWithConcatArrays = mergeDeepWithConcatArrays;
|
1519 | exports.mergeDeepWithRecurseArrayItems = mergeDeepWithRecurseArrayItems;
|
1520 | exports.mergeDeepWithRecurseArrayItemsAndMapObjs = mergeDeepWithRecurseArrayItemsAndMapObjs;
|
1521 | exports.mergeDeepWithRecurseArrayItemsByAndMergeObjectByRight = mergeDeepWithRecurseArrayItemsByAndMergeObjectByRight;
|
1522 | exports.mergeDeepWithRecurseArrayItemsByRight = mergeDeepWithRecurseArrayItemsByRight;
|
1523 | exports.moveToKeys = moveToKeys;
|
1524 | exports.omitDeep = omitDeep;
|
1525 | exports.omitDeepBy = omitDeepBy;
|
1526 | exports.omitDeepPaths = omitDeepPaths;
|
1527 | exports.onlyOne = onlyOne;
|
1528 | exports.onlyOneValue = onlyOneValue;
|
1529 | exports.orEmpty = orEmpty;
|
1530 | exports.overDeep = overDeep;
|
1531 | exports.pickDeepPaths = pickDeepPaths;
|
1532 | exports.removeDuplicateObjectsByProp = removeDuplicateObjectsByProp;
|
1533 | exports.renameKey = renameKey;
|
1534 | exports.replaceValuesAtDepth = replaceValuesAtDepth;
|
1535 | exports.replaceValuesAtDepthAndStringify = replaceValuesAtDepthAndStringify;
|
1536 | exports.replaceValuesWithCountAtDepth = replaceValuesWithCountAtDepth;
|
1537 | exports.replaceValuesWithCountAtDepthAndStringify = replaceValuesWithCountAtDepthAndStringify;
|
1538 | exports.reqPath = reqPath;
|
1539 | exports.reqPathPropEq = reqPathPropEq;
|
1540 | exports.reqStrPath = reqStrPath;
|
1541 | exports.splitAtInclusive = splitAtInclusive;
|
1542 | exports.strPath = strPath;
|
1543 | exports.strPathOr = strPathOr;
|
1544 | exports.strPathOrNullOk = strPathOrNullOk;
|
1545 | exports.toArrayIfNot = toArrayIfNot;
|
1546 | exports.transformKeys = transformKeys;
|
1547 | exports.unflattenObj = unflattenObj;
|
1548 | exports.unflattenObjNoArrays = unflattenObjNoArrays;
|
1549 | //# sourceMappingURL=functions-b6202a08.js.map
|