UNPKG

61.2 kBJavaScriptView Raw
1'use strict';
2
3var R = require('ramda');
4var Result = require('folktale/result');
5var Rm = require('ramda-maybe');
6
7function _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
23function _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
38function _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
47function 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
60function _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
77function _slicedToArray(arr, i) {
78 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
79}
80
81function _toArray(arr) {
82 return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();
83}
84
85function _toConsumableArray(arr) {
86 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
87}
88
89function _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
97function _arrayWithHoles(arr) {
98 if (Array.isArray(arr)) return arr;
99}
100
101function _iterableToArray(iter) {
102 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
103}
104
105function _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
135function _nonIterableSpread() {
136 throw new TypeError("Invalid attempt to spread non-iterable instance");
137}
138
139function _nonIterableRest() {
140 throw new TypeError("Invalid attempt to destructure non-iterable instance");
141}
142
143var 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
151var 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
162var 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
173var 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
181var 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
190var 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
201var 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
212var 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
225var 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
235var 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
246var 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
259var 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
273var 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
284var 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
299var 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
314var 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
356var 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
379var mergeDeepWithRecurseArrayItemsByAndMergeObjectByRight = R.curry(function (itemMatchBy, mergeObject, left, right) {
380 return _mergeDeepWithRecurseArrayItemsByRight(itemMatchBy, mergeObject, left, right, null);
381});
382var _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
444var 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
458var 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
471var applyDeepAndMapObjs = R.curry(function (fn, applyObj, obj) {
472 return mergeDeepWithRecurseArrayItemsAndMapObjs(fn, applyObj, obj, obj);
473});
474
475var _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
545var 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
556var 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
565var 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
577var 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
600var 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
631var 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
642var 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
653var 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});
657var 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
679var 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
691var 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
703var 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
718var 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
731var 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
746var 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
761var 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
773var 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
789var 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
807var 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
821var 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
836var 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
847var 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
865var 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
886var 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
895var onlyOneValue = R.compose( // Use R.map to operate on the value of Result without extracting it
896R.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
904var 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
916var 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
930var 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
944var 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
956var 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
967var 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
977var 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
987var 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
1002var 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
1046function 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
1071var 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
1081var 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
1098var 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
1108var 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
1118var flattenObjUntil = function flattenObjUntil(predicate, obj) {
1119 return R.fromPairs(_flattenObj({
1120 predicate: predicate
1121 }, obj));
1122};
1123
1124var _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
1153var 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
1162var 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
1173var unflattenObj = function unflattenObj(obj) {
1174 return _unflattenObj({
1175 allowArrays: true
1176 }, obj);
1177};
1178var _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
1218var 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
1230var 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
1242var 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
1283var _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
1323var _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
1332var 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
1370var _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
1388var 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
1443var 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
1455var 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
1466var eqStrPathsAll = R.curry(function (strPaths, obj1, obj2) {
1467 return R.all(function (prop) {
1468 return eqStrPath(prop, obj1, obj2);
1469 }, strPaths);
1470});
1471
1472exports._defineProperty = _defineProperty;
1473exports._mergeDeepWithRecurseArrayItemsByRight = _mergeDeepWithRecurseArrayItemsByRight;
1474exports._slicedToArray = _slicedToArray;
1475exports._toConsumableArray = _toConsumableArray;
1476exports._typeof = _typeof;
1477exports._unflattenObj = _unflattenObj;
1478exports.alwaysFunc = alwaysFunc;
1479exports.applyDeep = applyDeep;
1480exports.applyDeepAndMapObjs = applyDeepAndMapObjs;
1481exports.camelCase = camelCase;
1482exports.capitalize = capitalize;
1483exports.chainObjToValues = chainObjToValues;
1484exports.compact = compact;
1485exports.compactEmpty = compactEmpty;
1486exports.compactJoin = compactJoin;
1487exports.duplicateKey = duplicateKey;
1488exports.emptyToNull = emptyToNull;
1489exports.eqStrPath = eqStrPath;
1490exports.eqStrPathsAll = eqStrPathsAll;
1491exports.filterObjToValues = filterObjToValues;
1492exports.filterWithKeys = filterWithKeys;
1493exports.findByParams = findByParams;
1494exports.findMapped = findMapped;
1495exports.findOne = findOne;
1496exports.findOneValueByParams = findOneValueByParams;
1497exports.flattenObj = flattenObj;
1498exports.flattenObjUntil = flattenObjUntil;
1499exports.fromPairsDeep = fromPairsDeep;
1500exports.hasStrPath = hasStrPath;
1501exports.idOrIdFromObj = idOrIdFromObj;
1502exports.isObject = isObject;
1503exports.keyStringToLensPath = keyStringToLensPath;
1504exports.lowercase = lowercase;
1505exports.mapDefault = mapDefault;
1506exports.mapDefaultAndPrefixOthers = mapDefaultAndPrefixOthers;
1507exports.mapKeys = mapKeys;
1508exports.mapKeysAndValues = mapKeysAndValues;
1509exports.mapKeysForLens = mapKeysForLens;
1510exports.mapObjToValues = mapObjToValues;
1511exports.mapProp = mapProp;
1512exports.mapPropValueAsIndex = mapPropValueAsIndex;
1513exports.mapToObjValue = mapToObjValue;
1514exports.mergeAllWithKey = mergeAllWithKey;
1515exports.mergeDeep = mergeDeep;
1516exports.mergeDeepAll = mergeDeepAll;
1517exports.mergeDeepWith = mergeDeepWith;
1518exports.mergeDeepWithConcatArrays = mergeDeepWithConcatArrays;
1519exports.mergeDeepWithRecurseArrayItems = mergeDeepWithRecurseArrayItems;
1520exports.mergeDeepWithRecurseArrayItemsAndMapObjs = mergeDeepWithRecurseArrayItemsAndMapObjs;
1521exports.mergeDeepWithRecurseArrayItemsByAndMergeObjectByRight = mergeDeepWithRecurseArrayItemsByAndMergeObjectByRight;
1522exports.mergeDeepWithRecurseArrayItemsByRight = mergeDeepWithRecurseArrayItemsByRight;
1523exports.moveToKeys = moveToKeys;
1524exports.omitDeep = omitDeep;
1525exports.omitDeepBy = omitDeepBy;
1526exports.omitDeepPaths = omitDeepPaths;
1527exports.onlyOne = onlyOne;
1528exports.onlyOneValue = onlyOneValue;
1529exports.orEmpty = orEmpty;
1530exports.overDeep = overDeep;
1531exports.pickDeepPaths = pickDeepPaths;
1532exports.removeDuplicateObjectsByProp = removeDuplicateObjectsByProp;
1533exports.renameKey = renameKey;
1534exports.replaceValuesAtDepth = replaceValuesAtDepth;
1535exports.replaceValuesAtDepthAndStringify = replaceValuesAtDepthAndStringify;
1536exports.replaceValuesWithCountAtDepth = replaceValuesWithCountAtDepth;
1537exports.replaceValuesWithCountAtDepthAndStringify = replaceValuesWithCountAtDepthAndStringify;
1538exports.reqPath = reqPath;
1539exports.reqPathPropEq = reqPathPropEq;
1540exports.reqStrPath = reqStrPath;
1541exports.splitAtInclusive = splitAtInclusive;
1542exports.strPath = strPath;
1543exports.strPathOr = strPathOr;
1544exports.strPathOrNullOk = strPathOrNullOk;
1545exports.toArrayIfNot = toArrayIfNot;
1546exports.transformKeys = transformKeys;
1547exports.unflattenObj = unflattenObj;
1548exports.unflattenObjNoArrays = unflattenObjNoArrays;
1549//# sourceMappingURL=functions-b6202a08.js.map