Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

jsonexport

Package Overview
Dependencies
Maintainers
3
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsonexport - npm Package Compare versions

Comparing version 2.5.2 to 3.0.0

tests/promise.js

3

CHANGELOG.md
## Change log
----------------------
- v3.0.0 - Promise API & fillTopRow
- v2.5.2 - fix stream memory limit (issue #64)
- v2.5.1 - security fixes (npm audit)
- v2.5.0 - Fixed nester array issue
- v2.5.0 - fix nested array issue
- v2.3.0 - added mapHeaders option

@@ -7,0 +8,0 @@ - ran npm audit fix

@@ -8,5 +8,8 @@ /* jshint node:true */

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var Parser = require('./parser/csv');
var Stream = require('./core/stream');
var helper = require('./core/helper');
var EOL = require('./core/eol');

@@ -22,11 +25,78 @@ /**

*/
module.exports = function (json, userOptions, callback) {
if (helper.isFunction(userOptions)) {
callback = userOptions;
userOptions = {};
module.exports = function () {
var DEFAULT_OPTIONS = {
headers: [], // Array
rename: [], // Array
headerPathString: '.', // String
rowDelimiter: ',', // String
textDelimiter: '"', // String
arrayPathString: ';', // String
undefinedString: '', // String
endOfLine: EOL || '\n', // String
mainPathItem: null, // String
booleanTrueString: null, // String
booleanFalseString: null, // String
includeHeaders: true, // Boolean
fillGaps: false, // Boolean
verticalOutput: true, // Boolean
forceTextDelimiter: false //Boolean
};
// argument parsing
var json = void 0,
userOptions = void 0,
callback = void 0;
if (arguments.length === 3) {
var _arguments = Array.prototype.slice.call(arguments);
json = _arguments[0];
userOptions = _arguments[1];
callback = _arguments[2];
} else if (arguments.length === 2) {
var any = void 0;
var _arguments2 = Array.prototype.slice.call(arguments);
json = _arguments2[0];
any = _arguments2[1];
if (typeof any === 'function') {
callback = any;
} else if ((typeof any === 'undefined' ? 'undefined' : _typeof(any)) === 'object') {
userOptions = any;
}
} else if (arguments.length === 1) {
var _arguments3 = Array.prototype.slice.call(arguments),
_any = _arguments3[0];
if ((typeof _any === 'undefined' ? 'undefined' : _typeof(_any)) === 'object') {
var defaultKeys = Object.keys(DEFAULT_OPTIONS);
var objectKeys = Object.keys(_any);
var isOptions = objectKeys.every(function (key) {
return defaultKeys.includes(key);
});
if (objectKeys.length > 0 && isOptions) {
userOptions = _any;
} else {
json = _any;
}
} else {
json = _any;
}
} else {
return new Stream(new Parser(DEFAULT_OPTIONS));
}
userOptions = !callback ? json : userOptions;
var parser = new Parser(userOptions);
if (!callback || !helper.isFunction(callback)) return new Stream(parser);
parser.parse(json, callback);
var options = Object.assign({}, DEFAULT_OPTIONS, userOptions);
var parser = new Parser(options);
// if no json is provided Stream API will be used
if (!json) {
return new Stream(parser);
}
// always return an promise
return new Promise(function (resolve, reject) {
parser.parse(json, function (err, result) {
if (callback) return callback(err, result);
if (err) return reject(err);
if (reject) return resolve(result);
});
});
};

@@ -12,3 +12,2 @@ /* jshint node:true */

var EOL = require('../core/eol');
var joinRows = require('../core/join-rows');

@@ -22,3 +21,3 @@ var Handler = require('./handler');

this._options = this._parseOptions(options) || {};
this._options = options || {};
this._handler = new Handler(this._options);

@@ -132,3 +131,3 @@ this._headers = this._options.headers || [];

// make sure there isnt a empty row for this header
if (emptyRowIndexByHeader[elementHeaderIndex] < rows.length) {
if (self._options.fillTopRow && emptyRowIndexByHeader[elementHeaderIndex] < rows.length) {
rows[emptyRowIndexByHeader[elementHeaderIndex]][elementHeaderIndex] = self._escape(element.value);

@@ -233,37 +232,3 @@ emptyRowIndexByHeader[elementHeaderIndex] += 1;

}
/**
* Replaces the default options with the custom user options
*
* @param {Options} userOptions
*/
}, {
key: '_parseOptions',
value: function _parseOptions(userOptions) {
var defaultOptions = {
headers: [], // Array
rename: [], // Array
headerPathString: '.', // String
rowDelimiter: ',', // String
textDelimiter: '"', // String
arrayPathString: ';', // String
undefinedString: '', // String
endOfLine: EOL || '\n', // String
mainPathItem: null, // String
booleanTrueString: null, // String
booleanFalseString: null, // String
includeHeaders: true, // Boolean
fillGaps: false, // Boolean
verticalOutput: true, // Boolean
forceTextDelimiter: false, //Boolean
//Handlers
handleString: undefined, // Function
handleNumber: undefined, // Function
handleBoolean: undefined, // Function
handleDate: undefined // Function
};
return Object.assign({}, defaultOptions, userOptions);
}
}, {
key: 'headers',

@@ -270,0 +235,0 @@ get: function get() {

@@ -18,10 +18,4 @@ /* jshint node:true */

//an object of {typeName:(value,index,parent)=>any}
// an object of {typeName:(value,index,parent)=>any}
this._options.typeHandlers = this._options.typeHandlers || {};
//deprecated options
this._options.handleString = this._options.handleString ? warnDepOp('handleString', this._options.handleString) : this._handleString;
this._options.handleNumber = this._options.handleNumber ? warnDepOp('handleNumber', this._options.handleNumber) : this._handleNumber;
this._options.handleBoolean = this._options.handleBoolean ? warnDepOp('handleBoolean', this._options.handleBoolean) : this._handleBoolean;
this._options.handleDate = this._options.handleDate ? warnDepOp('handleDate', this._options.handleDate) : this._handleDate;
}

@@ -99,4 +93,3 @@

element = this.castValue(element, item, index, parent);
//try simple value by highier performance switch
// try simple value by highier performance switch
switch (typeof element === 'undefined' ? 'undefined' : _typeof(element)) {

@@ -106,3 +99,3 @@ case 'string':

item: item,
value: this._options.handleString(element, item)
value: this._handleString(element, item)
}];

@@ -113,3 +106,3 @@

item: item,
value: this._options.handleNumber(element, item)
value: this._handleNumber(element, item)
}];

@@ -120,3 +113,3 @@

item: item,
value: this._options.handleBoolean.bind(this)(element, item)
value: this._handleBoolean.bind(this)(element, item)
}];

