find-and
Version:
Find nested objects and: appendProps / replaceObject / changeProps / removeObject / returnFound / insertObjectBefore / insertObjectAfter
296 lines (295 loc) • 11.7 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
var helpers_1 = require("./helpers");
/**
* Function appends props to a nested object in an object or object array.
* If the `source` param is undefined, function returns undefined.
* If the `source` param is not an array or object, function returns it as is.
* If whether `predicate` or `newProps` param is not an object,
* or the `predicate` object is empty, function returns the unmodified `source`.
*
* @param source
* @param predicate
* @param newProps
*/
function appendProps(source, predicate, newProps) {
if (source === undefined) {
return undefined;
}
var processObject = function (item) {
if (!helpers_1.isObject(item)) {
return item;
}
var itemClone = __assign({}, item);
if (helpers_1.checkAgainstPredicate(itemClone, predicate)) {
itemClone = __assign(__assign({}, itemClone), newProps);
}
Object.keys(itemClone).forEach(function (key) {
var _a;
if (helpers_1.isObject(itemClone[key]) || Array.isArray(itemClone[key])) {
itemClone = __assign(__assign({}, itemClone), (_a = {}, _a[key] = appendProps(itemClone[key], predicate, newProps), _a));
}
});
return itemClone;
};
if ((Array.isArray(source) || helpers_1.isObject(source)) && !helpers_1.isEmpty(predicate) && !helpers_1.isEmpty(newProps)) {
return !Array.isArray(source) ? processObject(source) : source.map(function (item) { return processObject(item); });
}
return source;
}
exports.appendProps = appendProps;
/**
* Function replaces __all__ props of a nested object in an object or object array.
* If the `source` param is undefined, function returns undefined.
* If the `source` param is not an object, function returns it as is.
* If whether `predicate` or `replaceWith` param is not an object,
* or the `predicate` object is empty, function returns the unmodified `source`.
*
* @param source
* @param predicate
* @param replaceWith
*/
function replaceObject(source, predicate, replaceWith) {
if (source === undefined) {
return undefined;
}
var processObject = function (item) {
if (!helpers_1.isObject(item)) {
return item;
}
var itemClone = __assign({}, item);
if (helpers_1.checkAgainstPredicate(itemClone, predicate)) {
itemClone = __assign({}, replaceWith);
}
Object.keys(itemClone).forEach(function (key) {
var _a;
if (helpers_1.isObject(itemClone[key]) || Array.isArray(itemClone[key])) {
itemClone = __assign(__assign({}, itemClone), (_a = {}, _a[key] = replaceObject(itemClone[key], predicate, replaceWith), _a));
}
});
return itemClone;
};
if ((Array.isArray(source) || helpers_1.isObject(source)) && !helpers_1.isEmpty(predicate) && !helpers_1.isEmpty(replaceWith)) {
return !Array.isArray(source) ? processObject(source) : source.map(function (item) { return processObject(item); });
}
return source;
}
exports.replaceObject = replaceObject;
/**
* Function replaces some __existing__ props of a nested object in an object or object array.
* If the `source` param is undefined, function returns undefined.
* If the `source` param is not an object, function returns it as is.
* If whether `predicate` or `replaceProps` param is not an object,
* or the `predicate` object is empty, function returns the unmodified `source`.
*
* @param source
* @param predicate
* @param replaceProps
*/
function changeProps(source, predicate, replaceProps) {
if (source === undefined) {
return undefined;
}
var processObject = function (item) {
if (!helpers_1.isObject(item)) {
return item;
}
var itemClone = __assign({}, item);
if (helpers_1.checkAgainstPredicate(itemClone, predicate)) {
Object.keys(replaceProps).forEach(function (key) {
var _a;
if (Object.prototype.hasOwnProperty.call(itemClone, key)) {
itemClone = __assign(__assign({}, itemClone), (_a = {}, _a[key] = replaceProps[key], _a));
}
});
}
Object.keys(itemClone).forEach(function (key) {
var _a;
if (helpers_1.isObject(itemClone[key]) || Array.isArray(itemClone[key])) {
itemClone = __assign(__assign({}, itemClone), (_a = {}, _a[key] = changeProps(itemClone[key], predicate, replaceProps), _a));
}
});
return itemClone;
};
if ((Array.isArray(source) || helpers_1.isObject(source)) && !helpers_1.isEmpty(predicate) && !helpers_1.isEmpty(replaceProps)) {
return !Array.isArray(source) ? processObject(source) : source.map(function (item) { return processObject(item); });
}
return source;
}
exports.changeProps = changeProps;
/**
* Function removes a nested object in an object or object array.
* If the `source` param is undefined, function returns undefined.
* If the `source` param is not an object, function returns it as is.
* If the `predicate` param is not an object or it is empty, function returns the unmodified `source`.
*
* @param source
* @param predicate
*/
function removeObject(source, predicate) {
if (source === undefined) {
return undefined;
}
var processObject = function (item) {
if (!helpers_1.isObject(item)) {
return item;
}
var itemClone = __assign({}, item);
Object.keys(itemClone).forEach(function (key) {
var _a;
if (helpers_1.isObject(itemClone[key]) || Array.isArray(itemClone[key])) {
itemClone = __assign(__assign({}, itemClone), (_a = {}, _a[key] = removeObject(itemClone[key], predicate), _a));
}
});
return itemClone;
};
if ((Array.isArray(source) || helpers_1.isObject(source)) && !helpers_1.isEmpty(predicate)) {
if (!Array.isArray(source)) {
if (!helpers_1.checkAgainstPredicate(source, predicate)) {
return processObject(source);
}
}
else {
return source.filter(function (item) {
return !helpers_1.checkAgainstPredicate(item, predicate);
}).map(function (item) { return processObject(item); });
}
}
else {
return source;
}
}
exports.removeObject = removeObject;
/**
* Function returns the found object, or an object array if there's more than one object found.
* If the `source` param is undefined, function returns undefined.
* If the `source` param is not an object, function returns it as is.
* If the `predicate` param is not an object, or it's empty, function returns the unmodified `source`.
*
* @param source
* @param predicate
*/
function returnFound(source, predicate) {
if (source === undefined) {
return undefined;
}
var result = undefined;
var appendResult = function (item) {
if (!item || helpers_1.isEmpty(item)) {
return;
}
result = result ? (!Array.isArray(result) ? [result, __assign({}, item)] : __spreadArrays(result, [__assign({}, item)])) : item;
};
var processObject = function (item) {
if (helpers_1.checkAgainstPredicate(item, predicate)) {
appendResult(item);
}
Object.keys(item).forEach(function (key) {
if (helpers_1.isObject(item[key]) || Array.isArray(item[key])) {
appendResult(returnFound(item[key], predicate));
}
});
};
if ((Array.isArray(source) || helpers_1.isObject(source)) && !helpers_1.isEmpty(predicate)) {
!Array.isArray(source) ? processObject(source) : source.map(function (item) { return processObject(item); });
}
else {
return source;
}
return result;
}
exports.returnFound = returnFound;
/**
* Base function for `insertObjectBefore` and `insertObjectAfter`.
*
* @param source
* @param predicate
* @param objectToInsert
* @param isBefore
*/
function insertObject(source, predicate, objectToInsert, isBefore) {
if (source === undefined) {
return undefined;
}
var processObject = function (item) {
if (!helpers_1.isObject(item)) {
return item;
}
var itemClone = __assign({}, item);
Object.keys(itemClone).forEach(function (key) {
var _a;
if (helpers_1.isObject(itemClone[key]) || Array.isArray(itemClone[key])) {
itemClone = __assign(__assign({}, itemClone), (_a = {}, _a[key] = insertObject(itemClone[key], predicate, objectToInsert, isBefore), _a));
}
});
return itemClone;
};
var processArray = function (sourceArray) {
var indexes = [];
var sourceClone = sourceArray.map(function (item, index) {
var processedItem = processObject(item);
if (helpers_1.checkAgainstPredicate(processedItem, predicate)) {
indexes.push(index);
}
return processedItem;
});
if (indexes.length > 0) {
for (var i = 0; i < indexes.length; i += 1) {
sourceClone.splice(indexes[i] + i + (isBefore ? 0 : 1), 0, objectToInsert);
}
}
return sourceClone;
};
if ((Array.isArray(source) || helpers_1.isObject(source)) && !helpers_1.isEmpty(predicate) && !helpers_1.isEmpty(objectToInsert)) {
return !Array.isArray(source) ? processObject(source) : processArray(source);
}
return source;
}
/**
* Function inserts the given `objectToInsert` before the found object if the found object's parent is array.
* If the `source` param is undefined, function returns undefined.
* If the `source` param is not an object, function returns it as is.
* If whether `predicate` or `objectToInsert` param is not an object,
* or the `predicate` object is empty, function returns the unmodified `source`.
*
* @param source
* @param predicate
* @param objectToInsert
*/
function insertObjectBefore(source, predicate, objectToInsert) {
return insertObject(source, predicate, objectToInsert, true);
}
exports.insertObjectBefore = insertObjectBefore;
/**
* Function inserts the given `objectToInsert` after the found object if the found object's parent is array.
* If the `source` param is undefined, function returns undefined.
* If the `source` param is not an object, function returns it as is.
* If whether `predicate` or `objectToInsert` param is not an object,
* or the `predicate` object is empty, function returns the unmodified `source`.
*
* @param source
* @param predicate
* @param objectToInsert
*/
function insertObjectAfter(source, predicate, objectToInsert) {
return insertObject(source, predicate, objectToInsert, false);
}
exports.insertObjectAfter = insertObjectAfter;