UNPKG

@shopware-ag/dive

Version:

Shopware Spatial Framework

106 lines (87 loc) 3.35 kB
/** * Find the difference between two objects. */ export const getObjectDelta = <T extends object>( a: T, b: Partial<T>, ): Partial<T> => { // if a and b have no entries we have no delta if (Object.keys(a).length === 0 && Object.keys(b).length === 0) { return {}; } // if a or b is not an object we have a delta if (typeof a !== 'object' || typeof b !== 'object') { return b; } let delta = {}; Object.keys(b).forEach((key) => { // if key is not in a we have a delta if (!Object.keys(a).includes(key)) { delta = { ...delta, [key]: b[key as keyof object] }; return; } // assumption: b[key] is an array if (Array.isArray(b[key as keyof object])) { // if a[key] is not an array we have a delta if (!Array.isArray(a[key as keyof object])) { delta = { ...delta, [key]: b[key as keyof object] }; return; } // create arrays (for TS types to be correct) const aArray = a[key as keyof object] as []; const bArray = b[key as keyof object] as []; // if both arrays are empty we have no delta if (aArray.length === 0 && bArray.length === 0) { delta = { ...delta }; return; } // if array length is different we have a delta if (aArray.length !== bArray.length) { delta = { ...delta, [key]: b[key as keyof object] }; return; } // create array for deltas const arrayDeltas: [] = []; bArray.forEach((entry, index) => { // getObjectDelta in array const inArrayDelta = getObjectDelta( aArray[index], bArray[index], ); // if inArrayDelta has more then 0 entries we have a delta if (Object.keys(inArrayDelta).length) { arrayDeltas.push(bArray[index]); } }); // if arrayDeltas has more than 0 entries we have a delta if (Object.keys(arrayDeltas).length) { delta = { ...delta, [key]: arrayDeltas }; return; } return; } // assumption: b[key] is an object if (typeof b[key as keyof object] === 'object') { // if a[key] is not an object we have a delta if (typeof a[key as keyof object] !== 'object') { delta = { ...delta, [key]: b[key as keyof object] }; return; } // recursive: find objectDelta in a and b const objectDelta = getObjectDelta( a[key as keyof object], b[key as keyof object], ); // if objectDelta has more than 0 entries we have a delta if (Object.keys(objectDelta).length) { delta = { ...delta, [key]: objectDelta }; return; } } // if a[key] is not equal to b[key] we have a delta if (a[key as keyof object] !== b[key as keyof object]) { delta = { ...delta, [key]: b[key as keyof object] }; } }); return delta; };