UNPKG

vest-utils

Version:
218 lines (203 loc) 5.91 kB
'use strict'; // The module is named "isArrayValue" since it // is conflicting with a nested npm dependency. // We may need to revisit this in the future. function isArray(value) { return Boolean(Array.isArray(value)); } /** * A safe hasOwnProperty access */ function hasOwnProperty(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } function isNumeric(value) { const str = String(value); const num = Number(value); const result = !isNaN(parseFloat(str)) && !isNaN(Number(value)) && isFinite(num); return Boolean(result); } function numberEquals(value, eq) { return isNumeric(value) && isNumeric(eq) && Number(value) === Number(eq); } function lengthEquals(value, arg1) { return numberEquals(value.length, arg1); } function isNull(value) { return value === null; } function isUndefined(value) { return value === undefined; } function isNullish(value) { return isNull(value) || isUndefined(value); } function isObject(v) { return typeof v === 'object' && !isNullish(v); } function isEmpty(value) { if (!value) { return true; } else if (hasOwnProperty(value, 'length')) { return lengthEquals(value, 0); } else if (isObject(value)) { return lengthEquals(Object.keys(value), 0); } return false; } function isFunction(value) { return typeof value === 'function'; } function isStringValue(v) { return String(v) === v; } // Basic key generator that generates keys like a, b, c, ... aa, ab, ac, ... function genMinifiedKey() { const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*'; let index = 0; return function next() { let code = ''; let x = index; do { code = code + chars[x % chars.length]; x = Math.floor(x / chars.length); } while (x > 0); index++; return code; }; } function minifyObject(obj, replacer = v => v) { const countMap = new Map(); countOccurrences(obj, countMap, replacer); const maps = genMap(countMap); const o = minifyObjectImpl(obj, maps.map, replacer); // need to reverse the map so that the minified keys are the keys and the original keys are the values // and turn it into an object return [o, maps.reverseMap]; } function genMap(countMap) { const counts = []; for (const [value, count] of countMap) { if (count > 1) { counts.push({ value, count }); } } const sorted = counts.sort((a, z) => z.count - a.count); const getKey = genMinifiedKey(); return sorted.reduce((maps, { value }) => { if (!shouldAddToMap(value, maps.keyLength)) { return maps; } let key; do { key = getKey(); } while (countMap.has(key)); maps.map.set(value, key); maps.reverseMap[key] = value; maps.keyLength = key.length; return maps; }, { map: new Map(), reverseMap: {}, keyLength: 1, }); } // This avoids minification if the original key is shorter than or equals the minified key function shouldAddToMap(value, keyLength) { return value.toString().length >= keyLength; } function addCount(value, countMap) { countMap.set(value, (countMap.get(value) || 0) + 1); } function countOccurrences(obj, countMap, replacer) { for (const key in obj) { const value = replacer(obj[key], key); if (!shouldMinify(value)) continue; if (!Array.isArray(obj)) { addCount(key, countMap); } if (isObject(value)) { countOccurrences(value, countMap, replacer); } else { addCount(value, countMap); } } } function isNonSerializable(value) { return isNullish(value) || isFunction(value) || typeof value === 'symbol'; } // eslint-disable-next-line complexity function shouldMinify(value) { if (isObject(value) && isEmpty(value)) { return false; } if (isNonSerializable(value)) { return false; } if (isObject(value) && isEmpty(value)) { return false; } return true; } function minifyObjectImpl(obj, map, replacer) { const minifiedObject = getRootNode(obj); for (const key in obj) { const value = replacer(obj[key], key); if (!shouldMinify(value)) continue; let minifiedValue; if (isObject(value)) { minifiedValue = minifyObjectImpl(value, map, replacer); } else { minifiedValue = minifyValue(value, map); } setValue(minifiedObject, minifiedValue, minifyValue(key, map)); } return minifiedObject; } function minifyValue(value, map) { var _a; return (_a = map.get(value)) !== null && _a !== void 0 ? _a : value; } function expandSingle(value, map) { var _a; if (isStringValue(value)) { return (_a = map[value]) !== null && _a !== void 0 ? _a : value; } return value; } function expandObject(minifiedObj, map) { const expandedObject = getRootNode(minifiedObj); for (const key in minifiedObj) { let expandedValue; const value = minifiedObj[key]; if (isObject(value)) { expandedValue = expandObject(value, map); } else { expandedValue = expandSingle(value, map); } const expandedKey = expandSingle(key, map); setValue(expandedObject, expandedValue, expandedKey); } return expandedObject; } function setValue(container, value, key) { if (isArray(container)) { container.push(value); } else { container[key] = value; } } function getRootNode(node) { return isArray(node) ? [] : {}; } exports.expandObject = expandObject; exports.minifyObject = minifyObject; //# sourceMappingURL=minifyObject.development.js.map