diff --git a/lib/JSON2CSVBase.js b/lib/JSON2CSVBase.js index 8b8dfa62..bd737757 100644 --- a/lib/JSON2CSVBase.js +++ b/lib/JSON2CSVBase.js @@ -64,7 +64,7 @@ class JSON2CSVBase { : [row]; if (this.opts.flatten) { - return processedRow.map(this.flatten()); + return processedRow.map(row => this.flatten(row, this.opts.flattenSeparator)); } return processedRow; @@ -209,37 +209,35 @@ class JSON2CSVBase { /** * Performs the flattening of a data row recursively * - * @returns {Function} Function that receives dataRow as input and outputs flattened object + * @param {Object} dataRow Original JSON object + * @param {String} separator Separator to be used as the flattened field name + * @returns {Object} Flattened object */ - flatten() { - return (dataRow) => { - const separator = this.opts.flattenSeparator; - - function step (obj, flatDataRow, currentPath) { - Object.keys(obj).forEach((key) => { - const value = obj[key]; - - const newPath = currentPath - ? `${currentPath}${separator}${key}` - : key; - - if (typeof value !== 'object' - || value === null - || Array.isArray(value) - || Object.prototype.toString.call(value.toJSON) === '[object Function]' - || !Object.keys(value).length) { - flatDataRow[newPath] = value; - return; - } - - step(value, flatDataRow, newPath); - }); + flatten(dataRow, separator) { + function step (obj, flatDataRow, currentPath) { + Object.keys(obj).forEach((key) => { + const value = obj[key]; + + const newPath = currentPath + ? `${currentPath}${separator}${key}` + : key; + + if (typeof value !== 'object' + || value === null + || Array.isArray(value) + || Object.prototype.toString.call(value.toJSON) === '[object Function]' + || !Object.keys(value).length) { + flatDataRow[newPath] = value; + return; + } - return flatDataRow; - } + step(value, flatDataRow, newPath); + }); - return step(dataRow, {}); + return flatDataRow; } + + return step(dataRow, {}); } /** diff --git a/test/CLI.js b/test/CLI.js index f740a3b9..dcac8c20 100644 --- a/test/CLI.js +++ b/test/CLI.js @@ -313,7 +313,7 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { }); }); - testRunner.add('should support flattenning deep JSON', (t) => { + testRunner.add('should support flattening deep JSON', (t) => { const opts = ' --flatten'; child_process.exec(cli + '-i ' + getFixturePath('/json/deepJSON.json') + opts, (err, stdout, stderr) => { @@ -324,6 +324,17 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { }); }); + testRunner.add('should support custom flatten separator', (t) => { + const opts = ' --flatten --flatten-separator __'; + + child_process.exec(cli + '-i ' + getFixturePath('/json/deepJSON.json') + opts, (err, stdout, stderr) => { + t.notOk(stderr); + const csv = stdout; + t.equal(csv, csvFixtures.flattenedCustomSeparatorDeepJSON); + t.end(); + }); + }); + testRunner.add('should unwind and flatten an object in the right order', (t) => { const opts = ' --unwind items --flatten'; diff --git a/test/JSON2CSVParser.js b/test/JSON2CSVParser.js index 49d4c3d4..c07e27c8 100644 --- a/test/JSON2CSVParser.js +++ b/test/JSON2CSVParser.js @@ -290,7 +290,7 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { }); - testRunner.add('should support flattenning deep JSON', (t) => { + testRunner.add('should support flattening deep JSON', (t) => { const opts = { flatten: true }; @@ -302,7 +302,7 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { t.end(); }); - testRunner.add('should support flattenning JSON with toJSON', (t) => { + testRunner.add('should support flattening JSON with toJSON', (t) => { const opts = { flatten: true }; @@ -314,6 +314,19 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { t.end(); }); + testRunner.add('should support custom flatten separator', (t) => { + const opts = { + flatten: true, + flattenSeparator: '__', + }; + + const parser = new Json2csvParser(opts); + const csv = parser.parse(jsonFixtures.deepJSON); + + t.equal(csv, csvFixtures.flattenedCustomSeparatorDeepJSON); + t.end(); + }); + testRunner.add('should unwind and flatten an object in the right order', (t) => { const opts = { unwind: ['items'], diff --git a/test/JSON2CSVTransform.js b/test/JSON2CSVTransform.js index 20db1937..0749bc21 100644 --- a/test/JSON2CSVTransform.js +++ b/test/JSON2CSVTransform.js @@ -435,7 +435,7 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { .on('error', err => t.notOk(true, err.message)); }); - testRunner.add('should support flattenning deep JSON', (t) => { + testRunner.add('should support flattening deep JSON', (t) => { const opts = { flatten: true };