UNPKG

hashable-cli

Version:

Generate consistent and predictable JSON output for hashing, version control, and testing. Sorts arrays based on a configurable priority list of fields, handles nested objects and arrays, and optionally sorts object keys alphabetically. Provides a comma

93 lines (79 loc) 2.06 kB
/** * Generate consistent hashable JSON payload * great for piping through hash functions. * * Use `sortObject` to sort object keys. Default: false * Use `priority` to specify array sorting priority * (default priority is used if not specified) * * @author CJ <lim@chernjie.com> */ const defaultSort = [ "id", "_id", "name", "key", "category", "value", "label", "page", "language", "store_id", "category_id", ] export function getDefaultPriority() { return [...defaultSort] } function hashable(data, { priority = getDefaultPriority(), sortObject = false } = {}) { if (!_isObject(data)) return data const sorted = {} Object.keys(data).forEach(key => { // array if (Array.isArray(data[key])) { sorted[key] = data[key].filter(e => e !== null) .sort((a, b) => { if (['number', 'string'].includes(typeof a)) return sortBy(a, b) for (var i in priority) { const field = priority[i] const first = _get(a, field) if (typeof first !== 'undefined') return sortBy(first, _get(b, field)) } console.error('hashable sorting', a, b) }) .map(obj => hashable(obj, { priority, sortObject })) } // object else if (_isObject(data[key])) { sorted[key] = hashable(data[key], { priority, sortObject }) } // primitive else { sorted[key] = data[key] } }) if (sortObject) { return Object.keys(sorted) .sort() .reduce((accumulator, key) => { accumulator[key] = sorted[key] return accumulator }, {}) } return sorted } function sortBy(a, b) { if (a === b) return 0 return a > b ? 1 : -1 } function _get(obj, path) { return path.split('.').reduce((v, k) => { if (typeof v === 'undefined') return undefined if (typeof v[k] === 'undefined') return undefined return v[k] }, obj) } function _isObject(obj) { const type = typeof obj return type === 'function' || (type === 'object' && !!obj) } export default hashable