mongoose-history-diff
Version:
A mongoose plugin to take diffs and history of your documents
216 lines (215 loc) • 7.5 kB
JavaScript
"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;