param input function getEncodedValue ( input , allowEmptyString ? ) { if ( input == null ) { return input ; } if ( input . length === 0 && ( ! allowEmptyString || ( allowEmptyString && input !== '' ) ) ) { return null ; } const str = input instanceof Array ? input [ 0 ] : input ; if ( str == null ) { return str ; } if ( ! allowEmptyString && str === '' ) { return null ; } return str ; } param input function getEncodedValueArray ( input ) { if ( input == null ) { return input ; } return input instanceof Array ? input : input === '' ? [ ] : [ input ] ; } param { Date } date return { String } export function encodeDate ( date ) { if ( date == null ) { return date ; } const year = date . getFullYear ( ) ; const month = date . getMonth ( ) + 1 ; const day = date . getDate ( ) ; return `${ year }-${ month < 10 ? `0${ month }` : month }-${ day < 10 ? `0${ day }` : day }` ; } param { String } input return { Date } export function decodeDate ( input ) { const dateString = getEncodedValue ( input ) ; if ( dateString == null ) return dateString ; const parts = dateString . split ( '-' ) as any ; if ( parts [ 1 ] != null ) { parts [ 1 ] -= 1 ; } else { parts [ 1 ] = 0 ; parts [ 2 ] = 1 ; } const decoded = new Date ( ... ( parts as [ number , number , number ] ) ) ; if ( isNaN ( decoded . getTime ( ) ) ) { return null ; } return decoded ; } param { Date } date return { String } export function encodeDateTime ( date ) { if ( date == null ) { return date ; } return date . toISOString ( ) ; } param { String } input return { Date } export function decodeDateTime ( input ) { const dateString = getEncodedValue ( input ) ; if ( dateString == null ) return dateString ; const decoded = new Date ( dateString ) ; if ( isNaN ( decoded . getTime ( ) ) ) { return null ; } return decoded ; } param { Boolean } bool return { String } export function encodeBoolean ( bool ) { if ( bool == null ) { return bool ; } return bool ? '1' : '0' ; } param { String } input return { Boolean } export function decodeBoolean ( input ) { const boolStr = getEncodedValue ( input ) ; if ( boolStr == null ) return boolStr ; if ( boolStr === '1' ) { return true ; } else if ( boolStr === '0' ) { return false ; } return null ; } param { Number } num return { String } export function encodeNumber ( num ) { if ( num == null ) { return num ; } return String ( num ) ; } param { String } input return { Number } export function decodeNumber ( input ) { const numStr = getEncodedValue ( input ) ; if ( numStr == null ) return numStr ; if ( numStr === '' ) return null ; const result = + numStr ; return result ; } param { String } str return { String } export function encodeString ( str ) { if ( str == null ) { return str ; } return String ( str ) ; } param { String } input return { String } export function decodeString ( input ) { const str = getEncodedValue ( input , true ) ; if ( str == null ) return str ; return String ( str ) ; } param { String } input param { String [ ] } enumValues return { String } export function decodeEnum < T extends string > ( input , enumValues ) { const str = decodeString ( input ) ; if ( str == null ) return str ; return enumValues . includes ( str as any ) ? str as T : undefined ; } param { Any } any return { String } export function encodeJson ( any ) { if ( any == null ) { return any ; } return JSON . stringify ( any ) ; } param { String } input return { Any } export function decodeJson ( input ) { const jsonStr = getEncodedValue ( input ) ; if ( jsonStr == null ) return jsonStr ; let result = null ; try { result = JSON . parse ( jsonStr ) ; } catch ( e ) { } return result ; } param { Array } array return { String [ ] } export function encodeArray ( array ) { if ( array == null ) { return array ; } return array ; } param { String | Array } input return { Array } export function decodeArray ( input ) { const arr = getEncodedValueArray ( input ) ; if ( arr == null ) return arr ; return arr ; } param { Array } array return { String [ ] } export function encodeNumericArray ( array ) { if ( array == null ) { return array ; } return array . map ( String ) ; } param { String | Array } input return { Array } export function decodeNumericArray ( input ) { const arr = decodeArray ( input ) ; if ( arr == null ) return arr ; return arr . map ( ( d ) => ( d === '' || d == null ? null : + d ) ) ; } param array param entrySeparator return export function encodeDelimitedArray ( array , entrySeparator = '_' ) { if ( array == null ) { return array ; } return array . join ( entrySeparator ) ; } param { String } input param entrySeparator return { Array } export function decodeDelimitedArray ( input , entrySeparator = '_' ) { const arrayStr = getEncodedValue ( input , true ) ; if ( arrayStr == null ) return arrayStr ; if ( arrayStr === '' ) return [ ] ; return arrayStr . split ( entrySeparator ) ; } param { Array } array return { String } export const encodeDelimitedNumericArray = encodeDelimitedArray as ( array : ( number | null ) [ ] | null | undefined , entrySeparator ? : string ) => string | null | undefined ; param { String } jsonStr return { Array } export function decodeDelimitedNumericArray ( arrayStr , entrySeparator = '_' ) { const decoded = decodeDelimitedArray ( arrayStr , entrySeparator ) ; if ( decoded == null ) return decoded ; return decoded . map ( ( d ) => ( d === '' || d == null ? null : + d ) ) ; } param { Object } object param { String } keyValSeparator param { String } entrySeparator return { String } export function encodeObject ( obj , keyValSeparator = '-' , entrySeparator = '_' ) { if ( obj == null ) return obj ; if ( ! Object . keys ( obj ) . length ) return '' ; return Object . keys ( obj ) . map ( ( key ) => `${ key }${ keyValSeparator }${ obj [ key ] }` ) . join ( entrySeparator ) ; } param { String } input param { String } keyValSeparator param { String } entrySeparator return { Object } export function decodeObject ( input , keyValSeparator = '-' , entrySeparator = '_' ) { const objStr = getEncodedValue ( input , true ) ; if ( objStr == null ) return objStr ; if ( objStr === '' ) return { } ; const obj = { } ; const keyValSeparatorRegExp = new RegExp ( `${ keyValSeparator }(.*)` ) ; objStr . split ( entrySeparator ) . forEach ( ( entryStr ) => { const [ key , value ] = entryStr . split ( keyValSeparatorRegExp ) ; obj [ key ] = value ; } ) ; return obj ; } param { Object } object param { String } keyValSeparator param { String } entrySeparator return { String } export const encodeNumericObject = encodeObject as ( obj : { [ key ] : number | null | undefined ; } | null | undefined , keyValSeparator ? : string , entrySeparator ? : string ) => string | null | undefined ; param { String } input param { String } keyValSeparator param { String } entrySeparator return { Object } export function decodeNumericObject ( input , keyValSeparator = '-' , entrySeparator = '_' ) { const decoded = decodeObject ( input , keyValSeparator , entrySeparator ) ; if ( decoded == null ) return decoded ; const decodedNumberObj = { } ; for ( const key of Object . keys ( decoded ) ) { decodedNumberObj [ key ] = decodeNumber ( decoded [ key ] ) ; } return decodedNumberObj ; }