dbl-utils
Version:
Utilities for dbl, adba and others projects
177 lines (176 loc) • 7.6 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeWithMutation = mergeWithMutation;
exports.deepMerge = deepMerge;
exports.transformJson = transformJson;
let useConfig = {};
/**
* Check if an item is a simple object.
* @param item - The item to check.
* @returns True if the item is an object, false otherwise.
*/
function isObject(item) {
return item && typeof item === 'object' && !Array.isArray(item);
}
/**
* Deeply merge objects into the target object.
* @param target - The target object where to merge.
* @param sources - The sources to be merged into the target.
* @returns The merged target object.
*/
function effectiveDeepMerge(target, ...sources) {
if (!sources.length)
return target;
const source = sources.shift();
let fixValue;
if (typeof useConfig.fix === 'function') {
fixValue = useConfig.fix(target, source);
}
if (fixValue !== undefined)
target = fixValue;
else if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key])
Object.assign(target, { [key]: {} });
effectiveDeepMerge(target[key], source[key]);
}
else if (typeof source[key] !== 'undefined') {
Object.assign(target, { [key]: source[key] });
}
}
}
return effectiveDeepMerge(target, ...sources);
}
/**
* Execute a mutation function on the object and merge results.
* @param target - The target object to be merged with mutation.
* @param options - Options for mutation, ommit keys and additional data.
* @param parentKey - Internal tracking key for recursion.
* @returns The mutated and merged target object.
*/
function mergeWithMutation(target_1, _a) {
return __awaiter(this, arguments, void 0, function* (target, { mutation, ommit = [], data }, parentKey = '') {
for (const key in target) {
if (!ommit.includes(key) && typeof target[key] === 'object') {
const keyFixed = Array.isArray(target) ? parentKey + '.' + key : key;
const mergeResult = yield mutation(keyFixed, target[key], data);
if (mergeResult)
effectiveDeepMerge(target[key], mergeResult);
yield mergeWithMutation(target[key], { mutation, ommit, data }, key);
}
}
return target;
});
}
/**
* Deep merge multiple objects.
* @param target - The target object where other objects will be merged.
* @param sources - Other objects to be merged into the target.
* @returns The merged object.
*/
function deepMerge(target, ...sources) {
const mergedObject = effectiveDeepMerge(target, ...sources);
useConfig = {};
return mergedObject;
}
deepMerge.setConfig = (config) => {
useConfig = config;
};
/**
* Transforms and flattens a JSON object.
*
* @param json - The JSON object to be transformed.
* @param options - Options for the mutation functions.
* @returns An array with the modified object and the flattened object.
*/
function transformJson(json, options = {}) {
const objCopy = JSON.parse(JSON.stringify(json));
const flattenObj = {};
const recursive = (obj, key = null, parentObj = null, parentKey = null, path = '') => {
if (typeof options.beforeFunc === 'function') {
const mutation = options.beforeFunc({ input: obj, key, parentObj, parentKey, path });
if (mutation && typeof mutation === 'object') {
if (mutation.replace)
parentObj[key] = mutation.replace;
else if (mutation.merge)
deepMerge(obj, mutation.merge);
else if (mutation.delete)
delete parentObj[key];
}
}
for (const innerKey in obj) {
const value = obj[innerKey];
const newPath = path ? `${path}.${innerKey}` : innerKey;
if (typeof options.filter === 'string' && innerKey === options.filter) {
flattenObj[newPath] = value;
continue;
}
else if (Array.isArray(options.filter) && options.filter.includes(innerKey)) {
flattenObj[newPath] = value;
continue;
}
else if (typeof options.filter === 'function' &&
!options.filter({ input: value, key: innerKey, parentObj: obj, parentKey: key, path: newPath })) {
flattenObj[newPath] = value;
continue;
}
if (typeof value === 'object' && value !== null) {
if (typeof options.duringFunc === 'function') {
const mutation = options.duringFunc({ input: value, key: innerKey, parentObj: obj, parentKey: key, path: newPath });
if (mutation && typeof mutation === 'object') {
if (mutation.replace)
obj[innerKey] = mutation.replace;
else if (mutation.merge)
obj[innerKey] = deepMerge(value, mutation.merge);
else if (mutation.delete) {
delete obj[innerKey];
continue;
}
}
}
recursive(value, innerKey, obj, key, newPath);
}
else {
if (options.nonObjectFunc) {
const mutation = options.nonObjectFunc({ input: value, key: innerKey, parentObj: obj, parentKey: key, path: newPath });
if (mutation && typeof mutation === 'object') {
if (mutation.replace)
obj[innerKey] = mutation.replace;
else if (mutation.merge)
obj[innerKey] += mutation.merge;
else if (mutation.delete) {
delete obj[innerKey];
continue;
}
}
}
flattenObj[newPath] = value;
}
}
if (typeof options.afterFunc === 'function') {
const mutation = options.afterFunc({ input: obj, key, parentObj, parentKey, path });
if (mutation && typeof mutation === 'object') {
if (mutation.replace)
parentObj[key] = mutation.replace;
else if (mutation.merge)
deepMerge(obj, mutation.merge);
else if (mutation.delete)
delete parentObj[key];
}
}
};
const rootKey = options.key || '_root';
const rootObj = options.root || {};
recursive(objCopy, rootKey, rootObj);
return [objCopy, rootObj[rootKey]];
}