@@ -243,7 +236,2 @@ }

function warnDepOp(optionName, backOut) {
console.warn("[jsonexport]: option " + optionName + " has been deprecated. Use option.typeHandlers");
return backOut;
}
var globalScope = typeof window === "undefined" ? global : window;

@@ -250,0 +238,0 @@ function isInstanceOfTypeName(element, typeName) {

@@ -10,2 +10,3 @@ /* jshint node:true */

const helper = require('./core/helper');
const EOL = require('./core/eol');

@@ -21,11 +22,63 @@ /**

*/
module.exports = function(json, userOptions, callback) {
if (helper.isFunction(userOptions)) {
callback = userOptions;
userOptions = {};
module.exports = function() {
const DEFAULT_OPTIONS = {
headers: [], // Array
rename: [], // Array
headerPathString: '.', // String
rowDelimiter: ',', // String
textDelimiter: '"', // String
arrayPathString: ';', // String
undefinedString: '', // String
endOfLine: EOL || '\n', // String
mainPathItem: null, // String
booleanTrueString: null, // String
booleanFalseString: null, // String
includeHeaders: true, // Boolean
fillGaps: false, // Boolean
verticalOutput: true, // Boolean
forceTextDelimiter: false, //Boolean
};
// argument parsing
let json, userOptions, callback;
if (arguments.length === 3) {
[json, userOptions, callback] = arguments;
} else if (arguments.length === 2) {
let any;
[json, any] = arguments;
if (typeof any === 'function') {
callback = any;
} else if (typeof any === 'object') {
userOptions = any;
}
} else if (arguments.length === 1) {
const [any] = arguments;
if (typeof any === 'object') {
const defaultKeys = Object.keys(DEFAULT_OPTIONS);
const objectKeys = Object.keys(any);
const isOptions = objectKeys.every((key) => defaultKeys.includes(key));
if (objectKeys.length > 0 && isOptions) {
userOptions = any;
} else {
json = any;
}
} else {
json = any;
}
} else {
return new Stream(new Parser(DEFAULT_OPTIONS));
}
userOptions = !callback ? json : userOptions;
let parser = new Parser(userOptions);
if (!callback || !helper.isFunction(callback)) return new Stream(parser);
parser.parse(json, callback);
const options = Object.assign({}, DEFAULT_OPTIONS, userOptions);
const parser = new Parser(options);
// if no json is provided Stream API will be used
if (!json) {
return new Stream(parser);
}
// always return an promise
return new Promise((resolve, reject) => {
parser.parse(json, (err, result) => {
if (callback) return callback(err, result);
if (err) return reject(err);
if (reject) return resolve(result);
});
});
};

@@ -7,3 +7,2 @@ /* jshint node:true */

*/
const EOL = require('../core/eol')
const joinRows = require('../core/join-rows');

@@ -15,3 +14,3 @@ const Handler = require('./handler');

constructor(options) {
this._options = this._parseOptions(options) || {};
this._options = options || {};
this._handler = new Handler(this._options);

@@ -105,3 +104,3 @@ this._headers = this._options.headers || [];

// make sure there isnt a empty row for this header
if (emptyRowIndexByHeader[elementHeaderIndex] < rows.length) {
if (self._options.fillTopRow && emptyRowIndexByHeader[elementHeaderIndex] < rows.length) {
rows[emptyRowIndexByHeader[elementHeaderIndex]][elementHeaderIndex] = self._escape(element.value);

@@ -173,35 +172,4 @@ emptyRowIndexByHeader[elementHeaderIndex] += 1;

}
/**
* Replaces the default options with the custom user options
*
* @param {Options} userOptions
*/
_parseOptions(userOptions) {
let defaultOptions = {
headers: [], // Array
rename: [], // Array
headerPathString: '.', // String
rowDelimiter: ',', // String
textDelimiter: '"', // String
arrayPathString: ';', // String
undefinedString: '', // String
endOfLine: EOL || '\n', // String
mainPathItem: null, // String
booleanTrueString: null, // String
booleanFalseString: null, // String
includeHeaders: true, // Boolean
fillGaps: false, // Boolean
verticalOutput: true, // Boolean
forceTextDelimiter: false, //Boolean
//Handlers
handleString: undefined, // Function
handleNumber: undefined, // Function
handleBoolean: undefined, // Function
handleDate: undefined, // Function
};
return Object.assign({}, defaultOptions, userOptions);
}
}
module.exports = Parser;
module.exports = Parser;

@@ -10,10 +10,4 @@ /* jshint node:true */

//an object of {typeName:(value,index,parent)=>any}
// an object of {typeName:(value,index,parent)=>any}
this._options.typeHandlers = this._options.typeHandlers || {};
//deprecated options
this._options.handleString = this._options.handleString ? warnDepOp('handleString', this._options.handleString) : this._handleString;
this._options.handleNumber = this._options.handleNumber ? warnDepOp('handleNumber', this._options.handleNumber) : this._handleNumber;
this._options.handleBoolean = this._options.handleBoolean ? warnDepOp('handleBoolean', this._options.handleBoolean) : this._handleBoolean;
this._options.handleDate = this._options.handleDate ? warnDepOp('handleDate', this._options.handleDate) : this._handleDate;
}

@@ -82,4 +76,3 @@

element = this.castValue(element, item, index, parent);
//try simple value by highier performance switch
// try simple value by highier performance switch
switch(typeof element){

@@ -89,3 +82,3 @@ case 'string':

item: item,
value: this._options.handleString(element, item),
value: this._handleString(element, item),
}];

@@ -96,3 +89,3 @@

item: item,
value: this._options.handleNumber(element, item),
value: this._handleNumber(element, item),
}];

