import { isEmpty } from "tedb-utils" ; param obj param is param value param type returns { any } const operate = ( obj , is , value , type ) : any => { if ( typeof is === "string" ) { return operate ( obj , is . split ( "." ) , value , type ) ; } else if ( ( is . length === 1 ) && ( value !== undefined ) ) { switch ( type ) { case "set" : return obj [ is [ 0 ] ] = value ; case "mul" : return obj [ is [ 0 ] ] = obj [ is [ 0 ] ] * value ; case "inc" : return obj [ is [ 0 ] ] = obj [ is [ 0 ] ] + value ; case "unset" : return delete obj [ is [ 0 ] ] ; } } else if ( is . length === 0 ) { return obj ; } else { return operate ( obj [ is [ 0 ] ] , is . slice ( 1 ) , value , type ) ; } } ; param obj param set returns { Promise < T > } export const $set = ( obj , set ) : Promise < any > => { return new Promise ( ( resolve , reject ) => { if ( isEmpty ( set ) ) { return reject ( new Error ( "Empty $set object" ) ) ; } const returnObj = obj ; const setKeys = Object . keys ( set ) ; try { setKeys . forEach ( ( path ) => { operate ( returnObj , path , set [ path ] , "set" ) ; } ) ; resolve ( returnObj ) ; } catch ( e ) { return reject ( e ) ; } } ) ; } ; param obj param mul returns { Promise < T > } export const $mul = ( obj , mul ) : Promise < any > => { return new Promise ( ( resolve , reject ) => { if ( isEmpty ( mul ) ) { return reject ( new Error ( "Empty $mul object" ) ) ; } const returnObj = obj ; const mulKeys = Object . keys ( mul ) ; try { mulKeys . forEach ( ( path ) => operate ( returnObj , path , mul [ path ] , "mul" ) ) ; resolve ( returnObj ) ; } catch ( e ) { return reject ( e ) ; } } ) ; } ; param obj param inc returns { Promise < T > } export const $inc = ( obj , inc ) : Promise < any > => { return new Promise ( ( resolve , reject ) => { if ( isEmpty ( inc ) ) { return reject ( new Error ( "Empty $inc object" ) ) ; } const returnObj = obj ; const incKeys = Object . keys ( inc ) ; try { incKeys . forEach ( ( path ) => operate ( returnObj , path , inc [ path ] , "inc" ) ) ; resolve ( returnObj ) ; } catch ( e ) { return reject ( e ) ; } } ) ; } ; param obj param unset returns { Promise < T > } export const $unset = ( obj , unset ) : Promise < any > => { return new Promise ( ( resolve , reject ) => { if ( isEmpty ( unset ) ) { return reject ( new Error ( "Empty $unset object" ) ) ; } const returnObj = obj ; const unsetKeys = Object . keys ( unset ) ; try { unsetKeys . forEach ( ( path ) => operate ( returnObj , path , unset [ path ] , "unset" ) ) ; resolve ( returnObj ) ; } catch ( e ) { return reject ( e ) ; } } ) ; } ; param obj param rename returns { Promise < T > } export const $rename = ( obj , rename ) : Promise < any > => { return new Promise ( ( resolve , reject ) => { if ( isEmpty ( rename ) ) { return reject ( new Error ( "Empty $rename object" ) ) ; } const returnObj = obj ; const renameKeys = Object . keys ( rename ) ; try { renameKeys . forEach ( ( path ) => { let keyValue ; const del = ( thisObject , is , value ) : any => { if ( typeof is === "string" ) { return del ( thisObject , is . split ( "." ) , value ) ; } else if ( ( is . length === 1 ) && ( value !== undefined ) ) { keyValue = thisObject [ is [ 0 ] ] ; return delete thisObject [ is [ 0 ] ] ; } else if ( is . length === 0 ) { return thisObject ; } else { return del ( thisObject [ is [ 0 ] ] , is . slice ( 1 ) , value ) ; } } ; del ( returnObj , path , rename [ path ] ) ; if ( keyValue ) { const splitPath = path . split ( "." ) ; splitPath . pop ( ) ; splitPath . push ( rename [ path ] ) ; const newPath = splitPath . join ( "." ) . toString ( ) ; operate ( returnObj , newPath , keyValue , "set" ) ; } else { return reject ( new Error ( "Value to rename was not found" ) ) ; } } ) ; resolve ( returnObj ) ; } catch ( e ) { return reject ( e ) ; } } ) ; } ;