json-2-csv
Advanced tools
Comparing version 0.1.1 to 0.1.2
'use strict'; | ||
var json2Csv = require('./json-2-csv'), | ||
csv2Json = require('./csv-2-json'); | ||
csv2Json = require('./csv-2-json'), | ||
_ = require('underscore'); | ||
var OPTIONS = function () { // Ensures fields don't change from our defaults | ||
return { | ||
DELIMITER : ',', | ||
EOL : '\n', | ||
PARSE_CSV_NUMBERS : false | ||
}; | ||
} | ||
var buildOptions = function (opts) { | ||
var out = _.extend(OPTIONS(), {}); | ||
if (!opts) { return out; } // If undefined or null, return defaults | ||
_.each(_.keys(opts), function (key) { | ||
if (out[key]) { // If key is valid, set it | ||
out[key] = opts[key]; | ||
} // Else ignore its value | ||
}); | ||
return out; // Return customized version | ||
}; | ||
module.exports = { | ||
json2csv: function (data, callback) { | ||
json2Csv.json2csv(data, callback); | ||
json2csv: function (array, callback, opts) { | ||
if (!opts) { opts = OPTIONS(); } | ||
else { opts = buildOptions(opts); } | ||
json2Csv.json2csv(opts, array, callback); | ||
}, | ||
csv2json: function (data, callback) { | ||
csv2Json.csv2json(data, callback); | ||
csv2json: function (csv, callback, opts) { | ||
if (!opts) { opts = OPTIONS(); } | ||
else { opts = buildOptions(opts); } | ||
csv2Json.csv2json(opts, csv, callback); | ||
} | ||
}; |
@@ -6,4 +6,3 @@ 'use strict'; | ||
var DELIMITER = ',', | ||
EOL = '\n'; | ||
var options = {}; | ||
@@ -15,3 +14,3 @@ var retrieveHeading = function (lines, callback) { | ||
var heading = lines[0]; // Grab the top line (header line) | ||
return heading.split(DELIMITER); // Return the heading split by the field delimiter | ||
return heading.split(options.DELIMITER); // Return the heading split by the field options.DELIMITER | ||
}; | ||
@@ -42,3 +41,4 @@ | ||
var doc = {}, | ||
line = line.trim().split(DELIMITER); | ||
val, | ||
line = line.trim().split(options.DELIMITER); | ||
if (line == '') { return false; } | ||
@@ -49,7 +49,7 @@ if (keys.length !== line.length) { | ||
_.each(keys, function (key, indx) { | ||
// TODO: check for case where some or all of nested key path already exists | ||
val = line[indx] === '' ? null : line[indx]; | ||
if (key.indexOf('.')) { // Key has '.' representing nested document | ||
doc = addNestedKey(key, line[indx], doc); // Update the doc | ||
doc = addNestedKey(key, val, doc); // Update the doc | ||
} else { | ||
doc[key] = line[indx]; | ||
doc[key] = val; | ||
} | ||
@@ -72,9 +72,11 @@ }); | ||
csv2json: function (data, callback) { | ||
if (!callback) { callback(new Error('A callback is required!')); } | ||
if (!data) { callback(new Error('Cannot call csv2json on ' + data)); } | ||
csv2json: function (opts, data, callback) { | ||
if (!callback) { throw new Error('A callback is required!'); } | ||
if (!opts) { callback(new Error('Options were not passed and are required.')); return null; } // Shouldn't happen, but just in case | ||
else { options = opts; } | ||
if (!data) { callback(new Error('Cannot call csv2json on ' + data)); return null; } | ||
if (typeof data !== 'string') { // CSV is not a string | ||
callback(new Error("CSV is not a string")); | ||
} | ||
var lines = data.split(EOL); | ||
var lines = data.split(options.EOL); | ||
var json = convertCSV(lines, callback); | ||
@@ -81,0 +83,0 @@ callback(null, json); |
@@ -6,4 +6,3 @@ 'use strict'; | ||
var DELIMITER = ',', | ||
EOL = '\n'; | ||
var options = {}; | ||
@@ -16,3 +15,3 @@ // Takes the parent heading and this doc's data and creates the subdocument headings (string) | ||
newKey = heading === '' ? subKey : heading + '.' + subKey; | ||
if (typeof data[subKey] === 'object') { // Another nested document | ||
if (typeof data[subKey] === 'object' && data[subKey] !== null) { // Another nested document | ||
subKeys[indx] = retrieveSubHeading(newKey, data[subKey]); | ||
@@ -23,3 +22,3 @@ } else { | ||
}); | ||
return subKeys.join(DELIMITER); | ||
return subKeys.join(options.DELIMITER); | ||
}; | ||
@@ -37,3 +36,3 @@ | ||
if (keys.length > 1) { throw new Error('Not all documents have the same schema.', keys); } | ||
cb(null, _.flatten(keys).join(DELIMITER)); | ||
cb(null, _.flatten(keys).join(options.DELIMITER)); | ||
}; | ||
@@ -54,3 +53,3 @@ }; | ||
}); | ||
return output.join(DELIMITER); | ||
return output.join(options.DELIMITER); | ||
}; | ||
@@ -60,3 +59,3 @@ | ||
return function (cb) { | ||
return cb(null, _.reduce(data, function (csv, doc) { return csv += convertData(doc, _.keys(doc)) + EOL; }, '')); | ||
return cb(null, _.reduce(data, function (csv, doc) { return csv += convertData(doc, _.keys(doc)) + options.EOL; }, '')); | ||
}; | ||
@@ -67,5 +66,7 @@ }; | ||
json2csv: function (data, callback) { | ||
json2csv: function (opts, data, callback) { | ||
if (!callback) { throw new Error('A callback is required!'); } | ||
if (!data) { throw new Error('Cannot call json2csv on ' + data); } | ||
if (!opts) { callback(new Error('Options were not passed and are required.')); return null; } // Shouldn't happen, but just in case | ||
else { options = opts; } | ||
if (!data) { callback(new Error('Cannot call json2csv on ' + data)); return null; } | ||
if (typeof data === 'object' && !data.length) { // Single document, not an array | ||
@@ -76,3 +77,3 @@ data = [data]; // Convert to an array of the given document | ||
if (!err) { | ||
callback(null, res.join(EOL)); | ||
callback(null, res.join(options.EOL)); | ||
} else { | ||
@@ -79,0 +80,0 @@ callback(err, null); |
@@ -1,23 +0,12 @@ | ||
//var t = require('./converter'); | ||
// | ||
//t.json2csv([{'test':{'a':1, 'b':2}, 'var':3}], function (err, csv) { | ||
// if (err) throw err; | ||
// t.csv2json(csv, function (err, json) { | ||
// if (err) throw err; | ||
// console.log(typeof json); | ||
// }); | ||
// } | ||
//); | ||
var t = require('./converter'); | ||
var converter = require('./converter'); | ||
var csv = "" | ||
var csv2jsonCallback = function (err, json) { | ||
t.json2csv({ | ||
'name': 'mrodrig', | ||
'email': null, | ||
'country': 'USA', | ||
'githubUsername': 'mrodrig' | ||
}, function (err, csv) { | ||
if (err) throw err; | ||
console.log(typeof json); | ||
console.log(json.length); | ||
console.log(json); | ||
} | ||
converter.csv2json(csv, csv2jsonCallback); | ||
console.log(csv); | ||
} | ||
); |
{ | ||
"author": "mrodrig", | ||
"name": "json-2-csv", | ||
"description": "A JSON to CSV converter that natively supports sub-documents and auto-generates the heading.", | ||
"version": "0.1.1", | ||
"description": "A JSON to CSV and CSV to JSON converter that natively supports sub-documents and auto-generates the CSV heading.", | ||
"version": "0.1.2", | ||
"repository": { | ||
@@ -7,0 +7,0 @@ "type": "git", |
@@ -23,6 +23,10 @@ # Convert JSON to CSV or CSV to JSON | ||
#### json2csv(array, callback) | ||
#### json2csv(array, callback, options) | ||
* `array` - An array of JSON documents | ||
* `callback` - A function of the form `function (err, csv)`; This function will receive any errors and/or the CSV generated. | ||
* `options` - (Optional) A JSON document specifying any of {`DELIMITER`, `EOL`, `PARSE_CSV_NUMBERS`} | ||
** `DELIMITER` - String - Field Delimiter. Default: `','` | ||
** `EOL` - String - End of Line Delimiter. Default: `'\n'` | ||
** `PARSE_CSV_NUMBERS` - Boolean - Should numbers that are found in the CSV be converted to numbers? Default: `false` | ||
@@ -73,6 +77,10 @@ ##### json2csv Example: | ||
#### csv2json(csv, callback) | ||
#### csv2json(csv, callback, options) | ||
* `csv` - A string of CSV | ||
* `callback` - A function of the form `function (err, array)`; This function will receive any errors and/or the array of JSON documents generated. | ||
* `options` - (Optional) A JSON document specifying any of {`DELIMITER`, `EOL`, `PARSE_CSV_NUMBERS`} | ||
** `DELIMITER` - String - Field Delimiter. Default: `','` | ||
** `EOL` - String - End of Line Delimiter. Default: `'\n'` | ||
** `PARSE_CSV_NUMBERS` - Boolean - Should numbers that are found in the CSV be converted to numbers? Default: `false` | ||
@@ -113,3 +121,2 @@ ##### csv2json Example: | ||
## Tests | ||
@@ -121,3 +128,3 @@ | ||
_Note_: This requires `mocha`, `should`, and `async`. | ||
_Note_: This requires `mocha`, `should`, `async`, and `underscore`. | ||
@@ -130,2 +137,4 @@ ## Features | ||
- Custom ordering of columns (see F.A.Q. for more information) | ||
- Ability to re-generate the JSON documents that were used to generate the CSV (including nested documents) | ||
- Allows for custom field delimiters, end of line delimiters, etc. | ||
@@ -138,4 +147,3 @@ ## F.A.Q. | ||
## TODO | ||
- Add more tests | ||
- Get csv2json under test | ||
- Add more documentation | ||
- Add more comments to code | ||
- Use PARSE_CSV_NUMBERS option to actually convert numbers. Not currently implemented. |
@@ -5,4 +5,4 @@ [ | ||
"priceRange": { | ||
"min": 9000, | ||
"max": 11000 | ||
"min": "9000", | ||
"max": "11000" | ||
} | ||
@@ -13,4 +13,4 @@ }, | ||
"priceRange": { | ||
"min": 14000, | ||
"max": 16000 | ||
"min": "14000", | ||
"max": "16000" | ||
} | ||
@@ -21,4 +21,4 @@ }, | ||
"priceRange": { | ||
"min": 19000, | ||
"max": 21000 | ||
"min": "19000", | ||
"max": "21000" | ||
} | ||
@@ -29,6 +29,6 @@ }, | ||
"priceRange": { | ||
"min": 29000, | ||
"max": 31000 | ||
"min": "29000", | ||
"max": "31000" | ||
} | ||
} | ||
] | ||
] |
@@ -20,2 +20,2 @@ [ | ||
} | ||
] | ||
] |
@@ -1,1 +0,1 @@ | ||
[] | ||
[] |
[ | ||
{ "carModel" : "Audi", "price" : 10000, "color" : "blue" } | ||
, { "carModel" : "BMW", "price" : 15000, "color" : "red" } | ||
, { "carModel" : "Mercedes", "price" : 20000, "color" : "yellow" } | ||
, { "carModel" : "Porsche", "price" : 30000, "color" : "green" } | ||
] | ||
{ "carModel" : "Audi", "price" : "10000", "color" : "blue" }, | ||
{ "carModel" : "BMW", "price" : "15000", "color" : "red" }, | ||
{ "carModel" : "Mercedes", "price" : "20000", "color" : "yellow" }, | ||
{ "carModel" : "Porsche", "price" : "30000", "color" : "green" } | ||
] |
var should = require('should'), | ||
json2csv = require('.././lib/json-2-csv'), | ||
fs = require('fs'), | ||
commaTests = require('./testComma'), | ||
semiTests = require('./testSemi'), | ||
_ = require('underscore'), | ||
async = require('async'); | ||
var in_regularJson = require('./JSON/regularJson'), | ||
in_nestedJson = require('./JSON/nestedJson'), | ||
in_nestedJson2 = require('./JSON/nestedJson2'), | ||
in_nestedQuotes = require('./JSON/nestedQuotes'), | ||
in_noData = require('./JSON/noData.json'), | ||
out_regularJson = '', | ||
out_nestedJson = '', | ||
out_nestedJson2 = '', | ||
out_nestedQuotes = '', | ||
out_noData = ''; | ||
describe('json-2-csv', function() { | ||
before(function(done) { | ||
async.parallel([ | ||
function(callback) { | ||
fs.readFile('test/CSV/regularJson.csv', function(err, data) { | ||
if (err) callback(err); | ||
out_regularJson = data.toString(); | ||
callback(null); | ||
}); | ||
}, | ||
function(callback) { | ||
fs.readFile('test/CSV/nestedJson.csv', function(err, data) { | ||
if (err) callback(err); | ||
out_nestedJson = data.toString(); | ||
callback(null); | ||
}); | ||
}, | ||
function(callback) { | ||
fs.readFile('test/CSV/nestedJson2.csv', function(err, data) { | ||
if (err) callback(err); | ||
out_nestedJson2 = data.toString(); | ||
callback(null); | ||
}); | ||
}, | ||
function(callback) { | ||
fs.readFile('test/CSV/nestedQuotes.csv', function(err, data) { | ||
if (err) callback(err); | ||
out_nestedQuotes = data.toString(); | ||
callback(null); | ||
}); | ||
}, | ||
function(callback) { | ||
fs.readFile('test/CSV/noData.csv', function (err, data) { | ||
if (err) callback(err); | ||
out_noData = data.toString(); | ||
callback(null); | ||
}) | ||
} | ||
], | ||
function(err, results) { | ||
if (err) console.log(err); | ||
done(); | ||
} | ||
); | ||
}); | ||
it('should convert plain JSON to CSV', function(done) { | ||
json2csv.json2csv(in_regularJson, function(err, csv) { | ||
csv.should.equal(out_regularJson); | ||
done(); | ||
}) | ||
}); | ||
it('should parse nested JSON to CSV - 1', function(done) { | ||
json2csv.json2csv(in_nestedJson, function(err, csv) { | ||
csv.should.equal(out_nestedJson); | ||
done(); | ||
}) | ||
}); | ||
it('should parse nested JSON to CSV - 2', function(done) { | ||
json2csv.json2csv(in_nestedJson2, function(err, csv) { | ||
csv.should.equal(out_nestedJson2); | ||
done(); | ||
}) | ||
}); | ||
it('should parse nested quotes in JSON to have quotes in CSV', function(done) { | ||
json2csv.json2csv(in_nestedQuotes, function(err, csv) { | ||
csv.should.equal(out_nestedQuotes); | ||
done(); | ||
}) | ||
}); | ||
it('should parse an empty array to an empty CSV', function(done) { | ||
json2csv.json2csv(in_noData, function(err, csv) { | ||
csv.should.equal(out_noData); | ||
done(); | ||
}) | ||
}); | ||
}); | ||
describe('json-2-csv Module', function() { | ||
commaTests.runTests(); | ||
semiTests.runTests(); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
105229
32
1169
143
2