From 5c22d0caf653102deea9eea8247bcc7e38a36784 Mon Sep 17 00:00:00 2001 From: Juanjo Diaz Date: Sat, 24 Feb 2018 11:48:37 +0200 Subject: [PATCH] Fix flatten issue with toJSON --- lib/JSON2CSVBase.js | 37 ++++++++++++++++++++++++++--- package-lock.json | 14 ++++------- package.json | 2 -- test/JSON2CSVParser.js | 12 ++++++++++ test/fixtures/csv/flattenToJSON.csv | 2 ++ test/fixtures/json/flattenToJSON.js | 13 ++++++++++ 6 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 test/fixtures/csv/flattenToJSON.csv create mode 100644 test/fixtures/json/flattenToJSON.js diff --git a/lib/JSON2CSVBase.js b/lib/JSON2CSVBase.js index 2225473c..f055f531 100644 --- a/lib/JSON2CSVBase.js +++ b/lib/JSON2CSVBase.js @@ -4,7 +4,6 @@ const os = require('os'); const lodashGet = require('lodash.get'); const lodashSet = require('lodash.set'); const lodashCloneDeep = require('lodash.clonedeep'); -const flatten = require('flat'); class JSON2CSVBase { constructor(opts) { @@ -64,7 +63,7 @@ class JSON2CSVBase { ? this.unwindData(row, this.opts.unwind) : [row]; if (this.opts.flatten) { - return processedRow.map(flatten); + return processedRow.map(this.flatten); } return processedRow; @@ -192,10 +191,42 @@ class JSON2CSVBase { return stringifiedValue; } + /** + * Performs the flattening of a data row recursively + * + * @param {Object} dataRow Original JSON object + * @returns {Object} Flattened object + */ + flatten(dataRow) { + function step (obj, flatDataRow, currentPath) { + Object.keys(obj).forEach((key) => { + const value = obj[key]; + + const newPath = currentPath + ? `${currentPath}.${key}` + : key; + + if (typeof value !== 'object' + || Array.isArray(value) + || Object.prototype.toString.call(value.toJSON) === '[object Function]' + || !Object.keys(value).length) { + flatDataRow[newPath] = value; + return; + } + + step(value, flatDataRow, newPath); + }); + + return flatDataRow; + } + + return step(dataRow, {}); + } + /** * Performs the unwind recursively in specified sequence * - * @param {Array} dataRow Original JSON object + * @param {Object} dataRow Original JSON object * @param {String[]} unwindPaths The paths as strings to be used to deconstruct the array * @returns {Array} Array of objects containing all rows after unwind of chosen paths */ diff --git a/package-lock.json b/package-lock.json index 006f5cd2..b44a062b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2622,14 +2622,6 @@ "pinkie-promise": "2.0.1" } }, - "flat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.0.0.tgz", - "integrity": "sha1-Orx/O1iOZM533EL9Wao1gGYi/qg=", - "requires": { - "is-buffer": "1.1.6" - } - }, "flat-arguments": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/flat-arguments/-/flat-arguments-1.0.2.tgz", @@ -4487,7 +4479,8 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true }, "is-builtin-module": { "version": "1.0.0", @@ -5078,7 +5071,8 @@ "lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true }, "lodash.foreach": { "version": "4.5.0", diff --git a/package.json b/package.json index d36c3a46..b3b79b2d 100644 --- a/package.json +++ b/package.json @@ -39,10 +39,8 @@ "dependencies": { "cli-table2": "^0.2.0", "commander": "^2.8.1", - "flat": "^4.0.0", "jsonparse": "^1.3.1", "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", "lodash.get": "^4.4.0", "lodash.set": "^4.3.0" }, diff --git a/test/JSON2CSVParser.js b/test/JSON2CSVParser.js index 270f7432..178bb885 100644 --- a/test/JSON2CSVParser.js +++ b/test/JSON2CSVParser.js @@ -275,6 +275,18 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { t.end(); }); + testRunner.add('should support flattenning JSON with toJSON', (t) => { + const opts = { + flatten: true + }; + + const parser = new Json2csvParser(opts); + const csv = parser.parse(jsonFixtures.flattenToJSON); + + t.equal(csv, csvFixtures.flattenToJSON); + t.end(); + }); + testRunner.add('should unwind and flatten an object in the right order', (t) => { const opts = { unwind: ['items'], diff --git a/test/fixtures/csv/flattenToJSON.csv b/test/fixtures/csv/flattenToJSON.csv new file mode 100644 index 00000000..ef386709 --- /dev/null +++ b/test/fixtures/csv/flattenToJSON.csv @@ -0,0 +1,2 @@ +"hello.world","lorem.ipsum.dolor" +"good afternoon","good evening" \ No newline at end of file diff --git a/test/fixtures/json/flattenToJSON.js b/test/fixtures/json/flattenToJSON.js new file mode 100644 index 00000000..034c722b --- /dev/null +++ b/test/fixtures/json/flattenToJSON.js @@ -0,0 +1,13 @@ +module.exports = { + hello: { + world: { + again: 'good morning', + toJSON: () =>'good afternoon' + } + }, + lorem: { + ipsum: { + dolor: 'good evening' + } + } +} \ No newline at end of file