import { DateTime } from "luxon" ; import { DateSortKeys , SetType } from "../main/types" ; import { StatisticsSetType } from "../statistics/types" ; param obj param key returns export const hasKey = < O > ( obj , key ) : key is keyof O => key in obj ; param arr param item returns export const arrayIncludes = < T > ( arr , item ) : item is T => arr . includes ( item ) ; /**
 * Returns an array of object keys to iterate on.
 * Only use for objects you're certain won't gain more keys in runtime.
 */ export const objectKeys = < T extends Record < string , any > > ( obj ) : ( keyof T ) [ ] => Object . keys ( obj ) ; param array returns export const removeDuplicates = < T > ( array ) : T [ ] => array . filter ( ( v , i , a ) => a . indexOf ( v ) === i ) ; param arr param val returns export const countInArray = < T > ( arr , val ) : number => arr . reduce ( ( count , item ) => count + Number ( item === val ) , 0 ) ; param descending param hoist returns example example example example export const alphabeticalSortCurried = < T extends unknown > ( descending = false , hoist ? ) => ( a , b ) : 1 | - 1 | 0 => { if ( hoist && ( a === hoist || b === hoist ) && a !== b ) { return a === hoist ? - 1 : 1 ; } const x = typeof a === "string" ? a . toLowerCase ( ) : a ; const y = typeof b === "string" ? b . toLowerCase ( ) : b ; if ( x < y ) { return descending ? 1 : - 1 ; } if ( x > y ) { return descending ? - 1 : 1 ; } return 0 ; } ; param array param descending param hoist returns export const alphabeticalSort = ( array , descending = false , hoist ? ) : string [ ] => array . sort ( alphabeticalSortCurried ( descending , hoist ) ) ; param prop param descending param hoist returns example example export const alphabeticalSortPropCurried = < O extends Record < string , unknown > , K extends keyof O > ( prop , descending = false , hoist ? ) => ( a , b ) : 1 | - 1 | 0 => { const x = a [ prop ] ; const y = b [ prop ] ; if ( hoist && ( x === hoist || y === hoist ) && x !== y ) { return x === hoist ? - 1 : 1 ; } const c = typeof x === "string" ? x . toLowerCase ( ) : x ; const d = typeof y === "string" ? y . toLowerCase ( ) : y ; if ( c < d ) { return descending ? 1 : - 1 ; } if ( c > d ) { return descending ? - 1 : 1 ; } return 0 ; } ; param array param prop param descending param hoist returns export const alphabeticalSortProp = < O extends Record < string , unknown > , K extends keyof O > ( array , prop , descending = false , hoist ? ) : O [ ] => array . sort ( alphabeticalSortPropCurried ( prop , descending , hoist ) ) ; param sets param prop param format Luxon string to specify format. See  https .
 *  returns export const getSetMonthRange = ( sets , prop , format ) : string [ ] => { const setMonths = removeDuplicates ( sets . map ( ( set ) => { const val = set [ prop ] ; return val && ! val . includes ( "Q" ) ? DateTime . fromISO ( val ) . toFormat ( "yyyy-MM" ) : "" ; } ) ) . filter ( Boolean ) ; alphabeticalSort ( setMonths ) ; const monthDiff = ( dateFrom , dateTo ) => { return dateTo . month - dateFrom . month + 12 * ( dateTo . year - dateFrom . year ) ; } ; const length = monthDiff ( DateTime . fromISO ( setMonths [ 0 ] , { zone : "utc" } ) , DateTime . fromISO ( setMonths [ setMonths . length - 1 ] , { zone : "utc" } ) ) + 1 ; const allMonths = Array ( length ) . fill ( "" ) . map ( ( v , i ) => DateTime . fromISO ( setMonths [ 0 ] , { zone : "utc" } ) . plus ( { months : i } ) . toFormat ( format ) ) ; return allMonths ; } ; example param { Promise } promise param defaultError returns { Promise } returns { Promise } export const handle = < T > ( promise , defaultError = "rejected" ) : Promise < [ T , undefined ] | [ undefined , any ] > => { return promise . then ( ( data ) => [ data , undefined ] as [ T , undefined ] ) . catch ( ( error ) => [ undefined , error || defaultError ] ) ; } ;