import { Field } from './record' ; const DEFAULT_FIELD_DELIMITER = ',' ; const VALID_FIELD_DELIMITERS = [ DEFAULT_FIELD_DELIMITER , ';' ] ; export abstract class FieldStringifier { constructor ( public readonly fieldDelimiter ) { } abstract stringify ( value ? ) ; protected isEmpty ( value ? ) { return typeof value === 'undefined' || value === null || value === '' ; } protected quoteField ( field ) { return `"${ field . replace ( /"/g , '""' ) }"` ; } } class DefaultFieldStringifier extends FieldStringifier { stringify ( value ? ) { if ( this . isEmpty ( value ) ) return '' ; const str = String ( value ) ; return this . needsQuote ( str ) ? this . quoteField ( str ) : str ; } private needsQuote ( str ) { return str . includes ( this . fieldDelimiter ) || str . includes ( '\r' ) || str . includes ( '\n' ) || str . includes ( '"' ) ; } } class ForceQuoteFieldStringifier extends FieldStringifier { stringify ( value ? ) { return this . isEmpty ( value ) ? '' : this . quoteField ( String ( value ) ) ; } } export function createFieldStringifier ( fieldDelimiter = DEFAULT_FIELD_DELIMITER , alwaysQuote = false ) { _validateFieldDelimiter ( fieldDelimiter ) ; return alwaysQuote ? new ForceQuoteFieldStringifier ( fieldDelimiter ) : new DefaultFieldStringifier ( fieldDelimiter ) ; } function _validateFieldDelimiter ( delimiter ) { if ( VALID_FIELD_DELIMITERS . indexOf ( delimiter ) === - 1 ) { throw new Error ( `Invalid field delimiter \`${ delimiter }\` is specified` ) ; } }