@yolkai/nx-workspace
Version:
88 lines (87 loc) • 2.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var DiffType;
(function (DiffType) {
DiffType[DiffType["Deleted"] = 0] = "Deleted";
DiffType[DiffType["Added"] = 1] = "Added";
DiffType[DiffType["Modified"] = 2] = "Modified";
})(DiffType = exports.DiffType || (exports.DiffType = {}));
function jsonDiff(lhs, rhs) {
const result = [];
const seen = new Set();
walkJsonTree(lhs, [], (path, lhsValue) => {
seen.add(hashArray(path));
if (typeof lhsValue === 'object') {
return true;
}
const rhsValue = getJsonValue(path, rhs);
if (rhsValue === undefined) {
result.push({
type: DiffType.Deleted,
path,
value: {
lhs: lhsValue,
rhs: undefined
}
});
}
else if (lhsValue !== rhsValue) {
result.push({
type: DiffType.Modified,
path,
value: {
lhs: lhsValue,
rhs: rhsValue
}
});
}
return false;
});
walkJsonTree(rhs, [], (path, rhsValue) => {
if (seen.has(hashArray(path))) {
return false;
}
else if (typeof rhsValue === 'object') {
return true;
}
else {
result.push({
type: DiffType.Added,
path,
value: {
lhs: undefined,
rhs: rhsValue
}
});
return false;
}
});
return result;
}
exports.jsonDiff = jsonDiff;
// Depth-first walk down JSON tree.
function walkJsonTree(json, currPath, visitor) {
if (!json || typeof json !== 'object') {
return;
}
Object.keys(json).forEach(key => {
const path = currPath.concat([key]);
const shouldContinue = visitor(path, json[key]);
if (shouldContinue) {
walkJsonTree(json[key], path, visitor);
}
});
}
function hashArray(ary) {
return JSON.stringify(ary);
}
function getJsonValue(path, json) {
let curr = json;
for (const k of path) {
curr = curr[k];
if (curr === undefined) {
break;
}
}
return curr;
}