UNPKG

@toolsycc/json-diff

Version:

A lightweight utility to compare, intersect or subtract JSON objects deeply.

85 lines (84 loc) 2.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.diffJson = diffJson; exports.intersectJson = intersectJson; exports.subtractJson = subtractJson; exports.isObject = isObject; exports.isEqual = isEqual; function diffJson(a, b) { const added = {}; const removed = {}; const changed = {}; const keys = new Set([...Object.keys(a || {}), ...Object.keys(b || {})]); for (const key of keys) { const valA = a?.[key]; const valB = b?.[key]; if (!(key in a)) { added[key] = valB; } else if (!(key in b)) { removed[key] = valA; } else if (isObject(valA) && isObject(valB)) { const sub = diffJson(valA, valB); if (Object.keys(sub.added).length || Object.keys(sub.removed).length || Object.keys(sub.changed).length) { changed[key] = [valA, valB]; } } else if (!isEqual(valA, valB)) { changed[key] = [valA, valB]; } } return { added, removed, changed }; } function intersectJson(a, b) { if (!isObject(a) || !isObject(b)) return undefined; const result = {}; for (const key in a) { if (key in b) { const valA = a[key]; const valB = b[key]; if (isObject(valA) && isObject(valB)) { const sub = intersectJson(valA, valB); if (sub && Object.keys(sub).length) result[key] = sub; } else if (isEqual(valA, valB)) { result[key] = valA; } } } return result; } function subtractJson(a, b) { if (!isObject(a)) return a; if (!isObject(b)) return a; const result = {}; for (const key in a) { if (!(key in b)) { result[key] = a[key]; } else { const valA = a[key]; const valB = b[key]; if (isObject(valA) && isObject(valB)) { const sub = subtractJson(valA, valB); if (Object.keys(sub).length > 0) result[key] = sub; } else if (!isEqual(valA, valB)) { result[key] = valA; } } } return result; } function isObject(value) { return typeof value === 'object' && value !== null && !Array.isArray(value); } function isEqual(a, b) { return JSON.stringify(a) === JSON.stringify(b); }