import { Transform } from 'readable-stream' ; import { Timezone , isDate } from 'chronoshift' ; import { PlywoodValueBuilder , TimeRange , Set , Dataset , PlywoodValue } from 'plywood' ; import { table , getBorderCharacters , createStream } from 'table' ; function streamFlatten ( v ) { return v ; } function escapeControlChars ( str ) { return str . replace ( /[\x01-\x1A]/g , ( x ) => '\\x' + ( '0' + x . charCodeAt ( 0 ) . toString ( 16 ) ) . substr ( - 2 ) ) ; } function formatValue ( v , tz ) { if ( v == null ) return 'NULL' ; if ( isDate ( v ) ) return Timezone . formatDateWithTimezone ( v , tz ) ; if ( Set . isSet ( v ) || TimeRange . isTimeRange ( v ) ) return v . toString ( tz ) ; return escapeControlChars ( '' + v ) ; } export function getOutputTransform ( output , timezone ) { switch ( output ) { case 'table' : return collectOutput ( ( dataset ) => { let flatDataset = dataset . flatten ( { order : 'preorder' } ) ; let columnNames = flatDataset . attributes . map ( c => c . name ) ; if ( columnNames . length ) { let tableData = [ columnNames ] . concat ( flatDataset . data . map ( ( flatDatum ) => { return columnNames . map ( cn => formatValue ( flatDatum [ cn ] , timezone ) ) ; } ) ) ; return table ( tableData , { border : getBorderCharacters ( 'norc' ) , drawHorizontalLine : ( index , size ) => index <= 1 || index === size } ) ; } else { return '' ; } } ) ; case 'csv' : return collectOutput ( ( v ) => { if ( v instanceof Dataset ) { return v . toCSV ( { finalLineBreak : 'include' , timezone } ) ; } else { return String ( v ) ; } } ) ; case 'tsv' : return collectOutput ( ( v ) => { if ( v instanceof Dataset ) { return v . toTSV ( { finalLineBreak : 'include' , timezone } ) ; } else { return String ( v ) ; } } ) ; case 'json' : case 'flat' : return collectOutput ( ( v ) => { if ( v instanceof Dataset ) { return v . flatten ( ) . data . map ( ( d ) => JSON . stringify ( d ) ) . join ( '\n' ) + '\n' ; } else { return String ( v ) ; } } ) ; case 'plywood' : return collectOutput ( ( v ) => { return JSON . stringify ( v , null , 2 ) ; } ) ; case 'plywood-stream' : return jsonOutput ( ) ; default : throw new Error ( 'Unknown output type' ) ; } } function jsonOutput ( ) { return new Transform ( { objectMode : true , transform : function ( chunk , encoding , callback ) { callback ( null , JSON . stringify ( chunk ) + '\n' ) ; } } ) ; } function collectOutput ( onDone ) { let pvb = new PlywoodValueBuilder ( ) ; return new Transform ( { objectMode : true , transform : function ( chunk , encoding , callback ) { pvb . processBit ( chunk ) ; callback ( null ) ; } , flush : function ( callback ) { callback ( null , onDone ( pvb . getValue ( ) ) ) ; } } ) ; }