datum-merge
Version:
Simplified diff and merging for deeply nested objects
87 lines (86 loc) • 3.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.customMergePatch = customMergePatch;
exports.bypassMergePatch = bypassMergePatch;
exports.deepMergeLog = deepMergeLog;
exports.selectPathCode = selectPathCode;
const type_utils_1 = require("./type-utils");
const datum_utils_1 = require("./datum-utils");
const patch_low_1 = require("./patch-low");
const merge_low_1 = require("./merge-low");
const merge_conf_1 = require("./merge-conf");
function customMergePatch(target, source, mergeConf, excludeKeys) {
switch (mergeConf) {
case merge_low_1.UpdateCode.C:
return false;
case merge_low_1.UpdateCode.T:
return [];
case merge_low_1.UpdateCode.N:
return false;
case merge_low_1.UpdateCode.Y:
return bypassMergePatch(target, source);
}
const mergeCodes = (0, merge_conf_1.fillUpdateCodes)(source, mergeConf, false, excludeKeys);
if ((0, type_utils_1.emptyObject)(mergeCodes)) {
return false;
}
const targetBkp = (0, datum_utils_1.deepClone)(target);
const changed = (0, merge_conf_1.detailMerge)(target, source, mergeCodes);
const patch = deepMergeLog(targetBkp, target, mergeCodes);
if (changed || (patch === null || patch === void 0 ? void 0 : patch.length) > 0) {
return patch;
}
return false;
}
function bypassMergePatch(target, source) {
const sourceKeys = (0, datum_utils_1.getObjectKeys)(source !== null && source !== void 0 ? source : {});
if (!source || !sourceKeys.length) {
return false;
}
const mergeCodes = (0, datum_utils_1.createValueKeys)(sourceKeys, merge_low_1.UpdateCode.Y);
const targetBkp = (0, datum_utils_1.deepClone)(target);
Object.assign(target, Object.assign({}, source));
const patch = deepMergeLog(targetBkp, target, mergeCodes);
return !(patch === null || patch === void 0 ? void 0 : patch.length) ? false : patch;
}
function deepMergeLog(lhsObj, rhsObj, mergeCodes) {
const mergeLog = (0, patch_low_1.deepPatchLog)(lhsObj, rhsObj, false, true);
if (!(mergeLog === null || mergeLog === void 0 ? void 0 : mergeLog.length)) {
return [];
}
const opCodeMap = {
"add": merge_low_1.UpdateCode.I,
"replace": merge_low_1.UpdateCode.H,
"remove": merge_low_1.UpdateCode.D,
"test": merge_low_1.UpdateCode.N,
};
for (const patchItem of mergeLog) {
const pathParts = (0, patch_low_1.asLodashPath)(patchItem.path);
patchItem.code = !mergeCodes
? opCodeMap[patchItem.op]
: selectPathCode(mergeCodes, pathParts);
}
return mergeLog;
}
;
function selectPathCode(mergeCodes, pathParts) {
if (!mergeCodes || (0, type_utils_1.emptyObject)(mergeCodes)) {
return merge_low_1.UpdateCode.N;
}
let currConf = mergeCodes;
for (let itr = 0; itr < pathParts.length; itr++) {
const part = pathParts[itr];
const partConf = currConf[part];
if (!partConf) {
return merge_low_1.UpdateCode.N;
}
if ((0, type_utils_1.isString)(partConf)) {
return partConf;
}
if (itr === pathParts.length - 1) {
return merge_low_1.UpdateCode.I;
}
currConf = partConf;
}
return merge_low_1.UpdateCode.N;
}