@tdb/util
Version:
Shared helpers and utilities.
136 lines (135 loc) • 4.61 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var libs_1 = require("./libs");
var value_array_1 = require("./value.array");
function walk(obj, fn) {
var process = function (item) {
fn(item);
if (libs_1.R.is(Object, item) || libs_1.R.is(Array, item)) {
walk(item, fn);
}
};
if (libs_1.R.is(Array, obj)) {
obj.forEach(function (item) { return process(item); });
}
else {
Object.keys(obj).forEach(function (key) { return process(obj[key]); });
}
}
exports.walk = walk;
function build(keyPath, root, value) {
var parts = prepareKeyPath(keyPath);
var result = tslib_1.__assign({}, root);
var current = result;
var path = '';
parts.forEach(function (key, i) {
var isLast = i === parts.length - 1;
var hasValue = isLast && value !== undefined;
if (hasValue) {
current[key] = value;
}
else {
path = path ? path + "." + key : key;
var level = current[key] !== undefined ? current[key] : {};
if (!libs_1.R.is(Object, level)) {
throw new Error("Cannot build object '" + keyPath + "' as it will overwrite value '" + level + "' at '" + path + "'.");
}
current[key] = tslib_1.__assign({}, level);
current = current[key];
}
});
return result;
}
exports.build = build;
function pluck(keyPath, root) {
var parts = prepareKeyPath(keyPath);
var current = root;
var result;
var index = -1;
for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
var key = parts_1[_i];
if (!current) {
break;
}
index++;
var isLast = index === parts.length - 1;
if (isLast) {
result = current[key];
}
else {
current = current[key];
}
}
return result;
}
exports.pluck = pluck;
function remove(keyPath, root, options) {
if (options === void 0) { options = {}; }
var _a = options.type, type = _a === void 0 ? 'LEAF' : _a;
var isEmptyObject = function (value) { return libs_1.R.equals(value, {}); };
var isWildcard = function (value) { return value === '*'; };
var process = function (parts, obj, parent) {
var key = parts[0];
var nextKey = parts[1];
if (isWildcard(nextKey) || (parts.length > 1 && libs_1.R.is(Object, obj[key]))) {
process(parts.slice(1), obj[key], { key: key, obj: obj });
}
var isDeepest = parts.length === 1;
var value = obj && obj[key];
var isEmpty = isEmptyObject(value);
if (isWildcard(key) && !isDeepest) {
throw new Error("Wild card can only be used at end of path (error: '" + keyPath + "')");
}
var shouldDelete = false;
if (isEmpty && type === 'PRUNE') {
shouldDelete = true;
}
if (isDeepest && isWildcard(key)) {
shouldDelete = true;
}
if (isDeepest && !libs_1.R.is(Object, value)) {
shouldDelete = true;
}
if (shouldDelete) {
if (parent) {
parent.obj[parent.key] = tslib_1.__assign({}, parent.obj[parent.key]);
if (isWildcard(key)) {
switch (type) {
case 'LEAF':
parent.obj[parent.key] = {};
break;
case 'PRUNE':
delete parent.obj[parent.key];
break;
default:
throw new Error("Type '" + type + "' not supported.");
}
}
else {
delete parent.obj[parent.key][key];
}
}
else {
delete obj[key];
}
}
return obj;
};
var parts = prepareKeyPath(keyPath);
return parts.length === 1 && parts[0] === '*'
? {}
: process(parts, tslib_1.__assign({}, root));
}
exports.remove = remove;
function prune(keyPath, root) {
return remove(keyPath, root, { type: 'PRUNE' });
}
exports.prune = prune;
function prepareKeyPath(keyPath) {
keyPath = keyPath.trim();
if (keyPath.startsWith('.') || keyPath.endsWith('.')) {
throw new Error("The keyPath cannot start or end with a period (.): \"" + keyPath + "\"");
}
return value_array_1.compact(keyPath.replace(/\s/g, '').split('.'));
}