123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import { transform, isEqual, isObject, get } from 'lodash'
- type Dict = {
- [key: string]: boolean | Dict
- }
- export function diff(newObject: any = {}, oldObject: any = {}, ignore?: Dict) {
- const currentIgnoreList = ignore
- ? Object.entries(ignore).reduce(
- (accumulator, [key, value]) =>
- typeof value === 'boolean' ? [...accumulator, key] : accumulator,
- [] as string[]
- )
- : []
- const transformResult = transform(
- newObject,
- (result: any, value: any, key: string) => {
- if (!currentIgnoreList.includes(key) && !isEqual(value, oldObject[key])) {
- const child = ignore && ignore[key]
- let childIgnoreList
- if (result instanceof Array) {
- childIgnoreList = ignore
- } else if (typeof child !== 'boolean') {
- childIgnoreList = child
- } else {
- childIgnoreList = undefined
- }
- const newValue =
- isObject(value) && isObject(oldObject[key])
- ? diff(value, oldObject[key], childIgnoreList)
- : value
- if (newValue !== undefined && newValue !== null) result[key] = newValue
- }
- }
- )
- return Object.keys(transformResult).length > 0 ? transformResult : undefined
- }
- export function deepDiff(
- newObject: any = {},
- oldObject: any = {},
- ignore?: Dict
- ) {
- return {
- added: diff(newObject, oldObject, ignore),
- removed: diff(oldObject, newObject, ignore)
- }
- }
- interface IcompareOptions<T> {
- compareKeys: (keyof T)[]
- diffIgnore?: Dict
- keyNames?: {
- inA: string
- inB: string
- }
- }
- export function compare<T>(
- objectsA: T[],
- objectsB: T[],
- compareOptions: IcompareOptions<T>
- ) {
- const { keyNames, diffIgnore, compareKeys } = compareOptions
- const { inA, inB } = keyNames || { inA: 'inFile', inB: 'inDb' }
- let copyB = [...objectsB]
- let copyA: T[] = []
- for (let objectA of objectsA) {
- const idxObjectB = copyB.findIndex(objectB =>
- compareKeys.reduce((accumulator, value) => {
- console.log(get)
- return accumulator && get(objectA, value, 1) === get(objectB, value, 2)
- }, true as boolean)
- )
- const objectB = copyB[idxObjectB]
- copyB = [...copyB.slice(0, idxObjectB), ...copyB.slice(idxObjectB + 1)]
- copyA = [
- ...copyA,
- {
- ...objectA,
- changes: deepDiff(objectA, objectB, diffIgnore),
- [inA]: true,
- [inB]: !!objectB
- }
- ]
- }
- for (let objectB of copyB) {
- copyA = [
- ...copyA,
- {
- ...objectB,
- changes: deepDiff(undefined, objectB, diffIgnore),
- [inA]: false,
- [inB]: true
- }
- ]
- }
- return copyA
- }
|