json-order
Version:
Control the order of properties in JSON via a lookup object - including nested properties.
79 lines (78 loc) • 3.01 kB
JavaScript
;
/* eslint-disable @typescript-eslint/ban-types */
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
var getProperty = function (obj, key, separator) {
var exists = true;
var value = key
.split(separator)
.filter(function (s) { return s.length > 0; })
.reduce(function (o, x) {
exists = o && o.hasOwnProperty(x);
if (!exists) {
return undefined;
}
return o[x];
}, obj);
return { exists: exists, value: value };
};
var setProperty = function (obj, key, value, separator) {
key
.split(separator)
.filter(function (s) { return s.length > 0; })
.reduce(function (o, x, idx, src) {
if (idx === src.length - 1) {
var valueToSet = Array.isArray(value)
? lodash_clonedeep_1.default(value).map(function (p) { return (typeof p === 'object' ? {} : p); })
: value;
o[x] = valueToSet;
}
return o[x];
}, obj);
};
var copyProperty = function (sourceObject, resultObject, propertyPath, separator) {
var result = getProperty(sourceObject, propertyPath, separator);
if (result.exists) {
setProperty(resultObject, propertyPath, result.value, separator);
}
};
/**
* Duplicate a JS object but containing a particular property order
*
* @param sourceObject an object with the properties in any order
* @param map the `PropertyMap` generated by the `parse` method
* @param separator a non-empty `string` that controls what the key separator is in the generated map. Defaults to `~`.
* @returns the source object ordered as per the map
*/
var order = function (sourceObject, map, separator) {
if (separator === void 0) { separator = '~'; }
if (separator.length < 1) {
throw new Error('Separator should not be an empty string.');
}
if (!map) {
return sourceObject;
}
var mapKeys = Object.keys(map);
var prefixLength = (mapKeys[0] && mapKeys[0].length) || 0;
var resultObject = {};
mapKeys.forEach(function (mk) {
var childKeys = map[mk];
// Remove prefix
var parentKey = mk.substr(prefixLength);
var parent = getProperty(sourceObject, parentKey, separator);
if (parent.exists) {
// Set a default value for the property
var defaultValue = Array.isArray(parent.value) ? parent.value : {};
setProperty(resultObject, parentKey, defaultValue, separator);
// Fetch value from source and set on output
childKeys.forEach(function (key) {
return copyProperty(sourceObject, resultObject, "" + parentKey + separator + key, separator);
});
}
});
return resultObject;
};
exports.default = order;