/** * Utility functions for all environments. * This replaces the underscore dependency. * * @module utils * @private */ /** * @callback IterateeFunction * @param {*} arg * @return {*} */ /** * Produces a duplicate-free version of the array, using === to test object equality. In particular only the first * occurrence of each value is kept. If you want to compute unique items based on a transformation, pass an iteratee * function. * * Heavily inspired by {@link https://underscorejs.org/#uniq}. * @param {Array} array * @param {IterateeFunction} [iteratee] transformation applied to every element before checking for duplicates. This will not * transform the items in the result. * @return {Array} * @alias module:utils.uniq */ const uniq = (array, iteratee) => { if (iteratee) return [...(new Map(array.map(x => [iteratee(x), x]))).values()] else return [...new Set(array)] } /** * Returns true if arg is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings * and numbers are not. * * Heavily inspired by {@link https://underscorejs.org/#isObject}. * @param {*} arg * @return {boolean} */ const isObject = arg => typeof arg === 'object' && arg !== null /** * Returns true if d is a Date. * * Heavily inspired by {@link https://underscorejs.org/#isDate}. * @param {*} d * @return {boolean} * @alias module:utils.isDate */ const isDate = d => isObject(d) && Object.prototype.toString.call(d) === '[object Date]' /** * Returns true if re is a RegExp. * * Heavily inspired by {@link https://underscorejs.org/#isRegExp}. * @param {*} re * @return {boolean} * @alias module:utils.isRegExp */ const isRegExp = re => isObject(re) && Object.prototype.toString.call(re) === '[object RegExp]' /** * Return a copy of the object filtered using the given keys. * * @param {object} object * @param {string[]} keys * @return {object} */ const pick = (object, keys) => { return keys.reduce((obj, key) => { if (object && Object.prototype.hasOwnProperty.call(object, key)) { obj[key] = object[key] } return obj }, {}) } const filterIndexNames = (indexNames) => ([k, v]) => !!(typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' || isDate(v) || v === null) && indexNames.includes(k) module.exports.uniq = uniq module.exports.isDate = isDate module.exports.isRegExp = isRegExp module.exports.pick = pick module.exports.filterIndexNames = filterIndexNames