const _isArray = Array.isArray; const _keys = Object.keys; /** * Tests for a plain object * * @param aObject the object to test */ function _isPlainObject(aObject: any): boolean { return aObject && !aObject.prototype && (typeof aObject === 'object'); } const KEY_WEIGHTS: {[key: string]: number} = { 'name': 1, 'description': 2, 'id': 3, 'classification': 4 }; function _compareNumber(aLeft: number, aRight: number): number { return (aLeft < aRight) ? -1 : (aLeft > aRight) ? +1 : 0; } function _getKey(aName: string): number { return KEY_WEIGHTS[aName] || Number.MAX_SAFE_INTEGER; } function _compareName(aLeft: string, aRight: string): number { // first by key let c = _compareNumber(_getKey(aLeft), _getKey(aRight)); if (c === 0) { c = aLeft.localeCompare(aRight); } // ok return c; } function _canonicalize(aData: any): any { // handle if (_isArray(aData)) { const copy: any[] = []; aData.forEach(v => copy.push(_canonicalize(v))); return copy; } if (_isPlainObject(aData)) { // sort the keys const copy: any = {}; _keys(aData).sort(_compareName).forEach(k => copy[k] = _canonicalize(aData[k])); return copy; } // nothing to do return aData; } export { _canonicalize as canonicalizeJSON };