From a32c0879b3988b95d8eac3ca21d778f23787b3c0 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Thu, 6 May 2021 12:44:08 +0100 Subject: [PATCH] fix(convert-to-csv): fix bug with escaping quoted string --- src/utils/convertToCsv.spec.ts | 27 +++++++++++++++++++++++++++ src/utils/convertToCsv.ts | 22 +++++++++------------- 2 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 src/utils/convertToCsv.spec.ts diff --git a/src/utils/convertToCsv.spec.ts b/src/utils/convertToCsv.spec.ts new file mode 100644 index 0000000..0faa848 --- /dev/null +++ b/src/utils/convertToCsv.spec.ts @@ -0,0 +1,27 @@ +import { convertToCSV } from './convertToCsv' + +describe('convertToCsv', () => { + it('should convert single quoted values', () => { + const data = [ + { foo: `'bar'`, bar: 'abc' }, + { foo: 'sadf', bar: 'def' }, + { foo: 'asd', bar: `'qwert'` } + ] + + const expectedOutput = `foo:$5. bar:$7.\r\n"'bar'",abc\r\nsadf,def\r\nasd,"'qwert'"` + + expect(convertToCSV(data)).toEqual(expectedOutput) + }) + + it('should convert double quoted values', () => { + const data = [ + { foo: `"bar"`, bar: 'abc' }, + { foo: 'sadf', bar: 'def' }, + { foo: 'asd', bar: `"qwert"` } + ] + + const expectedOutput = `foo:$5. bar:$7.\r\n"""bar""",abc\r\nsadf,def\r\nasd,"""qwert"""` + + expect(convertToCSV(data)).toEqual(expectedOutput) + }) +}) diff --git a/src/utils/convertToCsv.ts b/src/utils/convertToCsv.ts index 08a33b1..c071ffa 100644 --- a/src/utils/convertToCsv.ts +++ b/src/utils/convertToCsv.ts @@ -1,6 +1,6 @@ /** - * Converts the given JSON object to a CSV string. - * @param data - the JSON object to convert. + * Converts the given JSON object array to a CSV string. + * @param data - the array of JSON objects to convert. */ export const convertToCSV = (data: any) => { const replacer = (key: any, value: any) => (value === null ? '' : value) @@ -37,15 +37,7 @@ export const convertToCSV = (data: any) => { let byteSize if (typeof row[field] === 'string') { - let doubleQuotesFound = row[field] - .split('') - .filter((char: any) => char === '"') - byteSize = getByteSize(row[field]) - - if (doubleQuotesFound.length > 0) { - byteSize += doubleQuotesFound.length - } } return byteSize @@ -73,6 +65,7 @@ export const convertToCSV = (data: any) => { if (invalidString) { return 'ERROR: LARGE STRING LENGTH' } + csvTest = data.map((row: any) => { const fields = Object.keys(row).map((fieldName, index) => { let value @@ -80,12 +73,11 @@ export const convertToCSV = (data: any) => { const currentCell = row[fieldName] if (JSON.stringify(currentCell).search(/(\\t|\\n|\\r)/gm) > -1) { - value = currentCell.toString() containsSpecialChar = true - } else { - value = JSON.stringify(currentCell, replacer) } + value = JSON.stringify(currentCell, replacer) + value = value.replace(/\\\\/gm, '\\') if (containsSpecialChar) { @@ -101,6 +93,10 @@ export const convertToCSV = (data: any) => { value = value.substring(1, value.length - 1) } + if (value.includes("'")) { + value = '"' + value + '"' + } + value = value.replace(/\\"/gm, '""') }