Superdiff provides a complete and readable diff for both arrays and objects. Plus, it supports stream and file inputs for handling large datasets efficiently, is battle-tested, has zero dependencies, and is super fast.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

8 lines
3.4 KiB

'use strict';
var i={ADDED:"added",EQUAL:"equal",MOVED:"moved",DELETED:"deleted",UPDATED:"updated"};function a(e,t,n={discardArrayOrder:!1}){return typeof e!=typeof t?!1:Array.isArray(e)?e.length!==t.length?!1:n.discardArrayOrder?e.every(r=>t.some(f=>JSON.stringify(f)===JSON.stringify(r))):e.every((r,f)=>JSON.stringify(r)===JSON.stringify(t[f])):typeof e=="object"?JSON.stringify(e)===JSON.stringify(t):e===t}function d(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}function A(e){return e.some(t=>t.status!==i.EQUAL)?i.UPDATED:i.EQUAL}function l(e,t){if(!e)return {type:"object",status:i.isEqual,diff:[]};let n=[];return Object.entries(e).forEach(([r,f])=>{if(d(f)){let u=[];return Object.entries(f).forEach(([s,o])=>{u.push({name:s,previousValue:t===i.ADDED?void 0:o,currentValue:t===i.ADDED?o:void 0,status:t});}),n.push({property:r,previousValue:t===i.ADDED?void 0:e[r],currentValue:t===i.ADDED?f:void 0,status:t,subPropertiesDiff:u})}return n.push({property:r,previousValue:t===i.ADDED?void 0:e[r],currentValue:t===i.ADDED?f:void 0,status:t})}),{type:"object",status:t,diff:n}}function S(e,t,n){if(!e)return;let r=Object.entries(e).find(([f])=>a(f,t,n));return r?r[1]:void 0}function E(e,t,n){return a(e,t,n)?i.EQUAL:i.UPDATED}function j(e){return e.some(t=>t.status!==i.EQUAL)?i.UPDATED:i.EQUAL}function y(e,t){if(!e)return;let n=Object.keys(e),r=Object.keys(t),f=n.filter(u=>!r.includes(u));if(f.length>0)return f.map(u=>({property:u,value:e[u]}))}function O(e,t,n){let r=[],f,u=y(e,t);return u&&u.forEach(s=>{r.push({name:s.property,previousValue:s.value,currentValue:void 0,status:i.DELETED});}),Object.entries(t).forEach(([s,o])=>{let D=S(e,s,n);if(!D&&!!s)return r.push({name:s,previousValue:void 0,currentValue:o,status:i.ADDED});if(d(o)){let c=O(D,o,n);c&&c.length>0&&(f=c);}D&&r.push({name:s,previousValue:D,currentValue:o,status:E(D,o,n),...!!f&&{subDiff:f}});}),r}function g(e,t,n){if(!e&&!t)return {type:"object",status:i.EQUAL,diff:[]};if(!e)return l(t,i.ADDED);if(!t)return l(e,i.DELETED);let r=[];Object.entries(t).forEach(([u,s])=>{let o=e[u];if(!o)return r.push({property:u,previousValue:void 0,currentValue:s,status:i.ADDED});if(d(s)){let D=O(o,s,n);return r.push({property:u,previousValue:o,currentValue:s,status:j(D),subPropertiesDiff:D})}return r.push({property:u,previousValue:o,currentValue:s,status:E(o,s,n)})});let f=y(e,t);return f&&f.forEach(u=>{r.push({property:u.property,previousValue:u.value,currentValue:void 0,status:i.DELETED});}),{type:"object",status:A(r),diff:r}}function b(e,t){return {type:"list",status:t,diff:e.map((n,r)=>({value:n,prevIndex:t===i.ADDED?null:r,newIndex:t===i.ADDED?r:null,indexDiff:null,status:t}))}}function m(e){return e.some(t=>t.status!==i.EQUAL)?i.UPDATED:i.EQUAL}var L=(e,t)=>{if(!e&&!t)return {type:"list",status:i.EQUAL,diff:[]};if(!e)return b(t,i.ADDED);if(!t)return b(e,i.DELETED);let n=[];return t.forEach((r,f)=>{let u=e.findIndex(o=>a(o,r)),s=u===-1?null:f-u;return s===0?n.push({value:r,prevIndex:u,newIndex:f,indexDiff:s,status:i.EQUAL}):u===-1?n.push({value:r,prevIndex:null,newIndex:f,indexDiff:s,status:i.ADDED}):n.push({value:r,prevIndex:u,newIndex:f,indexDiff:s,status:i.MOVED})}),e.forEach((r,f)=>{if(!t.some(u=>a(u,r)))return n.splice(f,0,{value:r,prevIndex:f,newIndex:null,indexDiff:null,status:i.DELETED})}),{type:"list",status:m(n),diff:n}};
exports.getListDiff = L;
exports.getObjectDiff = g;
exports.isEqual = a;
exports.isObject = d;