export const RE_RECORD_ID = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/ ; param { Any } value return { Boolean } function _isUndefined ( value ) { return typeof value === "undefined" ; } param { String } order param { Array } list return { Array } export function sortObjects < T extends { [ key ] : any ; } > ( order , list ) { const hasDash = order [ 0 ] === "-" ; const field = hasDash ? order . slice ( 1 ) : order ; const direction = hasDash ? - 1 : 1 ; return list . slice ( ) . sort ( ( a , b ) => { if ( a [ field ] && _isUndefined ( b [ field ] ) ) { return direction ; } if ( b [ field ] && _isUndefined ( a [ field ] ) ) { return - direction ; } if ( _isUndefined ( a [ field ] ) && _isUndefined ( b [ field ] ) ) { return 0 ; } return a [ field ] > b [ field ] ? direction : - direction ; } ) ; } param { Object } filters param { Object } entry return { Boolean } export function filterObject < T extends { [ key ] : any ; } > ( filters , entry ) { return Object . keys ( filters ) . every ( ( filter ) => { const value = filters [ filter ] ; if ( Array . isArray ( value ) ) { return value . some ( ( candidate ) => candidate === entry [ filter ] ) ; } else if ( typeof value === "object" ) { return filterObject ( value , entry [ filter ] ) ; } else if ( ! Object . prototype . hasOwnProperty . call ( entry , filter ) ) { console . error ( `The property ${ filter } does not exist` ) ; return false ; } return entry [ filter ] === value ; } ) ; } param { Object } filters param { Array } list return { Array } export function filterObjects < T > ( filters , list ) { return list . filter ( ( entry ) => { return filterObject ( filters , entry ) ; } ) ; } param { Array } fns param { Any } init return { Promise } export function waterfall ( fns , init ? ) { if ( ! fns . length ) { return Promise . resolve ( init ) ; } return fns . reduce ( ( promise , nextFn ) => { return promise . then ( nextFn ) ; } , Promise . resolve ( init ) ) ; } param { Object } a param { Object } b return { Boolean } export function deepEqual ( a , b ) { if ( a === b ) { return true ; } if ( typeof a !== typeof b ) { return false ; } if ( ! ( a && typeof a === "object" ) || ! ( b && typeof b === "object" ) ) { return false ; } if ( Object . keys ( a ) . length !== Object . keys ( b ) . length ) { return false ; } for ( const k in a ) { if ( ! deepEqual ( a [ k ] , b [ k ] ) ) { return false ; } } return true ; } param { Object } obj param { Array } keys return { Object } export function omitKeys < T extends { [ key ] : unknown ; } , K extends string > ( obj , keys = [ ] ) { const result = { ... obj } ; for ( const key of keys ) { delete result [ key ] ; } return result ; } export function arrayEqual ( a , b ) { if ( a . length !== b . length ) { return false ; } for ( let i = a . length ; i -- ; ) { if ( a [ i ] !== b [ i ] ) { return false ; } } return true ; } function makeNestedObjectFromArr ( arr , val , nestedFiltersObj ) { const last = arr . length - 1 ; return arr . reduce ( ( acc , cv , i ) => { if ( i === last ) { return ( acc [ cv ] = val ) ; } else if ( Object . prototype . hasOwnProperty . call ( acc , cv ) ) { return acc [ cv ] ; } else { return ( acc [ cv ] = { } ) ; } } , nestedFiltersObj ) ; } export function transformSubObjectFilters ( filtersObj ) { const transformedFilters = { } ; for ( const key in filtersObj ) { const keysArr = key . split ( "." ) ; const val = filtersObj [ key ] ; makeNestedObjectFromArr ( keysArr , val , transformedFilters ) ; } return transformedFilters ; } param obj param key export function getDeepKey ( obj , key ) { const segments = key . split ( "." ) ; let result = obj ; for ( let p = 0 ; p < segments . length ; p ++ ) { result = result ? result [ segments [ p ] ] : undefined ; } return result ?? undefined ; }