import { debugBase } from './debuggers' ; import Logs from './models/Logs' ; param oldArray param newArray returns todo const compareArrays = ( oldArray = [ ] , newArray = [ ] ) => { const changedItems = [ ] ; const unchangedItems = [ ] ; const addedItems = [ ] ; let removedItems = [ ] ; if ( oldArray . length > 0 && newArray . length === 0 ) { removedItems = oldArray ; } for ( const elem of oldArray ) { if ( typeof elem !== 'object' ) { const found = newArray . find ( el => el === elem ) ; /**
             * If removedItems contains the pushing value, then it caused the following error
             * FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
             */ if ( ! found && elem && ! removedItems . includes ( elem ) ) { removedItems . push ( elem ) ; } } } newArray . forEach ( ( elem , index ) => { if ( typeof elem !== 'object' ) { const found = oldArray . find ( el => el === elem ) ; if ( found ) { unchangedItems . push ( elem ) ; } if ( ! found && elem ) { addedItems . push ( elem ) ; } } if ( typeof elem === 'object' ) { const comparison = compareObjects ( oldArray [ index ] , newArray [ index ] ) ; const { unchanged , changed , added , removed } = comparison ; if ( changed && ! isObjectEmpty ( changed ) ) { changedItems . push ( changed ) ; } if ( added && ! isObjectEmpty ( added ) ) { addedItems . push ( added ) ; } if ( removed && ! isObjectEmpty ( removed ) ) { removedItems . push ( removed ) ; } if ( unchanged && ! isObjectEmpty ( unchanged ) ) { unchangedItems . push ( unchanged ) ; } } } ) ; return { unchanged : unchangedItems , changed : changedItems , added : addedItems , removed : removedItems , } ; } ; param val const isNull = val => val === null || val === undefined || val === '' ; param obj const isObjectEmpty = obj => { return typeof obj === 'object' && obj && Object . keys ( obj ) . length === 0 && obj . constructor === Object ; } ; param { Object } obj returns { Object } const flattenObject = ( obj = { } ) => { const flatObject = { ... obj } ; const names = obj ? Object . getOwnPropertyNames ( obj ) : [ ] ; for ( const name of names ) { const attr = obj [ name ] ; let empty = false ; if ( typeof attr !== 'object' ) { if ( isNull ( attr ) ) { empty = true ; } } if ( Array . isArray ( attr ) && attr . length === 0 ) { empty = true ; } if ( typeof attr === 'object' && ! Array . isArray ( attr ) ) { if ( isObjectEmpty ( attr ) ) { empty = true ; } } if ( empty ) { delete flatObject [ name ] ; } } return flatObject ; } ; param oldData param newData returns export const compareObjects = ( oldData = { } , newData = { } ) => { const changedFields = { } ; const unchangedFields = { } ; const addedFields = { } ; const removedFields = { } ; const nonSchemaNames = [ 'uid' , 'length' ] ; let fieldNames = [ ] ; if ( newData && ! isObjectEmpty ( newData ) ) { fieldNames = Object . getOwnPropertyNames ( newData ) ; fieldNames = fieldNames . map < string > ( n => { if ( ! nonSchemaNames . includes ( n ) ) { return n ; } } ) ; } for ( const name of fieldNames ) { const oldField = oldData [ name ] ; const newField = newData [ name ] ; if ( typeof newField !== 'object' ) { if ( oldField !== newField ) { changedFields [ name ] = newField ; if ( ! isNull ( oldField ) && isNull ( newField ) ) { removedFields [ name ] = oldField ; } if ( isNull ( oldField ) && ! isNull ( newField ) ) { addedFields [ name ] = newField ; } } if ( oldField === newField ) { unchangedFields [ name ] = newField ; } } if ( Array . isArray ( newField ) ) { const comparison = compareArrays ( oldField , newField ) ; const { changed , unchanged , added , removed } = comparison ; if ( changed . length > 0 ) { changedFields [ name ] = changed ; } if ( added . length > 0 ) { addedFields [ name ] = added ; } if ( removed . length > 0 ) { removedFields [ name ] = removed ; } if ( unchanged . length > 0 ) { unchangedFields [ name ] = unchanged ; } } if ( typeof newField === 'object' && ! Array . isArray ( newField ) ) { if ( newField && oldField ) { const comparison = compareObjects ( oldField , newField ) ; const { changed , added , removed , unchanged } = comparison ; if ( ! isObjectEmpty ( changed ) ) { changedFields [ name ] = flattenObject ( changed ) ; } if ( ! isObjectEmpty ( added ) ) { addedFields [ name ] = flattenObject ( added ) ; } if ( ! isObjectEmpty ( removed ) ) { removedFields [ name ] = flattenObject ( removed ) ; } if ( ! isObjectEmpty ( unchanged ) ) { unchangedFields [ name ] = flattenObject ( unchanged ) ; } } if ( ! oldField && newField ) { addedFields [ name ] = newField ; } if ( oldField && ! newField ) { removedFields [ name ] = oldField ; } } } return { changed : changedFields , unchanged : unchangedFields , added : addedFields , removed : removedFields , } ; } ; export const receivePutLogCommand = async ( params ) => { debugBase ( params ) ; const { createdBy , type , action , unicode , description , object , newData , extraDesc } = params ; return Logs . createLog ( { createdBy , type , action , object , newData , unicode , createdAt : new Date ( ) , description , extraDesc , } ) ; } ;