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.

4 lines
3.4 KiB

var r={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(i=>t.some(f=>JSON.stringify(f)===JSON.stringify(i))):e.every((i,f)=>JSON.stringify(i)===JSON.stringify(t[f])):typeof e=="object"?JSON.stringify(e)===JSON.stringify(t):e===t}function p(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}function S(e){return e.some(t=>t.status!==r.EQUAL)?r.UPDATED:r.EQUAL}function l(e,t){if(!e)return {type:"object",status:r.isEqual,diff:[]};let n=[];return Object.entries(e).forEach(([i,f])=>{if(p(f)){let s=[];return Object.entries(f).forEach(([u,o])=>{s.push({name:u,previousValue:t===r.ADDED?void 0:o,currentValue:t===r.ADDED?o:void 0,status:t});}),n.push({property:i,previousValue:t===r.ADDED?void 0:e[i],currentValue:t===r.ADDED?f:void 0,status:t,subPropertiesDiff:s})}return n.push({property:i,previousValue:t===r.ADDED?void 0:e[i],currentValue:t===r.ADDED?f:void 0,status:t})}),{type:"object",status:t,diff:n}}function j(e,t,n){if(!e)return;let i=Object.entries(e).find(([f])=>a(f,t,n));return i?i[1]:void 0}function y(e,t,n){return a(e,t,n)?r.EQUAL:r.UPDATED}function g(e){return e.some(t=>t.status!==r.EQUAL)?r.UPDATED:r.EQUAL}function O(e,t){if(!e)return;let n=Object.keys(e),i=Object.keys(t),f=n.filter(s=>!i.includes(s));if(f.length>0)return f.map(s=>({property:s,value:e[s]}))}function b(e,t,n){let i=[],f,s=O(e,t);return s&&s.forEach(u=>{i.push({name:u.property,previousValue:u.value,currentValue:void 0,status:r.DELETED});}),Object.entries(t).forEach(([u,o])=>{let D=j(e,u,n);if(!D)return i.push({name:u,previousValue:D,currentValue:o,status:!e||!(u in e)?r.ADDED:D===o?r.EQUAL:r.UPDATED});if(p(o)){let d=b(D,o,n);d&&d.length>0&&(f=d);}D&&i.push({name:u,previousValue:D,currentValue:o,status:y(D,o,n),...!!f&&{subDiff:f}});}),i}function m(e,t,n){if(!e&&!t)return {type:"object",status:r.EQUAL,diff:[]};if(!e)return l(t,r.ADDED);if(!t)return l(e,r.DELETED);let i=[];Object.entries(t).forEach(([s,u])=>{let o=e[s];if(!o)return i.push({property:s,previousValue:o,currentValue:u,status:s in e?o===u?r.EQUAL:r.UPDATED:r.ADDED});if(p(u)){let D=b(o,u,n),d=g(D);return i.push({property:s,previousValue:o,currentValue:u,status:d,...d!==r.EQUAL&&{subPropertiesDiff:D}})}return i.push({property:s,previousValue:o,currentValue:u,status:y(o,u,n)})});let f=O(e,t);return f&&f.forEach(s=>{i.push({property:s.property,previousValue:s.value,currentValue:void 0,status:r.DELETED});}),{type:"object",status:S(i),diff:i}}function A(e,t){return {type:"list",status:t,diff:e.map((n,i)=>({value:n,prevIndex:t===r.ADDED?null:i,newIndex:t===r.ADDED?i:null,indexDiff:null,status:t}))}}function L(e){return e.some(t=>t.status!==r.EQUAL)?r.UPDATED:r.EQUAL}var h=(e,t)=>{if(!e&&!t)return {type:"list",status:r.EQUAL,diff:[]};if(!e)return A(t,r.ADDED);if(!t)return A(e,r.DELETED);let n=[];return t.forEach((i,f)=>{let s=e.findIndex(o=>a(o,i)),u=s===-1?null:f-s;return u===0?n.push({value:i,prevIndex:s,newIndex:f,indexDiff:u,status:r.EQUAL}):s===-1?n.push({value:i,prevIndex:null,newIndex:f,indexDiff:u,status:r.ADDED}):n.push({value:i,prevIndex:s,newIndex:f,indexDiff:u,status:r.MOVED})}),e.forEach((i,f)=>{if(!t.some(s=>a(s,i)))return n.splice(f,0,{value:i,prevIndex:f,newIndex:null,indexDiff:null,status:r.DELETED})}),{type:"list",status:L(n),diff:n}};
export { h as getListDiff, m as getObjectDiff, a as isEqual, p as isObject };