UNPKG

mongoose-history-diff

Version:

A mongoose plugin to take diffs and history of your documents

216 lines (215 loc) 7.5 kB
"use strict"; 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 }); exports.revertChanges = exports.deepDiff = void 0; var utils_1 = require("./utils"); exports.deepDiff = function (lhs, rhs, changes, opts) { if (changes === void 0) { changes = []; } var _a = opts || {}, path = _a.path, prefilter = _a.prefilter, key = _a.key, orderIndependent = _a.orderIndependent; var stack = (opts || {}).stack; stack = stack || []; var currentPath = path ? __spreadArrays(path) : []; if (key) { if (prefilter && prefilter(currentPath, key)) return; currentPath.push(key); } if (utils_1.realTypeOf(lhs) === 'regexp' && utils_1.realTypeOf(rhs) === 'regexp') { lhs = lhs.toString(); rhs = rhs.toString(); } var i; var j; var other; var ldefined = (!!lhs || stack) && stack.length > 0 && stack[stack.length - 1].lhs && key && !!Object.getOwnPropertyDescriptor(stack[stack.length - 1].lhs, key); var rdefined = (!!rhs || stack) && stack.length > 0 && stack[stack.length - 1].rhs && key && !!Object.getOwnPropertyDescriptor(stack[stack.length - 1].rhs, key); if (!ldefined && rdefined) { changes.push({ k: 'N', p: currentPath, r: rhs }); } else if (!rdefined && ldefined) { changes.push({ k: 'D', p: currentPath, l: lhs }); } else if (utils_1.realTypeOf(lhs) !== utils_1.realTypeOf(rhs)) { changes.push({ k: 'E', p: currentPath, l: lhs, r: rhs, }); } else if (utils_1.realTypeOf(lhs) === 'date' && lhs - rhs !== 0) { changes.push({ k: 'E', p: currentPath, l: lhs, r: rhs, }); } else if (lhs && rhs && typeof lhs === 'object') { for (i = stack.length - 1; i > -1; --i) { if (stack[i].lhs === lhs) { other = true; break; } } if (!other) { stack.push({ lhs: lhs, rhs: rhs }); if (Array.isArray(lhs)) { if (orderIndependent) { lhs.sort(function (a, b) { return utils_1.getOrderIndependentHash(a) - utils_1.getOrderIndependentHash(b); }); rhs.sort(function (a, b) { return utils_1.getOrderIndependentHash(a) - utils_1.getOrderIndependentHash(b); }); } i = rhs.length - 1; j = lhs.length - 1; while (i > j) { changes.push({ k: 'A', p: currentPath, i: i, it: { k: 'N', r: rhs[i--] }, }); } while (j > i) { changes.push({ k: 'A', p: currentPath, i: j, it: { k: 'D', l: lhs[j--] }, }); } while (i >= 0) { exports.deepDiff(lhs[i], rhs[i], changes, { prefilter: prefilter, path: currentPath, key: i.toString(), stack: stack, orderIndependent: orderIndependent, }); --i; } } else { var lhsKeys = Object.keys(lhs); var rhsKeys_1 = Object.keys(rhs); lhsKeys.forEach(function (lhsKey) { other = rhsKeys_1.indexOf(lhsKey); if (other >= 0) { exports.deepDiff(lhs[lhsKey], rhs[lhsKey], changes, { prefilter: prefilter, path: currentPath, key: lhsKey, stack: stack, orderIndependent: orderIndependent, }); rhsKeys_1[other] = ''; } else { exports.deepDiff(lhs[lhsKey], null, changes, { prefilter: prefilter, path: currentPath, key: lhsKey, stack: stack, orderIndependent: orderIndependent, }); } }); rhsKeys_1.forEach(function (rhsKey) { if (rhsKey) { exports.deepDiff(null, rhs[rhsKey], changes, { prefilter: prefilter, path: currentPath, key: rhsKey, stack: stack, orderIndependent: orderIndependent, }); } }); } stack.length -= 1; } else if (lhs !== rhs) { changes.push({ k: 'E', p: currentPath, l: lhs, r: rhs, }); } } else if (lhs !== rhs) { if (!(typeof lhs === 'number' && Number.isNaN(lhs) && Number.isNaN(rhs))) { changes.push({ k: 'E', p: currentPath, l: lhs, r: rhs, }); } } }; exports.revertChanges = function (target, changes) { var copyTarget = utils_1.deepClone(target); changes.forEach(function (change) { var it = copyTarget; var i; for (i = 0; i < change.p.length - 1; i++) { if (typeof it[change.p[i]] === 'undefined') { it[change.p[i]] = {}; } it = it[change.p[i]]; } switch (change.k) { case 'A': if (Array.isArray(it)) { utils_1.revertArrayChange(it, parseInt(change.i, 10), change.it); break; } utils_1.revertArrayChange(it[change.p[i]], parseInt(change.i, 10), change.it); break; case 'D': it[change.p[i]] = change.l; break; case 'E': it[change.p[i]] = change.l; break; case 'N': delete it[change.p[i]]; break; default: it[change.p[i]] = {}; } }); return copyTarget; }; var MHD = (function () { function MHD() { } MHD.findDiff = function (lhs, rhs) { var _this = this; var changes = []; exports.deepDiff(lhs, rhs, changes, { prefilter: function (path, key) { return utils_1.excludeFields(path, key, _this.excludedFields); }, orderIndependent: this.orderIndependent, }); return changes; }; MHD.excludedFields = []; return MHD; }()); exports.default = MHD;