5 changed files with 69 additions and 620 deletions
@ -1,314 +1,8 @@
@@ -1,314 +1,8 @@
|
||||
'use strict'; |
||||
|
||||
// src/model.ts
|
||||
var STATUS = { |
||||
ADDED: "added", |
||||
EQUAL: "equal", |
||||
MOVED: "moved", |
||||
DELETED: "deleted", |
||||
UPDATED: "updated" |
||||
}; |
||||
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}}; |
||||
|
||||
// src/utils.ts
|
||||
function isEqual(a, b, options = { discardArrayOrder: false }) { |
||||
if (typeof a !== typeof b) |
||||
return false; |
||||
if (Array.isArray(a)) { |
||||
if (a.length !== b.length) { |
||||
return false; |
||||
} |
||||
if (options.discardArrayOrder) { |
||||
return a.every( |
||||
(v) => b.some((nextV) => JSON.stringify(nextV) === JSON.stringify(v)) |
||||
); |
||||
} |
||||
return a.every((v, i) => JSON.stringify(v) === JSON.stringify(b[i])); |
||||
} |
||||
if (typeof a === "object") { |
||||
return JSON.stringify(a) === JSON.stringify(b); |
||||
} |
||||
return a === b; |
||||
} |
||||
function isObject(value) { |
||||
return !!value && typeof value === "object" && !Array.isArray(value); |
||||
} |
||||
|
||||
// src/object-diff.ts
|
||||
function getObjectStatus(diff) { |
||||
return diff.some((property) => property.status !== STATUS.EQUAL) ? STATUS.UPDATED : STATUS.EQUAL; |
||||
} |
||||
function formatSingleObjectDiff(data, status) { |
||||
if (!data) { |
||||
return { |
||||
type: "object", |
||||
status: STATUS.isEqual, |
||||
diff: [] |
||||
}; |
||||
} |
||||
const diff = []; |
||||
Object.entries(data).forEach(([property, value]) => { |
||||
if (isObject(value)) { |
||||
const subPropertiesDiff = []; |
||||
Object.entries(value).forEach(([subProperty, subValue]) => { |
||||
subPropertiesDiff.push({ |
||||
name: subProperty, |
||||
previousValue: status === STATUS.ADDED ? void 0 : subValue, |
||||
currentValue: status === STATUS.ADDED ? subValue : void 0, |
||||
status |
||||
}); |
||||
}); |
||||
return diff.push({ |
||||
property, |
||||
previousValue: status === STATUS.ADDED ? void 0 : data[property], |
||||
currentValue: status === STATUS.ADDED ? value : void 0, |
||||
status, |
||||
subPropertiesDiff |
||||
}); |
||||
} |
||||
return diff.push({ |
||||
property, |
||||
previousValue: status === STATUS.ADDED ? void 0 : data[property], |
||||
currentValue: status === STATUS.ADDED ? value : void 0, |
||||
status |
||||
}); |
||||
}); |
||||
return { |
||||
type: "object", |
||||
status, |
||||
diff |
||||
}; |
||||
} |
||||
function getPreviousMatch(previousValue, nextSubProperty, options) { |
||||
if (!previousValue) { |
||||
return void 0; |
||||
} |
||||
const previousMatch = Object.entries(previousValue).find( |
||||
([subPreviousKey]) => isEqual(subPreviousKey, nextSubProperty, options) |
||||
); |
||||
return previousMatch ? previousMatch[1] : void 0; |
||||
} |
||||
function getValueStatus(previousValue, nextValue, options) { |
||||
if (isEqual(previousValue, nextValue, options)) { |
||||
return STATUS.EQUAL; |
||||
} |
||||
return STATUS.UPDATED; |
||||
} |
||||
function getPropertyStatus(subPropertiesDiff) { |
||||
return subPropertiesDiff.some((property) => property.status !== STATUS.EQUAL) ? STATUS.UPDATED : STATUS.EQUAL; |
||||
} |
||||
function getDeletedProperties(previousValue, nextValue) { |
||||
if (!previousValue) |
||||
return void 0; |
||||
const prevKeys = Object.keys(previousValue); |
||||
const nextKeys = Object.keys(nextValue); |
||||
const deletedKeys = prevKeys.filter((prevKey) => !nextKeys.includes(prevKey)); |
||||
if (deletedKeys.length > 0) { |
||||
return deletedKeys.map((deletedKey) => ({ |
||||
property: deletedKey, |
||||
value: previousValue[deletedKey] |
||||
})); |
||||
} |
||||
return void 0; |
||||
} |
||||
function getSubPropertiesDiff(previousValue, nextValue, options) { |
||||
const subPropertiesDiff = []; |
||||
let subDiff; |
||||
const deletedMainSubProperties = getDeletedProperties( |
||||
previousValue, |
||||
nextValue |
||||
); |
||||
if (deletedMainSubProperties) { |
||||
deletedMainSubProperties.forEach((deletedProperty) => { |
||||
subPropertiesDiff.push({ |
||||
name: deletedProperty.property, |
||||
previousValue: deletedProperty.value, |
||||
currentValue: void 0, |
||||
status: STATUS.DELETED |
||||
}); |
||||
}); |
||||
} |
||||
Object.entries(nextValue).forEach(([nextSubProperty, nextSubValue]) => { |
||||
const previousMatch = getPreviousMatch( |
||||
previousValue, |
||||
nextSubProperty, |
||||
options |
||||
); |
||||
if (!!!previousMatch && !!nextSubProperty) { |
||||
return subPropertiesDiff.push({ |
||||
name: nextSubProperty, |
||||
previousValue: void 0, |
||||
currentValue: nextSubValue, |
||||
status: STATUS.ADDED |
||||
}); |
||||
} |
||||
if (isObject(nextSubValue)) { |
||||
const data = getSubPropertiesDiff( |
||||
previousMatch, |
||||
nextSubValue, |
||||
options |
||||
); |
||||
if (data && data.length > 0) { |
||||
subDiff = data; |
||||
} |
||||
} |
||||
if (previousMatch) { |
||||
subPropertiesDiff.push({ |
||||
name: nextSubProperty, |
||||
previousValue: previousMatch, |
||||
currentValue: nextSubValue, |
||||
status: getValueStatus(previousMatch, nextSubValue, options), |
||||
...!!subDiff && { subDiff } |
||||
}); |
||||
} |
||||
}); |
||||
return subPropertiesDiff; |
||||
} |
||||
function getObjectDiff(prevData, nextData, options) { |
||||
if (!prevData && !nextData) { |
||||
return { |
||||
type: "object", |
||||
status: STATUS.EQUAL, |
||||
diff: [] |
||||
}; |
||||
} |
||||
if (!prevData) { |
||||
return formatSingleObjectDiff(nextData, STATUS.ADDED); |
||||
} |
||||
if (!nextData) { |
||||
return formatSingleObjectDiff(prevData, STATUS.DELETED); |
||||
} |
||||
const diff = []; |
||||
Object.entries(nextData).forEach(([nextProperty, nextValue]) => { |
||||
const previousValue = prevData[nextProperty]; |
||||
if (!!!previousValue) { |
||||
return diff.push({ |
||||
property: nextProperty, |
||||
previousValue: void 0, |
||||
currentValue: nextValue, |
||||
status: STATUS.ADDED |
||||
}); |
||||
} |
||||
if (isObject(nextValue)) { |
||||
const subPropertiesDiff = getSubPropertiesDiff( |
||||
previousValue, |
||||
nextValue, |
||||
options |
||||
); |
||||
return diff.push({ |
||||
property: nextProperty, |
||||
previousValue, |
||||
currentValue: nextValue, |
||||
status: getPropertyStatus(subPropertiesDiff), |
||||
subPropertiesDiff |
||||
}); |
||||
} |
||||
return diff.push({ |
||||
property: nextProperty, |
||||
previousValue, |
||||
currentValue: nextValue, |
||||
status: getValueStatus(previousValue, nextValue, options) |
||||
}); |
||||
}); |
||||
const deletedProperties = getDeletedProperties(prevData, nextData); |
||||
if (deletedProperties) { |
||||
deletedProperties.forEach((deletedProperty) => { |
||||
diff.push({ |
||||
property: deletedProperty.property, |
||||
previousValue: deletedProperty.value, |
||||
currentValue: void 0, |
||||
status: STATUS.DELETED |
||||
}); |
||||
}); |
||||
} |
||||
return { |
||||
type: "object", |
||||
status: getObjectStatus(diff), |
||||
diff |
||||
}; |
||||
} |
||||
|
||||
// src/list-diff.ts
|
||||
function formatSingleListDiff(listData, status) { |
||||
return { |
||||
type: "list", |
||||
status, |
||||
diff: listData.map((data, i) => ({ |
||||
value: data, |
||||
prevIndex: status === STATUS.ADDED ? null : i, |
||||
newIndex: status === STATUS.ADDED ? i : null, |
||||
indexDiff: null, |
||||
status |
||||
})) |
||||
}; |
||||
} |
||||
function getListStatus(listDiff) { |
||||
return listDiff.some((value) => value.status !== STATUS.EQUAL) ? STATUS.UPDATED : STATUS.EQUAL; |
||||
} |
||||
var getListDiff = (prevList, nextList) => { |
||||
if (!prevList && !nextList) { |
||||
return { |
||||
type: "list", |
||||
status: STATUS.EQUAL, |
||||
diff: [] |
||||
}; |
||||
} |
||||
if (!prevList) { |
||||
return formatSingleListDiff(nextList, STATUS.ADDED); |
||||
} |
||||
if (!nextList) { |
||||
return formatSingleListDiff(prevList, STATUS.DELETED); |
||||
} |
||||
const diff = []; |
||||
nextList.forEach((nextValue, i) => { |
||||
const prevIndex = prevList.findIndex( |
||||
(prevValue) => isEqual(prevValue, nextValue) |
||||
); |
||||
const indexDiff = prevIndex === -1 ? null : i - prevIndex; |
||||
if (indexDiff === 0) { |
||||
return diff.push({ |
||||
value: nextValue, |
||||
prevIndex, |
||||
newIndex: i, |
||||
indexDiff, |
||||
status: STATUS.EQUAL |
||||
}); |
||||
} |
||||
if (prevIndex === -1) { |
||||
return diff.push({ |
||||
value: nextValue, |
||||
prevIndex: null, |
||||
newIndex: i, |
||||
indexDiff, |
||||
status: STATUS.ADDED |
||||
}); |
||||
} |
||||
return diff.push({ |
||||
value: nextValue, |
||||
prevIndex, |
||||
newIndex: i, |
||||
indexDiff, |
||||
status: STATUS.MOVED |
||||
}); |
||||
}); |
||||
prevList.forEach((prevValue, i) => { |
||||
if (!nextList.some((nextValue) => isEqual(nextValue, prevValue))) { |
||||
return diff.splice(i, 0, { |
||||
value: prevValue, |
||||
prevIndex: i, |
||||
newIndex: null, |
||||
indexDiff: null, |
||||
status: STATUS.DELETED |
||||
}); |
||||
} |
||||
}); |
||||
return { |
||||
type: "list", |
||||
status: getListStatus(diff), |
||||
diff |
||||
}; |
||||
}; |
||||
|
||||
exports.getListDiff = getListDiff; |
||||
exports.getObjectDiff = getObjectDiff; |
||||
exports.isEqual = isEqual; |
||||
exports.isObject = isObject; |
||||
exports.getListDiff = L; |
||||
exports.getObjectDiff = g; |
||||
exports.isEqual = a; |
||||
exports.isObject = d; |
||||
|
@ -1,309 +1,3 @@
@@ -1,309 +1,3 @@
|
||||
// src/model.ts
|
||||
var STATUS = { |
||||
ADDED: "added", |
||||
EQUAL: "equal", |
||||
MOVED: "moved", |
||||
DELETED: "deleted", |
||||
UPDATED: "updated" |
||||
}; |
||||
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 S(e){return e.some(t=>t.status!==i.EQUAL)?i.UPDATED:i.EQUAL}function E(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 j(e,t,n){if(!e)return;let r=Object.entries(e).find(([f])=>a(f,t,n));return r?r[1]:void 0}function y(e,t,n){return a(e,t,n)?i.EQUAL:i.UPDATED}function g(e){return e.some(t=>t.status!==i.EQUAL)?i.UPDATED:i.EQUAL}function O(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 b(e,t,n){let r=[],f,u=O(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=j(e,s,n);if(!D&&!!s)return r.push({name:s,previousValue:void 0,currentValue:o,status:i.ADDED});if(d(o)){let l=b(D,o,n);l&&l.length>0&&(f=l);}D&&r.push({name:s,previousValue:D,currentValue:o,status:y(D,o,n),...!!f&&{subDiff:f}});}),r}function m(e,t,n){if(!e&&!t)return {type:"object",status:i.EQUAL,diff:[]};if(!e)return E(t,i.ADDED);if(!t)return E(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=b(o,s,n);return r.push({property:u,previousValue:o,currentValue:s,status:g(D),subPropertiesDiff:D})}return r.push({property:u,previousValue:o,currentValue:s,status:y(o,s,n)})});let f=O(e,t);return f&&f.forEach(u=>{r.push({property:u.property,previousValue:u.value,currentValue:void 0,status:i.DELETED});}),{type:"object",status:S(r),diff:r}}function A(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 L(e){return e.some(t=>t.status!==i.EQUAL)?i.UPDATED:i.EQUAL}var h=(e,t)=>{if(!e&&!t)return {type:"list",status:i.EQUAL,diff:[]};if(!e)return A(t,i.ADDED);if(!t)return A(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:L(n),diff:n}}; |
||||
|
||||
// src/utils.ts
|
||||
function isEqual(a, b, options = { discardArrayOrder: false }) { |
||||
if (typeof a !== typeof b) |
||||
return false; |
||||
if (Array.isArray(a)) { |
||||
if (a.length !== b.length) { |
||||
return false; |
||||
} |
||||
if (options.discardArrayOrder) { |
||||
return a.every( |
||||
(v) => b.some((nextV) => JSON.stringify(nextV) === JSON.stringify(v)) |
||||
); |
||||
} |
||||
return a.every((v, i) => JSON.stringify(v) === JSON.stringify(b[i])); |
||||
} |
||||
if (typeof a === "object") { |
||||
return JSON.stringify(a) === JSON.stringify(b); |
||||
} |
||||
return a === b; |
||||
} |
||||
function isObject(value) { |
||||
return !!value && typeof value === "object" && !Array.isArray(value); |
||||
} |
||||
|
||||
// src/object-diff.ts
|
||||
function getObjectStatus(diff) { |
||||
return diff.some((property) => property.status !== STATUS.EQUAL) ? STATUS.UPDATED : STATUS.EQUAL; |
||||
} |
||||
function formatSingleObjectDiff(data, status) { |
||||
if (!data) { |
||||
return { |
||||
type: "object", |
||||
status: STATUS.isEqual, |
||||
diff: [] |
||||
}; |
||||
} |
||||
const diff = []; |
||||
Object.entries(data).forEach(([property, value]) => { |
||||
if (isObject(value)) { |
||||
const subPropertiesDiff = []; |
||||
Object.entries(value).forEach(([subProperty, subValue]) => { |
||||
subPropertiesDiff.push({ |
||||
name: subProperty, |
||||
previousValue: status === STATUS.ADDED ? void 0 : subValue, |
||||
currentValue: status === STATUS.ADDED ? subValue : void 0, |
||||
status |
||||
}); |
||||
}); |
||||
return diff.push({ |
||||
property, |
||||
previousValue: status === STATUS.ADDED ? void 0 : data[property], |
||||
currentValue: status === STATUS.ADDED ? value : void 0, |
||||
status, |
||||
subPropertiesDiff |
||||
}); |
||||
} |
||||
return diff.push({ |
||||
property, |
||||
previousValue: status === STATUS.ADDED ? void 0 : data[property], |
||||
currentValue: status === STATUS.ADDED ? value : void 0, |
||||
status |
||||
}); |
||||
}); |
||||
return { |
||||
type: "object", |
||||
status, |
||||
diff |
||||
}; |
||||
} |
||||
function getPreviousMatch(previousValue, nextSubProperty, options) { |
||||
if (!previousValue) { |
||||
return void 0; |
||||
} |
||||
const previousMatch = Object.entries(previousValue).find( |
||||
([subPreviousKey]) => isEqual(subPreviousKey, nextSubProperty, options) |
||||
); |
||||
return previousMatch ? previousMatch[1] : void 0; |
||||
} |
||||
function getValueStatus(previousValue, nextValue, options) { |
||||
if (isEqual(previousValue, nextValue, options)) { |
||||
return STATUS.EQUAL; |
||||
} |
||||
return STATUS.UPDATED; |
||||
} |
||||
function getPropertyStatus(subPropertiesDiff) { |
||||
return subPropertiesDiff.some((property) => property.status !== STATUS.EQUAL) ? STATUS.UPDATED : STATUS.EQUAL; |
||||
} |
||||
function getDeletedProperties(previousValue, nextValue) { |
||||
if (!previousValue) |
||||
return void 0; |
||||
const prevKeys = Object.keys(previousValue); |
||||
const nextKeys = Object.keys(nextValue); |
||||
const deletedKeys = prevKeys.filter((prevKey) => !nextKeys.includes(prevKey)); |
||||
if (deletedKeys.length > 0) { |
||||
return deletedKeys.map((deletedKey) => ({ |
||||
property: deletedKey, |
||||
value: previousValue[deletedKey] |
||||
})); |
||||
} |
||||
return void 0; |
||||
} |
||||
function getSubPropertiesDiff(previousValue, nextValue, options) { |
||||
const subPropertiesDiff = []; |
||||
let subDiff; |
||||
const deletedMainSubProperties = getDeletedProperties( |
||||
previousValue, |
||||
nextValue |
||||
); |
||||
if (deletedMainSubProperties) { |
||||
deletedMainSubProperties.forEach((deletedProperty) => { |
||||
subPropertiesDiff.push({ |
||||
name: deletedProperty.property, |
||||
previousValue: deletedProperty.value, |
||||
currentValue: void 0, |
||||
status: STATUS.DELETED |
||||
}); |
||||
}); |
||||
} |
||||
Object.entries(nextValue).forEach(([nextSubProperty, nextSubValue]) => { |
||||
const previousMatch = getPreviousMatch( |
||||
previousValue, |
||||
nextSubProperty, |
||||
options |
||||
); |
||||
if (!!!previousMatch && !!nextSubProperty) { |
||||
return subPropertiesDiff.push({ |
||||
name: nextSubProperty, |
||||
previousValue: void 0, |
||||
currentValue: nextSubValue, |
||||
status: STATUS.ADDED |
||||
}); |
||||
} |
||||
if (isObject(nextSubValue)) { |
||||
const data = getSubPropertiesDiff( |
||||
previousMatch, |
||||
nextSubValue, |
||||
options |
||||
); |
||||
if (data && data.length > 0) { |
||||
subDiff = data; |
||||
} |
||||
} |
||||
if (previousMatch) { |
||||
subPropertiesDiff.push({ |
||||
name: nextSubProperty, |
||||
previousValue: previousMatch, |
||||
currentValue: nextSubValue, |
||||
status: getValueStatus(previousMatch, nextSubValue, options), |
||||
...!!subDiff && { subDiff } |
||||
}); |
||||
} |
||||
}); |
||||
return subPropertiesDiff; |
||||
} |
||||
function getObjectDiff(prevData, nextData, options) { |
||||
if (!prevData && !nextData) { |
||||
return { |
||||
type: "object", |
||||
status: STATUS.EQUAL, |
||||
diff: [] |
||||
}; |
||||
} |
||||
if (!prevData) { |
||||
return formatSingleObjectDiff(nextData, STATUS.ADDED); |
||||
} |
||||
if (!nextData) { |
||||
return formatSingleObjectDiff(prevData, STATUS.DELETED); |
||||
} |
||||
const diff = []; |
||||
Object.entries(nextData).forEach(([nextProperty, nextValue]) => { |
||||
const previousValue = prevData[nextProperty]; |
||||
if (!!!previousValue) { |
||||
return diff.push({ |
||||
property: nextProperty, |
||||
previousValue: void 0, |
||||
currentValue: nextValue, |
||||
status: STATUS.ADDED |
||||
}); |
||||
} |
||||
if (isObject(nextValue)) { |
||||
const subPropertiesDiff = getSubPropertiesDiff( |
||||
previousValue, |
||||
nextValue, |
||||
options |
||||
); |
||||
return diff.push({ |
||||
property: nextProperty, |
||||
previousValue, |
||||
currentValue: nextValue, |
||||
status: getPropertyStatus(subPropertiesDiff), |
||||
subPropertiesDiff |
||||
}); |
||||
} |
||||
return diff.push({ |
||||
property: nextProperty, |
||||
previousValue, |
||||
currentValue: nextValue, |
||||
status: getValueStatus(previousValue, nextValue, options) |
||||
}); |
||||
}); |
||||
const deletedProperties = getDeletedProperties(prevData, nextData); |
||||
if (deletedProperties) { |
||||
deletedProperties.forEach((deletedProperty) => { |
||||
diff.push({ |
||||
property: deletedProperty.property, |
||||
previousValue: deletedProperty.value, |
||||
currentValue: void 0, |
||||
status: STATUS.DELETED |
||||
}); |
||||
}); |
||||
} |
||||
return { |
||||
type: "object", |
||||
status: getObjectStatus(diff), |
||||
diff |
||||
}; |
||||
} |
||||
|
||||
// src/list-diff.ts
|
||||
function formatSingleListDiff(listData, status) { |
||||
return { |
||||
type: "list", |
||||
status, |
||||
diff: listData.map((data, i) => ({ |
||||
value: data, |
||||
prevIndex: status === STATUS.ADDED ? null : i, |
||||
newIndex: status === STATUS.ADDED ? i : null, |
||||
indexDiff: null, |
||||
status |
||||
})) |
||||
}; |
||||
} |
||||
function getListStatus(listDiff) { |
||||
return listDiff.some((value) => value.status !== STATUS.EQUAL) ? STATUS.UPDATED : STATUS.EQUAL; |
||||
} |
||||
var getListDiff = (prevList, nextList) => { |
||||
if (!prevList && !nextList) { |
||||
return { |
||||
type: "list", |
||||
status: STATUS.EQUAL, |
||||
diff: [] |
||||
}; |
||||
} |
||||
if (!prevList) { |
||||
return formatSingleListDiff(nextList, STATUS.ADDED); |
||||
} |
||||
if (!nextList) { |
||||
return formatSingleListDiff(prevList, STATUS.DELETED); |
||||
} |
||||
const diff = []; |
||||
nextList.forEach((nextValue, i) => { |
||||
const prevIndex = prevList.findIndex( |
||||
(prevValue) => isEqual(prevValue, nextValue) |
||||
); |
||||
const indexDiff = prevIndex === -1 ? null : i - prevIndex; |
||||
if (indexDiff === 0) { |
||||
return diff.push({ |
||||
value: nextValue, |
||||
prevIndex, |
||||
newIndex: i, |
||||
indexDiff, |
||||
status: STATUS.EQUAL |
||||
}); |
||||
} |
||||
if (prevIndex === -1) { |
||||
return diff.push({ |
||||
value: nextValue, |
||||
prevIndex: null, |
||||
newIndex: i, |
||||
indexDiff, |
||||
status: STATUS.ADDED |
||||
}); |
||||
} |
||||
return diff.push({ |
||||
value: nextValue, |
||||
prevIndex, |
||||
newIndex: i, |
||||
indexDiff, |
||||
status: STATUS.MOVED |
||||
}); |
||||
}); |
||||
prevList.forEach((prevValue, i) => { |
||||
if (!nextList.some((nextValue) => isEqual(nextValue, prevValue))) { |
||||
return diff.splice(i, 0, { |
||||
value: prevValue, |
||||
prevIndex: i, |
||||
newIndex: null, |
||||
indexDiff: null, |
||||
status: STATUS.DELETED |
||||
}); |
||||
} |
||||
}); |
||||
return { |
||||
type: "list", |
||||
status: getListStatus(diff), |
||||
diff |
||||
}; |
||||
}; |
||||
|
||||
export { getListDiff, getObjectDiff, isEqual, isObject }; |
||||
export { h as getListDiff, m as getObjectDiff, a as isEqual, d as isObject }; |
||||
|
Loading…
Reference in new issue