const semver = /^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)?)?$/i ; const patch = /-([0-9A-Za-z-.]+)/ ; param v returns { String [ ] } const split = ( v ) : string [ ] => { const temp = v . replace ( /^v/ , '' ) . split ( '.' ) ; const arr = temp . splice ( 0 , 2 ) ; arr . push ( temp . join ( '.' ) ) ; return arr ; } ; param v const tryParse = ( v ) : string | number => { return Number . isNaN ( Number ( v ) ) ? v : Number ( v ) ; } ; param version returns { number } const validate = ( version ) : number => { if ( ! semver . test ( version ) ) { return - 1 ; } return 1 ; } ; param v1 param v2 returns { number } export const compareVersions = ( v1 , v2 ) : number => { if ( validate ( v1 ) === - 1 || validate ( v2 ) === - 1 ) { return - 1 ; } const s1 = split ( v1 ) ; const s2 = split ( v2 ) ; for ( let i = 0 ; i < 3 ; i ++ ) { const n1 = parseInt ( s1 [ i ] || '0' , 10 ) ; const n2 = parseInt ( s2 [ i ] || '0' , 10 ) ; if ( n1 > n2 ) { return 1 ; } if ( n2 > n1 ) { return - 1 ; } } if ( [ s1 [ 2 ] , s2 [ 2 ] ] . every ( patch . test . bind ( patch ) ) ) { const p1 = patch . exec ( s1 [ 2 ] ) [ 1 ] . split ( '.' ) . map ( tryParse ) ; const p2 = patch . exec ( s2 [ 2 ] ) [ 1 ] . split ( '.' ) . map ( tryParse ) ; for ( let k = 0 ; k < Math . max ( p1 . length , p2 . length ) ; k ++ ) { if ( p1 [ k ] === undefined || ( typeof p2 [ k ] === 'string' && typeof p1 [ k ] === 'number' ) ) { return - 1 ; } if ( p2 [ k ] === undefined || ( typeof p1 [ k ] === 'string' && typeof p2 [ k ] === 'number' ) ) { return 1 ; } if ( p1 [ k ] > p2 [ k ] ) { return 1 ; } if ( p2 [ k ] > p1 [ k ] ) { return - 1 ; } } } else if ( [ s1 [ 2 ] , s2 [ 2 ] ] . some ( patch . test . bind ( patch ) ) ) { return patch . test ( s1 [ 2 ] ) ? - 1 : 1 ; } return 0 ; } ; param { Array } argv param { String } argName param { Boolean } exactMatch return { String } export const getCommandLineArgs = ( argv , argName , exactMatch ) : string | null => { if ( ! Array . isArray ( argv ) ) { throw new Error ( `get-command-line-args: TypeError invalid func arg, must be an array: ${ argv }` ) ; } const argNameToFind = argName . toLocaleLowerCase ( ) ; for ( let i = 0 , len = argv . length ; i < len ; i ++ ) { const arg = argv [ i ] . toLocaleLowerCase ( ) ; if ( ( exactMatch && arg === argNameToFind ) || ( ! exactMatch && arg . startsWith ( argNameToFind ) ) ) { return argv [ i ] ; } } return null ; } ; return { String } export const getGuid = ( ) : string => { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' . replace ( /[xy]/g , ( c ) => { const r = ( Math . random ( ) * 16 ) | 0 ; const v = c === 'x' ? r : ( r & 0x3 ) | 0x8 ; return v . toString ( 16 ) ; } ) ; } ; param object param fields export const pick = ( object , fields ) => { const obj = { } ; for ( const field of fields ) { if ( object [ field ] !== undefined && object [ field ] !== null ) { obj [ field ] = object [ field ] ; } } return obj ; } ; param data { Object } param values { Array } return { Object } export const filterOutSelectedValues = ( data , values ) : object => { if ( ! data ) { return { } ; } return Object . keys ( data ) . reduce ( ( obj , key ) => { if ( Array . isArray ( data [ key ] ) && data [ key ] . length <= 0 ) { return obj ; } if ( values . indexOf ( data [ key ] ) <= - 1 ) { obj [ key ] = data [ key ] ; } return obj ; } , { } ) ; } ; param func param wait example export const throttle = ( func , wait ) : ( ( ... args ) => void ) => { if ( wait <= 0 ) { throw Error ( 'throttle: invalid throttleTime arg, must be a number: ' + wait ) ; } let timer ; let lastRan = 0 ; return ( ... args ) => { if ( ! lastRan ) { func . apply ( null , args ) ; lastRan = Date . now ( ) ; } else { clearTimeout ( timer ) ; timer = setTimeout ( ( ) => { if ( Date . now ( ) - lastRan >= wait ) { func . apply ( null , args ) ; lastRan = Date . now ( ) ; } } , wait - ( Date . now ( ) - lastRan ) ) ; } } ; } ; param str { String } param data { Object } example return { * } export const formatString = ( str , data ? ) : string => { if ( ! str || ! data ) { return str ; } for ( const key in data ) { if ( Object . prototype . hasOwnProperty . call ( data , key ) ) { return str . replace ( /({([^}]+)})/g , ( i ) => { const replacedKey = i . replace ( /{/ , '' ) . replace ( /}/ , '' ) ; return data [ replacedKey ] ? data [ replacedKey ] : replacedKey ; } ) ; } } return str ; } ; param value param percentage export const calculatePercentage = ( value , percentage ) => { return value * percentage * 0.01 ; } ;