Browse Source

feat: resolve conflicts

pull/19/head
Máté Szentgróti 10 months ago
parent
commit
8988f3575d
  1. 7
      dist/index.d.mts
  2. 7
      dist/index.d.ts
  3. 9
      dist/index.js
  4. 4
      dist/index.mjs
  5. 5
      src/utils.ts
  6. 82
      test/object-diff.test.ts
  7. 2
      test/utils.test.ts

7
dist/index.d.mts vendored

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
declare const STATUS: Record<string, ObjectDiffStatus>;
declare const LIST_STATUS: Record<string, ListDiffStatus>;
declare const GRANULARITY: Record<string, "basic" | "deep">;
type ListDiffStatus = "added" | "equal" | "moved" | "deleted" | "updated";
type ObjectDiffStatus = "added" | "equal" | "deleted" | "updated";
@ -89,7 +91,8 @@ declare const getListDiff: <T>(prevList: T[] | null | undefined, nextList: T[] | @@ -89,7 +91,8 @@ declare const getListDiff: <T>(prevList: T[] | null | undefined, nextList: T[] |
/**
* Returns true if two data are equal
* @param {any} a - The original data.
* @param {any} b- The data to compare.
* @param {any} b - The data to compare.
* @param {isEqualOptions} options - The options to compare the data.
* @returns boolean
*/
declare function isEqual(a: any, b: any, options?: isEqualOptions): boolean;
@ -100,4 +103,4 @@ declare function isEqual(a: any, b: any, options?: isEqualOptions): boolean; @@ -100,4 +103,4 @@ declare function isEqual(a: any, b: any, options?: isEqualOptions): boolean;
*/
declare function isObject(value: any): value is Record<string, any>;
export { type DataDiff, type ListData, type ListDiff, type ListDiffStatus, type ListOptions, type ListStatusTuple, type ObjectData, type ObjectDiff, type ObjectDiffStatus, type ObjectOptions, type ObjectStatusTuple, type SubProperties, getListDiff, getObjectDiff, isEqual, type isEqualOptions, isObject };
export { type DataDiff, GRANULARITY, LIST_STATUS, type ListData, type ListDiff, type ListDiffStatus, type ListOptions, type ListStatusTuple, type ObjectData, type ObjectDiff, type ObjectDiffStatus, type ObjectOptions, type ObjectStatusTuple, STATUS, type SubProperties, getListDiff, getObjectDiff, isEqual, type isEqualOptions, isObject };

7
dist/index.d.ts vendored

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
declare const STATUS: Record<string, ObjectDiffStatus>;
declare const LIST_STATUS: Record<string, ListDiffStatus>;
declare const GRANULARITY: Record<string, "basic" | "deep">;
type ListDiffStatus = "added" | "equal" | "moved" | "deleted" | "updated";
type ObjectDiffStatus = "added" | "equal" | "deleted" | "updated";
@ -89,7 +91,8 @@ declare const getListDiff: <T>(prevList: T[] | null | undefined, nextList: T[] | @@ -89,7 +91,8 @@ declare const getListDiff: <T>(prevList: T[] | null | undefined, nextList: T[] |
/**
* Returns true if two data are equal
* @param {any} a - The original data.
* @param {any} b- The data to compare.
* @param {any} b - The data to compare.
* @param {isEqualOptions} options - The options to compare the data.
* @returns boolean
*/
declare function isEqual(a: any, b: any, options?: isEqualOptions): boolean;
@ -100,4 +103,4 @@ declare function isEqual(a: any, b: any, options?: isEqualOptions): boolean; @@ -100,4 +103,4 @@ declare function isEqual(a: any, b: any, options?: isEqualOptions): boolean;
*/
declare function isObject(value: any): value is Record<string, any>;
export { type DataDiff, type ListData, type ListDiff, type ListDiffStatus, type ListOptions, type ListStatusTuple, type ObjectData, type ObjectDiff, type ObjectDiffStatus, type ObjectOptions, type ObjectStatusTuple, type SubProperties, getListDiff, getObjectDiff, isEqual, type isEqualOptions, isObject };
export { type DataDiff, GRANULARITY, LIST_STATUS, type ListData, type ListDiff, type ListDiffStatus, type ListOptions, type ListStatusTuple, type ObjectData, type ObjectDiff, type ObjectDiffStatus, type ObjectOptions, type ObjectStatusTuple, STATUS, type SubProperties, getListDiff, getObjectDiff, isEqual, type isEqualOptions, isObject };

9
dist/index.js vendored

@ -1,8 +1,11 @@ @@ -1,8 +1,11 @@
'use strict';
var u={ADDED:"added",EQUAL:"equal",DELETED:"deleted",UPDATED:"updated"},d={...u,MOVED:"moved"},y={BASIC:"basic",DEEP:"deep"};function p(e,t,i={ignoreArrayOrder:!1}){return typeof e!=typeof t?!1:Array.isArray(e)?e.length!==t.length?!1:i.ignoreArrayOrder?e.every(f=>t.some(s=>JSON.stringify(s)===JSON.stringify(f))):e.every((f,s)=>JSON.stringify(f)===JSON.stringify(t[s])):typeof e=="object"?JSON.stringify(e)===JSON.stringify(t):e===t}function D(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}function O(e,t={statuses:[],granularity:y.BASIC}){let{statuses:i,granularity:f}=t;return e.reduce((s,r)=>{if(f===y.DEEP&&r.subPropertiesDiff){let n=O(r.subPropertiesDiff,t);if(n.length>0)return [...s,{...r,subPropertiesDiff:n}]}if(f===y.DEEP&&r.subDiff){let n=O(r.subDiff,t);if(n.length>0)return [...s,{...r,subDiff:n}]}return i.includes(r.status)?[...s,r]:s},[])}function E(e){return e.some(t=>t.status!==u.EQUAL)?u.UPDATED:u.EQUAL}function A(e,t,i={ignoreArrayOrder:!1,showOnly:{statuses:[],granularity:y.BASIC}}){if(!e)return {type:"object",status:u.EQUAL,diff:[]};let f=[];return Object.entries(e).forEach(([s,r])=>{if(D(r)){let n=[];return Object.entries(r).forEach(([o,c])=>{n.push({property:o,previousValue:t===u.ADDED?void 0:c,currentValue:t===u.ADDED?c:void 0,status:t});}),f.push({property:s,previousValue:t===u.ADDED?void 0:e[s],currentValue:t===u.ADDED?r:void 0,status:t,subPropertiesDiff:n})}return f.push({property:s,previousValue:t===u.ADDED?void 0:e[s],currentValue:t===u.ADDED?r:void 0,status:t})}),i.showOnly&&i.showOnly.statuses.length>0?{type:"object",status:t,diff:O(f,i.showOnly)}:{type:"object",status:t,diff:f}}function P(e,t,i){if(!e)return;let f=Object.entries(e).find(([s])=>p(s,t,i));return f?f[1]:void 0}function j(e,t,i){return p(e,t,i)?u.EQUAL:u.UPDATED}function U(e){return e.some(t=>t.status!==u.EQUAL)?u.UPDATED:u.EQUAL}function S(e,t){if(!e)return;let i=Object.keys(e),f=Object.keys(t),s=i.filter(r=>!f.includes(r));if(s.length>0)return s.map(r=>({property:r,value:e[r]}))}function g(e,t,i){let f=[],s,r=S(e,t);return r&&r.forEach(n=>{f.push({property:n.property,previousValue:n.value,currentValue:void 0,status:u.DELETED});}),Object.entries(t).forEach(([n,o])=>{let c=P(e,n,i);if(!c)return f.push({property:n,previousValue:c,currentValue:o,status:!e||!(n in e)?u.ADDED:c===o?u.EQUAL:u.UPDATED});if(D(o)){let a=g(c,o,i);a&&a.length>0&&(s=a);}c&&f.push({property:n,previousValue:c,currentValue:o,status:j(c,o,i),...!!s&&{subDiff:s}});}),f}function m(e,t,i={ignoreArrayOrder:!1,showOnly:{statuses:[],granularity:y.BASIC}}){if(!e&&!t)return {type:"object",status:u.EQUAL,diff:[]};if(!e)return A(t,u.ADDED,i);if(!t)return A(e,u.DELETED,i);let f=[];Object.entries(t).forEach(([r,n])=>{let o=e[r];if(!o)return f.push({property:r,previousValue:o,currentValue:n,status:r in e?o===n?u.EQUAL:u.UPDATED:u.ADDED});if(D(n)){let c=g(o,n,i),a=U(c);return f.push({property:r,previousValue:o,currentValue:n,status:a,...a!==u.EQUAL&&{subPropertiesDiff:c}})}return f.push({property:r,previousValue:o,currentValue:n,status:j(o,n,i)})});let s=S(e,t);return s&&s.forEach(r=>{f.push({property:r.property,previousValue:r.value,currentValue:void 0,status:u.DELETED});}),i.showOnly&&i.showOnly.statuses.length>0?{type:"object",status:E(f),diff:O(f,i.showOnly)}:{type:"object",status:E(f),diff:f}}function w(e,t=[]){return e.filter(i=>t?.includes(i.status))}function L(e,t,i={showOnly:[]}){let f=e.map((s,r)=>({value:s,prevIndex:t===d.ADDED?null:r,newIndex:t===d.ADDED?r:null,indexDiff:null,status:t}));return i.showOnly&&i.showOnly.length>0?{type:"list",status:t,diff:f.filter(s=>i.showOnly?.includes(s.status))}:{type:"list",status:t,diff:f}}function h(e){return e.some(t=>t.status!==d.EQUAL)?d.UPDATED:d.EQUAL}function T(e,t){return D(e)&&t?Object.hasOwn(e,t):!1}var I=(e,t,i={showOnly:[],referenceProperty:void 0,considerMoveAsUpdate:!1})=>{if(!e&&!t)return {type:"list",status:d.EQUAL,diff:[]};if(!e)return L(t,d.ADDED,i);if(!t)return L(e,d.DELETED,i);let f=[],s=[];return t.forEach((r,n)=>{let o=e.findIndex((a,b)=>T(a,i.referenceProperty)?D(r)?p(a[i.referenceProperty],r[i.referenceProperty])&&!s.includes(b):!1:p(a,r)&&!s.includes(b));o>-1&&s.push(o);let c=o===-1?null:n-o;if(c===0){let a=d.EQUAL;return T(r,i.referenceProperty)&&(p(e[o],r)||(a=d.UPDATED)),f.push({value:r,prevIndex:o,newIndex:n,indexDiff:c,status:a})}return o===-1?f.push({value:r,prevIndex:null,newIndex:n,indexDiff:c,status:d.ADDED}):f.push({value:r,prevIndex:o,newIndex:n,indexDiff:c,status:i.considerMoveAsUpdate?d.UPDATED:d.MOVED})}),e.forEach((r,n)=>{if(!s.includes(n))return f.splice(n,0,{value:r,prevIndex:n,newIndex:null,indexDiff:null,status:d.DELETED})}),i.showOnly&&i?.showOnly?.length>0?{type:"list",status:h(f),diff:w(f,i.showOnly)}:{type:"list",status:h(f),diff:f}};
var u={ADDED:"added",EQUAL:"equal",DELETED:"deleted",UPDATED:"updated"},d={...u,MOVED:"moved"},y={BASIC:"basic",DEEP:"deep"};function D(e,t,i={ignoreArrayOrder:!1}){return typeof e!=typeof t?!1:Array.isArray(e)&&Array.isArray(t)?e.length!==t.length?!1:i.ignoreArrayOrder?e.every(f=>t.some(n=>JSON.stringify(n)===JSON.stringify(f))):e.every((f,n)=>JSON.stringify(f)===JSON.stringify(t[n])):typeof e=="object"?JSON.stringify(e)===JSON.stringify(t):e===t}function p(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}function O(e,t={statuses:[],granularity:y.BASIC}){let{statuses:i,granularity:f}=t;return e.reduce((n,r)=>{if(f===y.DEEP&&r.subPropertiesDiff){let s=O(r.subPropertiesDiff,t);if(s.length>0)return [...n,{...r,subPropertiesDiff:s}]}if(f===y.DEEP&&r.subDiff){let s=O(r.subDiff,t);if(s.length>0)return [...n,{...r,subDiff:s}]}return i.includes(r.status)?[...n,r]:n},[])}function E(e){return e.some(t=>t.status!==u.EQUAL)?u.UPDATED:u.EQUAL}function A(e,t,i={ignoreArrayOrder:!1,showOnly:{statuses:[],granularity:y.BASIC}}){if(!e)return {type:"object",status:u.EQUAL,diff:[]};let f=[];return Object.entries(e).forEach(([n,r])=>{if(p(r)){let s=[];return Object.entries(r).forEach(([o,c])=>{s.push({property:o,previousValue:t===u.ADDED?void 0:c,currentValue:t===u.ADDED?c:void 0,status:t});}),f.push({property:n,previousValue:t===u.ADDED?void 0:e[n],currentValue:t===u.ADDED?r:void 0,status:t,subPropertiesDiff:s})}return f.push({property:n,previousValue:t===u.ADDED?void 0:e[n],currentValue:t===u.ADDED?r:void 0,status:t})}),i.showOnly&&i.showOnly.statuses.length>0?{type:"object",status:t,diff:O(f,i.showOnly)}:{type:"object",status:t,diff:f}}function P(e,t,i){if(!e)return;let f=Object.entries(e).find(([n])=>D(n,t,i));return f?f[1]:void 0}function j(e,t,i){return D(e,t,i)?u.EQUAL:u.UPDATED}function U(e){return e.some(t=>t.status!==u.EQUAL)?u.UPDATED:u.EQUAL}function g(e,t){if(!e)return;let i=Object.keys(e),f=Object.keys(t),n=i.filter(r=>!f.includes(r));if(n.length>0)return n.map(r=>({property:r,value:e[r]}))}function S(e,t,i){let f=[],n,r=g(e,t);return r&&r.forEach(s=>{f.push({property:s.property,previousValue:s.value,currentValue:void 0,status:u.DELETED});}),Object.entries(t).forEach(([s,o])=>{let c=P(e,s,i);if(!c)return f.push({property:s,previousValue:c,currentValue:o,status:!e||!(s in e)?u.ADDED:c===o?u.EQUAL:u.UPDATED});if(p(o)){let a=S(c,o,i);a&&a.length>0&&(n=a);}c&&f.push({property:s,previousValue:c,currentValue:o,status:j(c,o,i),...!!n&&{subDiff:n}});}),f}function m(e,t,i={ignoreArrayOrder:!1,showOnly:{statuses:[],granularity:y.BASIC}}){if(!e&&!t)return {type:"object",status:u.EQUAL,diff:[]};if(!e)return A(t,u.ADDED,i);if(!t)return A(e,u.DELETED,i);let f=[];Object.entries(t).forEach(([r,s])=>{let o=e[r];if(!o)return f.push({property:r,previousValue:o,currentValue:s,status:r in e?o===s?u.EQUAL:u.UPDATED:u.ADDED});if(p(s)){let c=S(o,s,i),a=U(c);return f.push({property:r,previousValue:o,currentValue:s,status:a,...a!==u.EQUAL&&{subPropertiesDiff:c}})}return f.push({property:r,previousValue:o,currentValue:s,status:j(o,s,i)})});let n=g(e,t);return n&&n.forEach(r=>{f.push({property:r.property,previousValue:r.value,currentValue:void 0,status:u.DELETED});}),i.showOnly&&i.showOnly.statuses.length>0?{type:"object",status:E(f),diff:O(f,i.showOnly)}:{type:"object",status:E(f),diff:f}}function w(e,t=[]){return e.filter(i=>t?.includes(i.status))}function h(e,t,i={showOnly:[]}){let f=e.map((n,r)=>({value:n,prevIndex:t===d.ADDED?null:r,newIndex:t===d.ADDED?r:null,indexDiff:null,status:t}));return i.showOnly&&i.showOnly.length>0?{type:"list",status:t,diff:f.filter(n=>i.showOnly?.includes(n.status))}:{type:"list",status:t,diff:f}}function L(e){return e.some(t=>t.status!==d.EQUAL)?d.UPDATED:d.EQUAL}function T(e,t){return p(e)&&t?Object.hasOwn(e,t):!1}var I=(e,t,i={showOnly:[],referenceProperty:void 0,considerMoveAsUpdate:!1})=>{if(!e&&!t)return {type:"list",status:d.EQUAL,diff:[]};if(!e)return h(t,d.ADDED,i);if(!t)return h(e,d.DELETED,i);let f=[],n=[];return t.forEach((r,s)=>{let o=e.findIndex((a,b)=>T(a,i.referenceProperty)?p(r)?D(a[i.referenceProperty],r[i.referenceProperty])&&!n.includes(b):!1:D(a,r)&&!n.includes(b));o>-1&&n.push(o);let c=o===-1?null:s-o;if(c===0){let a=d.EQUAL;return T(r,i.referenceProperty)&&(D(e[o],r)||(a=d.UPDATED)),f.push({value:r,prevIndex:o,newIndex:s,indexDiff:c,status:a})}return o===-1?f.push({value:r,prevIndex:null,newIndex:s,indexDiff:c,status:d.ADDED}):f.push({value:r,prevIndex:o,newIndex:s,indexDiff:c,status:i.considerMoveAsUpdate?d.UPDATED:d.MOVED})}),e.forEach((r,s)=>{if(!n.includes(s))return f.splice(s,0,{value:r,prevIndex:s,newIndex:null,indexDiff:null,status:d.DELETED})}),i.showOnly&&i?.showOnly?.length>0?{type:"list",status:L(f),diff:w(f,i.showOnly)}:{type:"list",status:L(f),diff:f}};
exports.GRANULARITY = y;
exports.LIST_STATUS = d;
exports.STATUS = u;
exports.getListDiff = I;
exports.getObjectDiff = m;
exports.isEqual = p;
exports.isObject = D;
exports.isEqual = D;
exports.isObject = p;

4
dist/index.mjs vendored

@ -1,3 +1,3 @@ @@ -1,3 +1,3 @@
var u={ADDED:"added",EQUAL:"equal",DELETED:"deleted",UPDATED:"updated"},d={...u,MOVED:"moved"},y={BASIC:"basic",DEEP:"deep"};function p(e,t,i={ignoreArrayOrder:!1}){return typeof e!=typeof t?!1:Array.isArray(e)?e.length!==t.length?!1:i.ignoreArrayOrder?e.every(f=>t.some(s=>JSON.stringify(s)===JSON.stringify(f))):e.every((f,s)=>JSON.stringify(f)===JSON.stringify(t[s])):typeof e=="object"?JSON.stringify(e)===JSON.stringify(t):e===t}function D(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}function b(e,t={statuses:[],granularity:y.BASIC}){let{statuses:i,granularity:f}=t;return e.reduce((s,r)=>{if(f===y.DEEP&&r.subPropertiesDiff){let n=b(r.subPropertiesDiff,t);if(n.length>0)return [...s,{...r,subPropertiesDiff:n}]}if(f===y.DEEP&&r.subDiff){let n=b(r.subDiff,t);if(n.length>0)return [...s,{...r,subDiff:n}]}return i.includes(r.status)?[...s,r]:s},[])}function A(e){return e.some(t=>t.status!==u.EQUAL)?u.UPDATED:u.EQUAL}function j(e,t,i={ignoreArrayOrder:!1,showOnly:{statuses:[],granularity:y.BASIC}}){if(!e)return {type:"object",status:u.EQUAL,diff:[]};let f=[];return Object.entries(e).forEach(([s,r])=>{if(D(r)){let n=[];return Object.entries(r).forEach(([o,c])=>{n.push({property:o,previousValue:t===u.ADDED?void 0:c,currentValue:t===u.ADDED?c:void 0,status:t});}),f.push({property:s,previousValue:t===u.ADDED?void 0:e[s],currentValue:t===u.ADDED?r:void 0,status:t,subPropertiesDiff:n})}return f.push({property:s,previousValue:t===u.ADDED?void 0:e[s],currentValue:t===u.ADDED?r:void 0,status:t})}),i.showOnly&&i.showOnly.statuses.length>0?{type:"object",status:t,diff:b(f,i.showOnly)}:{type:"object",status:t,diff:f}}function U(e,t,i){if(!e)return;let f=Object.entries(e).find(([s])=>p(s,t,i));return f?f[1]:void 0}function S(e,t,i){return p(e,t,i)?u.EQUAL:u.UPDATED}function m(e){return e.some(t=>t.status!==u.EQUAL)?u.UPDATED:u.EQUAL}function g(e,t){if(!e)return;let i=Object.keys(e),f=Object.keys(t),s=i.filter(r=>!f.includes(r));if(s.length>0)return s.map(r=>({property:r,value:e[r]}))}function L(e,t,i){let f=[],s,r=g(e,t);return r&&r.forEach(n=>{f.push({property:n.property,previousValue:n.value,currentValue:void 0,status:u.DELETED});}),Object.entries(t).forEach(([n,o])=>{let c=U(e,n,i);if(!c)return f.push({property:n,previousValue:c,currentValue:o,status:!e||!(n in e)?u.ADDED:c===o?u.EQUAL:u.UPDATED});if(D(o)){let a=L(c,o,i);a&&a.length>0&&(s=a);}c&&f.push({property:n,previousValue:c,currentValue:o,status:S(c,o,i),...!!s&&{subDiff:s}});}),f}function w(e,t,i={ignoreArrayOrder:!1,showOnly:{statuses:[],granularity:y.BASIC}}){if(!e&&!t)return {type:"object",status:u.EQUAL,diff:[]};if(!e)return j(t,u.ADDED,i);if(!t)return j(e,u.DELETED,i);let f=[];Object.entries(t).forEach(([r,n])=>{let o=e[r];if(!o)return f.push({property:r,previousValue:o,currentValue:n,status:r in e?o===n?u.EQUAL:u.UPDATED:u.ADDED});if(D(n)){let c=L(o,n,i),a=m(c);return f.push({property:r,previousValue:o,currentValue:n,status:a,...a!==u.EQUAL&&{subPropertiesDiff:c}})}return f.push({property:r,previousValue:o,currentValue:n,status:S(o,n,i)})});let s=g(e,t);return s&&s.forEach(r=>{f.push({property:r.property,previousValue:r.value,currentValue:void 0,status:u.DELETED});}),i.showOnly&&i.showOnly.statuses.length>0?{type:"object",status:A(f),diff:b(f,i.showOnly)}:{type:"object",status:A(f),diff:f}}function I(e,t=[]){return e.filter(i=>t?.includes(i.status))}function h(e,t,i={showOnly:[]}){let f=e.map((s,r)=>({value:s,prevIndex:t===d.ADDED?null:r,newIndex:t===d.ADDED?r:null,indexDiff:null,status:t}));return i.showOnly&&i.showOnly.length>0?{type:"list",status:t,diff:f.filter(s=>i.showOnly?.includes(s.status))}:{type:"list",status:t,diff:f}}function T(e){return e.some(t=>t.status!==d.EQUAL)?d.UPDATED:d.EQUAL}function P(e,t){return D(e)&&t?Object.hasOwn(e,t):!1}var R=(e,t,i={showOnly:[],referenceProperty:void 0,considerMoveAsUpdate:!1})=>{if(!e&&!t)return {type:"list",status:d.EQUAL,diff:[]};if(!e)return h(t,d.ADDED,i);if(!t)return h(e,d.DELETED,i);let f=[],s=[];return t.forEach((r,n)=>{let o=e.findIndex((a,E)=>P(a,i.referenceProperty)?D(r)?p(a[i.referenceProperty],r[i.referenceProperty])&&!s.includes(E):!1:p(a,r)&&!s.includes(E));o>-1&&s.push(o);let c=o===-1?null:n-o;if(c===0){let a=d.EQUAL;return P(r,i.referenceProperty)&&(p(e[o],r)||(a=d.UPDATED)),f.push({value:r,prevIndex:o,newIndex:n,indexDiff:c,status:a})}return o===-1?f.push({value:r,prevIndex:null,newIndex:n,indexDiff:c,status:d.ADDED}):f.push({value:r,prevIndex:o,newIndex:n,indexDiff:c,status:i.considerMoveAsUpdate?d.UPDATED:d.MOVED})}),e.forEach((r,n)=>{if(!s.includes(n))return f.splice(n,0,{value:r,prevIndex:n,newIndex:null,indexDiff:null,status:d.DELETED})}),i.showOnly&&i?.showOnly?.length>0?{type:"list",status:T(f),diff:I(f,i.showOnly)}:{type:"list",status:T(f),diff:f}};
var u={ADDED:"added",EQUAL:"equal",DELETED:"deleted",UPDATED:"updated"},d={...u,MOVED:"moved"},y={BASIC:"basic",DEEP:"deep"};function D(e,t,i={ignoreArrayOrder:!1}){return typeof e!=typeof t?!1:Array.isArray(e)&&Array.isArray(t)?e.length!==t.length?!1:i.ignoreArrayOrder?e.every(f=>t.some(n=>JSON.stringify(n)===JSON.stringify(f))):e.every((f,n)=>JSON.stringify(f)===JSON.stringify(t[n])):typeof e=="object"?JSON.stringify(e)===JSON.stringify(t):e===t}function p(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}function b(e,t={statuses:[],granularity:y.BASIC}){let{statuses:i,granularity:f}=t;return e.reduce((n,r)=>{if(f===y.DEEP&&r.subPropertiesDiff){let s=b(r.subPropertiesDiff,t);if(s.length>0)return [...n,{...r,subPropertiesDiff:s}]}if(f===y.DEEP&&r.subDiff){let s=b(r.subDiff,t);if(s.length>0)return [...n,{...r,subDiff:s}]}return i.includes(r.status)?[...n,r]:n},[])}function A(e){return e.some(t=>t.status!==u.EQUAL)?u.UPDATED:u.EQUAL}function j(e,t,i={ignoreArrayOrder:!1,showOnly:{statuses:[],granularity:y.BASIC}}){if(!e)return {type:"object",status:u.EQUAL,diff:[]};let f=[];return Object.entries(e).forEach(([n,r])=>{if(p(r)){let s=[];return Object.entries(r).forEach(([o,c])=>{s.push({property:o,previousValue:t===u.ADDED?void 0:c,currentValue:t===u.ADDED?c:void 0,status:t});}),f.push({property:n,previousValue:t===u.ADDED?void 0:e[n],currentValue:t===u.ADDED?r:void 0,status:t,subPropertiesDiff:s})}return f.push({property:n,previousValue:t===u.ADDED?void 0:e[n],currentValue:t===u.ADDED?r:void 0,status:t})}),i.showOnly&&i.showOnly.statuses.length>0?{type:"object",status:t,diff:b(f,i.showOnly)}:{type:"object",status:t,diff:f}}function U(e,t,i){if(!e)return;let f=Object.entries(e).find(([n])=>D(n,t,i));return f?f[1]:void 0}function g(e,t,i){return D(e,t,i)?u.EQUAL:u.UPDATED}function m(e){return e.some(t=>t.status!==u.EQUAL)?u.UPDATED:u.EQUAL}function S(e,t){if(!e)return;let i=Object.keys(e),f=Object.keys(t),n=i.filter(r=>!f.includes(r));if(n.length>0)return n.map(r=>({property:r,value:e[r]}))}function h(e,t,i){let f=[],n,r=S(e,t);return r&&r.forEach(s=>{f.push({property:s.property,previousValue:s.value,currentValue:void 0,status:u.DELETED});}),Object.entries(t).forEach(([s,o])=>{let c=U(e,s,i);if(!c)return f.push({property:s,previousValue:c,currentValue:o,status:!e||!(s in e)?u.ADDED:c===o?u.EQUAL:u.UPDATED});if(p(o)){let a=h(c,o,i);a&&a.length>0&&(n=a);}c&&f.push({property:s,previousValue:c,currentValue:o,status:g(c,o,i),...!!n&&{subDiff:n}});}),f}function w(e,t,i={ignoreArrayOrder:!1,showOnly:{statuses:[],granularity:y.BASIC}}){if(!e&&!t)return {type:"object",status:u.EQUAL,diff:[]};if(!e)return j(t,u.ADDED,i);if(!t)return j(e,u.DELETED,i);let f=[];Object.entries(t).forEach(([r,s])=>{let o=e[r];if(!o)return f.push({property:r,previousValue:o,currentValue:s,status:r in e?o===s?u.EQUAL:u.UPDATED:u.ADDED});if(p(s)){let c=h(o,s,i),a=m(c);return f.push({property:r,previousValue:o,currentValue:s,status:a,...a!==u.EQUAL&&{subPropertiesDiff:c}})}return f.push({property:r,previousValue:o,currentValue:s,status:g(o,s,i)})});let n=S(e,t);return n&&n.forEach(r=>{f.push({property:r.property,previousValue:r.value,currentValue:void 0,status:u.DELETED});}),i.showOnly&&i.showOnly.statuses.length>0?{type:"object",status:A(f),diff:b(f,i.showOnly)}:{type:"object",status:A(f),diff:f}}function I(e,t=[]){return e.filter(i=>t?.includes(i.status))}function L(e,t,i={showOnly:[]}){let f=e.map((n,r)=>({value:n,prevIndex:t===d.ADDED?null:r,newIndex:t===d.ADDED?r:null,indexDiff:null,status:t}));return i.showOnly&&i.showOnly.length>0?{type:"list",status:t,diff:f.filter(n=>i.showOnly?.includes(n.status))}:{type:"list",status:t,diff:f}}function T(e){return e.some(t=>t.status!==d.EQUAL)?d.UPDATED:d.EQUAL}function P(e,t){return p(e)&&t?Object.hasOwn(e,t):!1}var R=(e,t,i={showOnly:[],referenceProperty:void 0,considerMoveAsUpdate:!1})=>{if(!e&&!t)return {type:"list",status:d.EQUAL,diff:[]};if(!e)return L(t,d.ADDED,i);if(!t)return L(e,d.DELETED,i);let f=[],n=[];return t.forEach((r,s)=>{let o=e.findIndex((a,E)=>P(a,i.referenceProperty)?p(r)?D(a[i.referenceProperty],r[i.referenceProperty])&&!n.includes(E):!1:D(a,r)&&!n.includes(E));o>-1&&n.push(o);let c=o===-1?null:s-o;if(c===0){let a=d.EQUAL;return P(r,i.referenceProperty)&&(D(e[o],r)||(a=d.UPDATED)),f.push({value:r,prevIndex:o,newIndex:s,indexDiff:c,status:a})}return o===-1?f.push({value:r,prevIndex:null,newIndex:s,indexDiff:c,status:d.ADDED}):f.push({value:r,prevIndex:o,newIndex:s,indexDiff:c,status:i.considerMoveAsUpdate?d.UPDATED:d.MOVED})}),e.forEach((r,s)=>{if(!n.includes(s))return f.splice(s,0,{value:r,prevIndex:s,newIndex:null,indexDiff:null,status:d.DELETED})}),i.showOnly&&i?.showOnly?.length>0?{type:"list",status:T(f),diff:I(f,i.showOnly)}:{type:"list",status:T(f),diff:f}};
export { R as getListDiff, w as getObjectDiff, p as isEqual, D as isObject };
export { y as GRANULARITY, d as LIST_STATUS, u as STATUS, R as getListDiff, w as getObjectDiff, D as isEqual, p as isObject };

5
src/utils.ts

@ -3,7 +3,8 @@ import { isEqualOptions } from "./model"; @@ -3,7 +3,8 @@ import { isEqualOptions } from "./model";
/**
* Returns true if two data are equal
* @param {any} a - The original data.
* @param {any} b- The data to compare.
* @param {any} b - The data to compare.
* @param {isEqualOptions} options - The options to compare the data.
* @returns boolean
*/
export function isEqual(
@ -12,7 +13,7 @@ export function isEqual( @@ -12,7 +13,7 @@ export function isEqual(
options: isEqualOptions = { ignoreArrayOrder: false }
): boolean {
if (typeof a !== typeof b) return false;
if (Array.isArray(a)) {
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length) {
return false;
}

82
test/object-diff.test.ts

@ -858,4 +858,86 @@ describe("getObjectDiff", () => { @@ -858,4 +858,86 @@ describe("getObjectDiff", () => {
],
});
});
it("detects changes when comparing an array value property to a non-array value property", () => {
expect(
getObjectDiff(
{
name: "joe",
age: 55,
hobbies: ["golf", "football"]
},
{
name: "joe",
age: 55,
hobbies: null
}))
.toStrictEqual({
type: "object",
status: "updated",
diff: [
{
currentValue: "joe",
previousValue: "joe",
property: "name",
status: "equal",
},
{
currentValue: 55,
previousValue: 55,
property: "age",
status: "equal",
},
{
currentValue: null,
previousValue: [
"golf",
"football",
],
property: "hobbies",
status: "updated",
}
]
})
})
it("detects changes when comparing a non-array value property to an array value property", () => {
expect(
getObjectDiff(
{
name: "joe",
age: 55,
hobbies: null
},
{
name: "joe",
age: 55,
hobbies: ["golf", "football"]
}))
.toStrictEqual({
type: "object",
status: "updated",
diff: [
{
currentValue: "joe",
previousValue: "joe",
property: "name",
status: "equal",
},
{
currentValue: 55,
previousValue: 55,
property: "age",
status: "equal",
},
{
currentValue: [
"golf",
"football",
],
previousValue: null,
property: "hobbies",
status: "updated",
}
]
})
});
});

2
test/utils.test.ts

@ -39,6 +39,8 @@ describe("isEqual", () => { @@ -39,6 +39,8 @@ describe("isEqual", () => {
)
).toBeFalsy();
expect(isEqual(["psg"], ["psg", "nantes"])).toBeFalsy();
expect(isEqual(null, ["hello", "world"])).toBeFalsy();
expect(isEqual(["hello", "world"], null)).toBeFalsy();
});
it("return true if ignoreArrayOrder option is activated and arrays contains the same values regardless of their positions", () => {
expect(

Loading…
Cancel
Save