@@ -103,3 +96,3 @@

item: item,
value: this._options.handleBoolean.bind(this)(element, item),
value: this._handleBoolean.bind(this)(element, item),
}];

@@ -207,7 +200,2 @@ }

function warnDepOp(optionName, backOut){
console.warn("[jsonexport]: option "+optionName+" has been deprecated. Use option.typeHandlers");
return backOut;
}
const globalScope = typeof(window)==="undefined" ? global : window;

@@ -227,2 +215,2 @@ function isInstanceOfTypeName(element, typeName){

return false;
}
}
{
"name": "jsonexport",
"version": "2.5.2",
"version": "3.0.0",
"description": "Makes easy to convert JSON to CSV",

@@ -5,0 +5,0 @@ "main": "./lib",

@@ -11,2 +11,3 @@ # jsonexport {} → 📄

[![Try jsonexport on RunKit](https://badge.runkitcdn.com/jsonexport.svg)](https://npm.runkit.com/jsonexport)
![npm bundle size](https://img.shields.io/bundlephobia/minzip/jsonexport)

@@ -17,3 +18,3 @@ ✔ **easy to use** 👌 (should work as expected without much customization)️

✔️ **tiny** 🐜 (0 dependencies)
✔️ **tiny** 🐜 (0 dependencies)

@@ -24,5 +25,5 @@ ✔ **scalable** 💪 (works with big files using Streams)

[Project Page](http://kauegimenes.github.io/jsonexport/)
[Project Page](https://kauegimenes.github.io/jsonexport/)
[Online Demo Page](http://kauegimenes.github.io/jsonexport/demo/)
[Online Demo Page](https://kauegimenes.github.io/jsonexport/demo/)

@@ -37,2 +38,3 @@ <details>

- [Stream](#stream)
- [Promise](#promise)
- [JSON Array Example](#json-array-example)

@@ -98,2 +100,13 @@ - [Simple Array](#simple-array)

## Promise
```javascript
const jsonexport = require('jsonexport')
try {
const csv = await jsonexport({lang: 'Node.js', module: 'jsonexport'}, {rowDelimiter: '|'});
} catch (err) {
console.error(err);
}
```
## JSON Array Example

@@ -258,2 +271,3 @@

- `fillGaps` - `Boolean` Set this option if don't want to have empty cells in case of an object with multiple nested items (array prop), defaults to `false` [Issue #22](https://github.com/kauegimenes/jsonexport/issues/22)
- `fillTopRow` - `Boolean` try filling top rows first for unpopular colums, defaults to `false`
- `headers` - `Array` Used to set a custom header order, defaults to `[]` example `['lastname', 'name']`

@@ -278,9 +292,2 @@ - `rename` - `Array` Used to set a custom header text, defaults to `[]` example `['Last Name', 'Name']`

**Deprecated Options** (Use typeHandlers)
- `handleString` - `Function` Use this to customize all `Strings` in the CSV file.
- `handleNumber` - `Function` Use this to customize all `Numbers` in the CSV file.
- `handleBoolean` - `Function` Use this to customize all `Booleans` in the CSV file.
- `handleDate` - `Function` Use this to customize all `Dates` in the CSV file. (default to date.toLocaleString)
#### typeHandlers

@@ -338,3 +345,22 @@ Define types by constructors and what function to run when that type is matched

Date typeHandler?
```javascript
var date = new Date();
jsonexport({
a: date,
b: true
}, {
typeHandlers: {
Object: (value, name) => {
if (value instanceof Date) return date.toLocaleString();
return value;
}
}
}, (err, csv) => {
if (err) return console.error(err);
console.log(csv);
});
```
When using **typeHandlers**, Do NOT do this

@@ -341,0 +367,0 @@

@@ -70,3 +70,3 @@ /* jshint node:true */

}], {}, (err, csv) => {
expect(csv).to.equal(`a.b,a.c.d,a.e.f${os.EOL}true,1,1${os.EOL},2,2${os.EOL},3,${os.EOL},4,`);
expect(csv).to.equal(`a.b,a.c.d,a.e.f${os.EOL}true,1,${os.EOL},2,${os.EOL},3,${os.EOL},4,1${os.EOL},,2`);
});

@@ -73,0 +73,0 @@ });

@@ -43,2 +43,33 @@ var chai = require('chai');

});
it('fillTopRow', () => {
jsonexport([{
a: {
b: true,
c: [{
d: 1
},
{
d: 2
},
{
d: 3
},
{
d: 4
}
],
e: [{
f: 1
},
{
f: 2
}
]
}
}], {
fillTopRow: true,
}, (err, csv) => {
expect(csv).to.equal(`a.b,a.c.d,a.e.f${os.EOL}true,1,1${os.EOL},2,2${os.EOL},3,${os.EOL},4,`);
});
});
it('mapHeaders', () => {

@@ -186,4 +217,4 @@ jsonexport([{

});
describe.skip('Handlers', () => {
it('handleString', () => {
describe('Type Handlers', () => {
it('String', () => {
jsonexport({

@@ -193,3 +224,5 @@ a: 'test',

}, {
handleString: (value, name) => value + "|||"
typeHandlers: {
String: (value) => value + "|||"
}
}, (err, csv) => {

@@ -199,3 +232,3 @@ expect(csv).to.have.string('a,test|||');

});
it('handleNumber', () => {
it('Number', () => {
jsonexport({

@@ -205,3 +238,5 @@ a: 1,

}, {
handleNumber: (value, name) => value + "|||"
typeHandlers: {
Number: (value) => value + "|||"
}
}, (err, csv) => {

@@ -211,3 +246,3 @@ expect(csv).to.have.string('a,1|||');

});
it('handleBoolean', () => {
it('Boolean', () => {
jsonexport({

@@ -217,3 +252,5 @@ a: true,

}, {
handleBoolean: (value, name) => value + "|||"
typeHandlers: {
Boolean: (value, name) => value + "|||"
}
}, (err, csv) => {

@@ -223,3 +260,3 @@ expect(csv).to.have.string('a,true|||');

});
it('handleDate', () => {
it('Date', (done) => {
var date = new Date();

@@ -230,5 +267,11 @@ jsonexport({

}, {
handleDate: (value, name) => value + "|||"
typeHandlers: {
Object: (value, name) => {
if (value instanceof Date) return date + '|||';
return value;
}
}
}, (err, csv) => {
expect(csv).to.have.string('a,' + date + '|||');
done();
});

@@ -235,0 +278,0 @@ });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc