From feeec3b829fb82d2e12d443ef4153dfaef345fc4 Mon Sep 17 00:00:00 2001 From: mrodrig Date: Sat, 24 Feb 2024 22:44:52 -0500 Subject: [PATCH 1/4] feat: add arrayIndexesAsKeys option support for #207 --- src/constants.ts | 1 + src/json2csv.ts | 1 + src/types.ts | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/src/constants.ts b/src/constants.ts index 9115a9d..ac59c3b 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -18,6 +18,7 @@ export const errors = { }; export const defaultJson2CsvOptions: DefaultJson2CsvOptions = { + arrayIndexesAsKeys: false, checkSchemaDifferences: false, delimiter : { field : ',', diff --git a/src/json2csv.ts b/src/json2csv.ts index 8b1e30f..cd4ae01 100755 --- a/src/json2csv.ts +++ b/src/json2csv.ts @@ -12,6 +12,7 @@ export const Json2Csv = function(options: FullJson2CsvOptions) { customValueParser = options.parseValue && typeof options.parseValue === 'function' ? options.parseValue : null, expandingWithoutUnwinding = options.expandArrayObjects && !options.unwindArrays, deeksOptions = { + arrayIndexesAsKeys: options.arrayIndexesAsKeys, expandNestedObjects: options.expandNestedObjects, expandArrayObjects: expandingWithoutUnwinding, ignoreEmptyArraysWhenExpanding: expandingWithoutUnwinding, diff --git a/src/types.ts b/src/types.ts index fbe42d9..d652fdf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -87,6 +87,11 @@ export interface Csv2JsonOptions extends Omit { } export interface Json2CsvOptions extends SharedConverterOptions { + /** Should array indexes be included in the generated keys? + * @default false + */ + arrayIndexesAsKeys?: boolean; + /** * Should all documents have the same schema? * @default false From 14e3d20144abefb201f4a1e89503e267f48edfa9 Mon Sep 17 00:00:00 2001 From: mrodrig Date: Sat, 24 Feb 2024 22:51:09 -0500 Subject: [PATCH 2/4] docs: add info to README about arrayIndexesAsKeys option --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 1721f6f..85e8718 100755 --- a/README.md +++ b/README.md @@ -50,6 +50,9 @@ Returns the CSV `string` or rejects with an `Error` if there was an issue. * `array` - An array of JSON documents to be converted to CSV. * `options` - (Optional) A JSON document specifying any of the following key value pairs: + * `arrayIndexesAsKeys` - Boolean - Should array indexes be included in the generated keys? + * Default: `false` + * Note: This provides a more accurate representation of the JSON in the returned CSV, but may be less human readable. See [#207](https://github.com/mrodrig/json-2-csv/issues/207) for more details. * `checkSchemaDifferences` - Boolean - Should all documents have the same schema? * Default: `false` * Note: An error will be thrown if some documents have differing schemas when this is set to `true`. From b017dfb6a9f5bf010af654548ac916c627ca0d0b Mon Sep 17 00:00:00 2001 From: mrodrig Date: Sat, 24 Feb 2024 23:11:19 -0500 Subject: [PATCH 3/4] chore(deps): update dependencies to have support for use case in #207 --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac95b59..476081d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "5.3.0", "license": "MIT", "dependencies": { - "deeks": "3.0.2", - "doc-path": "4.0.2" + "deeks": "3.1.0", + "doc-path": "4.1.0" }, "devDependencies": { "@types/mocha": "10.0.1", @@ -1601,9 +1601,9 @@ } }, "node_modules/deeks": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/deeks/-/deeks-3.0.2.tgz", - "integrity": "sha512-c6OmjIygIB/avwXwEQOiODS+nw6fEX4cvOdDMqdL7dt3dicV/xykAJ9AeVc/8/JTVQDuacjRc9KCMmXafL1Y4A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/deeks/-/deeks-3.1.0.tgz", + "integrity": "sha512-e7oWH1LzIdv/prMQ7pmlDlaVoL64glqzvNgkgQNgyec9ORPHrT2jaOqMtRyqJuwWjtfb6v+2rk9pmaHj+F137A==", "engines": { "node": ">= 16" } @@ -1664,9 +1664,9 @@ } }, "node_modules/doc-path": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-4.0.2.tgz", - "integrity": "sha512-OqZEk7EM1aP3JpO+mq0pv1msEJWrzZVXu4q3YjEYJKc+Wt3/chac4KJdaGueK5IGemOwfptrLctG9I8xkb59qQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-4.1.0.tgz", + "integrity": "sha512-i+hXn5HFwpPOwe8JcvjjQYuUVt0p46Ybi+73g9L43zQUKR6zMyaUAKFwGBMH3NWQDugRWIwxg2+FvvxCv0IG7Q==", "engines": { "node": ">=16" } diff --git a/package.json b/package.json index 9c65319..f31f08c 100755 --- a/package.json +++ b/package.json @@ -39,8 +39,8 @@ "cli" ], "dependencies": { - "deeks": "3.0.2", - "doc-path": "4.0.2" + "deeks": "3.1.0", + "doc-path": "4.1.0" }, "devDependencies": { "@types/mocha": "10.0.1", From c3562d98f02fe3dac857906c3e4001eaf365fbd4 Mon Sep 17 00:00:00 2001 From: mrodrig Date: Sat, 24 Feb 2024 23:41:26 -0500 Subject: [PATCH 4/4] test: add test for arrayIndexesAsKeys option for #207 --- test/config/testCsvFilesList.ts | 1 + test/config/testJsonFilesList.ts | 1 + test/data/csv/arrayIndexesAsKeys.csv | 3 +++ test/data/json/arrayIndexesAsKeys.json | 30 ++++++++++++++++++++++++++ test/json2csv.ts | 8 +++++++ 5 files changed, 43 insertions(+) create mode 100644 test/data/csv/arrayIndexesAsKeys.csv create mode 100644 test/data/json/arrayIndexesAsKeys.json diff --git a/test/config/testCsvFilesList.ts b/test/config/testCsvFilesList.ts index be3bd89..4178671 100644 --- a/test/config/testCsvFilesList.ts +++ b/test/config/testCsvFilesList.ts @@ -52,6 +52,7 @@ const csvFileConfig = [ {key: 'newlineWithWrapDelimiters', file: '../data/csv/newlineWithWrapDelimiters.csv'}, {key: 'excludeKeyPattern', file: '../data/csv/excludeKeyPattern.csv'}, {key: 'wildcardMatch', file: '../data/csv/wildcardMatch.csv'}, + {key: 'arrayIndexesAsKeys', file: '../data/csv/arrayIndexesAsKeys.csv'}, ]; function readCsvFile(filePath: string) { diff --git a/test/config/testJsonFilesList.ts b/test/config/testJsonFilesList.ts index c8efe2d..9d4d3bc 100644 --- a/test/config/testJsonFilesList.ts +++ b/test/config/testJsonFilesList.ts @@ -45,4 +45,5 @@ export default { newlineWithWrapDelimiters: require('../data/json/newlineWithWrapDelimiters'), excludeKeyPattern: require('../data/json/excludeKeyPattern'), wildcardMatch: require('../data/json/wildcardMatch.json'), + arrayIndexesAsKeys: require('../data/json/arrayIndexesAsKeys.json'), }; diff --git a/test/data/csv/arrayIndexesAsKeys.csv b/test/data/csv/arrayIndexesAsKeys.csv new file mode 100644 index 0000000..55a17c9 --- /dev/null +++ b/test/data/csv/arrayIndexesAsKeys.csv @@ -0,0 +1,3 @@ +test.list.0.a,test.list.0.optionA,test.list.1.a,test.list.1.optionB +1,ac,2,radio +3,cd,4,heat \ No newline at end of file diff --git a/test/data/json/arrayIndexesAsKeys.json b/test/data/json/arrayIndexesAsKeys.json new file mode 100644 index 0000000..2e589b1 --- /dev/null +++ b/test/data/json/arrayIndexesAsKeys.json @@ -0,0 +1,30 @@ +[ + { + "test": { + "list": [ + { + "a": 1, + "optionA": "ac" + }, + { + "a": 2, + "optionB": "radio" + } + ] + } + }, + { + "test": { + "list": [ + { + "a": 3, + "optionA": "cd" + }, + { + "a": 4, + "optionB": "heat" + } + ] + } + } +] \ No newline at end of file diff --git a/test/json2csv.ts b/test/json2csv.ts index cff3bdd..a16c33a 100644 --- a/test/json2csv.ts +++ b/test/json2csv.ts @@ -578,6 +578,14 @@ export function runTests() { assert.equal(csv, updatedCsv); }); + // Test case for #207 + it('should include the array indexes in CSV key headers if specified via the option', () => { + const csv = json2csv(jsonTestData.arrayIndexesAsKeys, { + arrayIndexesAsKeys: true, + }); + assert.equal(csv, csvTestData.arrayIndexesAsKeys); + }); + it('should use a custom value parser function when provided', () => { const updatedCsv = csvTestData.trimmedFields.split('\n'); const textRow = 'Parsed Value,Parsed Value,Parsed Value,Parsed Value,Parsed Value';