import { FieldStringifier } from '../field-stringifier' ; import { Field } from '../record' ; const DEFAULT_RECORD_DELIMITER = '\n' ; const VALID_RECORD_DELIMITERS = [ DEFAULT_RECORD_DELIMITER , '\r\n' ] ; export abstract class CsvStringifier < T > { constructor ( private readonly fieldStringifier , private readonly recordDelimiter = DEFAULT_RECORD_DELIMITER ) { _validateRecordDelimiter ( recordDelimiter ) ; } getHeaderString ( ) { const headerRecord = this . getHeaderRecord ( ) ; return headerRecord ? this . joinRecords ( [ this . getCsvLine ( headerRecord ) ] ) : null ; } stringifyRecords ( records ) { const csvLines = Array . from ( records , record => this . getCsvLine ( this . getRecordAsArray ( record ) ) ) ; return this . joinRecords ( csvLines ) ; } protected abstract getRecordAsArray ( _record ) ; protected abstract getHeaderRecord ( ) ; private getCsvLine ( record ) { return record . map ( fieldValue => this . fieldStringifier . stringify ( fieldValue ) ) . join ( this . fieldStringifier . fieldDelimiter ) ; } private joinRecords ( records ) { return records . join ( this . recordDelimiter ) + this . recordDelimiter ; } } function _validateRecordDelimiter ( delimiter ) { if ( VALID_RECORD_DELIMITERS . indexOf ( delimiter ) === - 1 ) { throw new Error ( `Invalid record delimiter \`${ delimiter }\` is specified` ) ; } }