UNPKG

datum-merge

Version:

Simplified diff and merging for deeply nested objects

115 lines (114 loc) 3.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.deepDiffTyped = deepDiffTyped; exports.antiDiffTyped = antiDiffTyped; exports.deepDiffLow = deepDiffLow; exports.deepDiffFlat = deepDiffFlat; exports.flattenObject = flattenObject; exports.unflattenObject = unflattenObject; const type_utils_1 = require("./type-utils"); const deep_diff_1 = require("./diff-lib/deep-diff"); function deepDiffTyped(lhsObj, rhsObj, orderInd = false) { if ((0, type_utils_1.emptyObject)(rhsObj)) { return {}; } if ((0, type_utils_1.emptyObject)(lhsObj)) { return Object.assign({}, rhsObj); } const differences = deepDiffLow(lhsObj, rhsObj, orderInd); const deltaObj = {}; if (!differences) { return deltaObj; } for (const difference of differences) { (0, deep_diff_1.applyChange)(deltaObj, undefined, difference); } cleanupObjArrays(deltaObj); return deltaObj; } ; function cleanupObjArrays(obj) { var _a; for (const objKey of Object.keys(obj)) { if ((_a = obj[objKey]) === null || _a === void 0 ? void 0 : _a.filter) { obj[objKey] = obj[objKey].filter((e) => !!e); } } } function antiDiffTyped(lhsObj, rhsObj, orderInd = false) { if ((0, type_utils_1.emptyObject)(lhsObj) || (0, type_utils_1.emptyObject)(rhsObj)) { return {}; } const differences = deepDiffLow(lhsObj, rhsObj, orderInd); if (!differences) { return Object.assign({}, lhsObj); } const modFields = new Set(); differences.map((d) => d === null || d === void 0 ? void 0 : d.path) .filter((p) => !!p && p.length > 0) .map((p) => (p === null || p === void 0 ? void 0 : p[0]).toString()) .forEach((s) => modFields.add(s)); const shareObj = Object.fromEntries(Object.entries(lhsObj) .filter(([k, _]) => !modFields.has(k))); return shareObj; } function deepDiffLow(lhsObj, rhsObj, orderInd = false) { const differences = !orderInd ? (0, deep_diff_1.diff)(lhsObj, rhsObj) : (0, deep_diff_1.orderIndependentDiff)(lhsObj, rhsObj); return !(differences === null || differences === void 0 ? void 0 : differences.length) ? false : differences; } ; function deepDiffFlat(oldFlat, newFlat, flatten = true) { if (flatten) { oldFlat = flattenObject(oldFlat); newFlat = flattenObject(newFlat); } const updated = Object.assign({}, oldFlat); const removed = Object.assign({}, newFlat); for (const key of Object.keys(newFlat)) { if (newFlat[key] === oldFlat[key]) { delete updated[key]; delete removed[key]; } } return [updated, removed]; } function flattenObject(obj) { const flatObj = {}; const path = []; const isObject = (value) => Object(value) === value; function dig(obj) { for (const [key, value] of Object.entries(obj)) { path.push(key); if (isObject(value)) { dig(value); } else { flatObj[path.join('.')] = value; } path.pop(); } } dig(obj); return flatObj; } function unflattenObject(flatObj) { const unflatObj = {}; for (const [path, value] of Object.entries(flatObj)) { const parts = path.split('.'); let obj = unflatObj; for (const [i, key] of parts.slice(0, -1).entries()) { if (!obj[key]) { const needArray = Number.isInteger(Number(parts[+i + 1])); obj[key] = needArray ? [] : {}; } obj = obj[key]; } const lastkey = parts.pop(); obj[lastkey] = value; } return unflatObj; }