export interface HeaderObj { label : string ; key : string ; } export const isJsons = ( array ) => Array . isArray ( array ) && array . every ( row => typeof row === 'object' && ! ( row instanceof Array ) ) ; export const isArrays = ( array ) => Array . isArray ( array ) && array . every ( row => Array . isArray ( row ) ) ; export function jsonsHeaders ( array ) { return Array . from ( new Set ( array . map ( item => Object . keys ( item ) ) . reduce ( ( a , b ) => [ ... a , ... b ] , [ ] ) ) ) ; } export function jsons2arrays ( jsons , headers ? ) { headers = headers || jsonsHeaders ( jsons ) ; let headerLabels = headers as string [ ] ; let headerKeys = headers as string [ ] ; if ( isJsons ( headers ) ) { headerLabels = ( headers as HeaderObj [ ] ) . map ( header => header . label ) ; headerKeys = ( headers as HeaderObj [ ] ) . map ( header => header . key ) ; } const data = jsons . map ( object => headerKeys . map ( header => ( header in object ? object [ header ] : '' ) ) ) ; return [ headerLabels , ... data ] ; } export const elementOrEmpty = ( element ) => element || element === 0 ? element : '' ; export function joiner ( data , delimiter = ',' ) { return data . map ( ( row , index ) => row . map ( ( element ) => '"' + elementOrEmpty ( element ) + '"' ) . join ( delimiter ) ) . join ( `\n` ) ; } export function arrays2csv ( data , headers ? , delimiter ? ) { return joiner ( headers ? [ headers , ... data ] : data , delimiter ) ; } export function jsons2csv ( data , headers ? , delimiter ? ) { return joiner ( jsons2arrays ( data , headers ) , delimiter ) ; } export function string2csv ( data , headers ? , delimiter ? ) { return headers ? `${ headers . join ( delimiter ) }\n${ data }` : data ; } export function toCSV ( data , headers ? , delimiter ? ) { if ( isJsons ( data as any ) ) { return jsons2csv ( data as { [ key ] : string ; } [ ] , headers , delimiter ) ; } if ( isArrays ( data as any ) ) { return arrays2csv ( data as string [ ] [ ] , headers , delimiter ) ; } if ( typeof data === 'string' ) { return string2csv ( data , headers as string [ ] , delimiter ) ; } throw new TypeError ( `Data should be a "String", "Array of arrays" OR "Array of objects" ` ) ; } export function blob ( data , uFEFF = true , headers ? , delimiter ? ) { const csv = toCSV ( data , headers , delimiter ) ; return new Blob ( [ uFEFF ? '\uFEFF' : '' , csv ] , { type : 'text/csv' } ) ; } export function buildURI ( data , uFEFF = true , headers ? , delimiter ? ) { return URL . createObjectURL ( blob ( data , uFEFF , headers , delimiter ) ) ; }