Socket
Socket
Sign inDemoInstall

csv-stringify

Package Overview
Dependencies
Maintainers
1
Versions
84
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

csv-stringify - npm Package Compare versions

Comparing version 5.0.0 to 5.1.0

samples/option.cast.js

41

CHANGELOG.md
# Changelog
## Version 5.1.0
Fix:
* header: ensure column definition
New features
* cast: pass context to functions
Minor enhancements:
* write: validate written records
* src: extends stream class
Project Management:
* package: latest dev dependencies
## Version 5.0.0

@@ -8,4 +27,4 @@

* cast: was formatters
* record_delimiter: was row_delimiter
* `cast`: was `formatters`
* `record_delimiter`: was `row_delimiter`
* options: instance options stored in underscore form

@@ -16,3 +35,3 @@ * nodejs: drop support for version 7, use './lib/es5'

* quoted_match: new option
* `quoted_match`: new option
* options: accept underscore and camelcase forms

@@ -41,3 +60,3 @@

* formatter: new string formatter
* `formatters`: new string formatter
* stream: be a much better transform citizen

@@ -48,3 +67,3 @@ * package: upgrade to babel 7

* columns: support array with column definition objects
* `columns`: support array with column definition objects
* travis: support Node.js 10

@@ -63,11 +82,11 @@ * samples: new formatters script

* formatters: rename bool to boolean
* `formatters`: rename bool to boolean
New features:
* formatters: handle number
* `formatters`: handle number
Cleanup
* src: cache call to typeof
* src: cache call to `typeof`
* package: latest dependencies

@@ -85,3 +104,3 @@

* Switch linebreak check for rowDelimiter check
* Switch linebreak check for `rowDelimiter` check

@@ -91,3 +110,3 @@ ## Version 2.1.0

* package: allow empty quote value
* package: add ascii option for rowDelimiter
* package: add ascii option for `rowDelimiter`

@@ -123,2 +142,2 @@ ## Version 2.0.4

* test: should require handled by mocha
* package: coffeescript 2 and use semver tilde
* package: CoffeeScript 2 and use of semver tilde
"use strict";
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

@@ -9,2 +17,18 @@

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
// Generated by CoffeeScript 2.3.2

@@ -14,4 +38,3 @@ // # CSV Stringifier

// information.
var _Stringifier, get, stream, underscore, util;
var Stringifier, get, stream, underscore, util;
stream = require('stream');

@@ -58,3 +81,3 @@ util = require('util');

stringifier = new _Stringifier(options);
stringifier = new Stringifier(options);

@@ -109,449 +132,559 @@ if (data) {

_Stringifier = function Stringifier() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var base, base1, base2, base3, base4, isRegExp, isString, j, k, len, options, quoted_match, ref, v;
stream.Transform.call(this, _objectSpread({}, options, {
writableObjectMode: true
}));
options = {};
Stringifier =
/*#__PURE__*/
function (_stream$Transform) {
_inherits(Stringifier, _stream$Transform);
for (k in opts) {
v = opts[k]; // Immutable options and camelcase conversion
function Stringifier() {
var _this;
options[underscore(k)] = v;
} //# Default options
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Stringifier);
if (options.delimiter == null) {
options.delimiter = ',';
}
var base, base1, base2, base3, base4, isRegExp, isString, j, k, len, options, quoted_match, ref, v;
_this = _possibleConstructorReturn(this, _getPrototypeOf(Stringifier).call(this, _objectSpread({}, {
writableObjectMode: true
}, options)));
options = {};
if (options.quote == null) {
options.quote = '"';
}
for (k in opts) {
v = opts[k]; // Immutable options and camelcase conversion
if (options.quoted == null) {
options.quoted = false;
}
options[underscore(k)] = v;
} //# Default options
if (options.quoted_empty == null) {
options.quoted_empty = void 0;
}
if (options.quoted_string == null) {
options.quoted_string = false;
}
if (options.delimiter == null) {
options.delimiter = ',';
}
if (options.eof == null) {
options.eof = true;
}
if (options.quote == null) {
options.quote = '"';
}
if (options.escape == null) {
options.escape = '"';
}
if (options.quoted == null) {
options.quoted = false;
}
if (options.header == null) {
options.header = false;
} // Normalize the columns option
if (options.quoted_empty == null) {
options.quoted_empty = void 0;
}
if (options.quoted_string == null) {
options.quoted_string = false;
}
options.columns = _Stringifier.normalize_columns(options.columns);
if (options.eof == null) {
options.eof = true;
}
if (options.cast == null) {
options.cast = {};
} // Normalize option `quoted_match`
if (options.escape == null) {
options.escape = '"';
}
if (options.header == null) {
options.header = false;
} // Normalize the columns option
if (options.quoted_match === void 0 || options.quoted_match === null || options.quoted_match === false) {
options.quoted_match = null;
} else if (!Array.isArray(options.quoted_match)) {
options.quoted_match = [options.quoted_match];
}
if (options.quoted_match) {
ref = options.quoted_match;
options.columns = _this.normalize_columns(options.columns);
for (j = 0, len = ref.length; j < len; j++) {
quoted_match = ref[j];
isString = typeof quoted_match === 'string';
isRegExp = quoted_match instanceof RegExp;
if (options.cast == null) {
options.cast = {};
} // Normalize option `quoted_match`
if (!isString && !isRegExp) {
throw Error("Invalid Option: quoted_match must be a string or a regex, got ".concat(JSON.stringify(quoted_match)));
}
if (options.quoted_match === void 0 || options.quoted_match === null || options.quoted_match === false) {
options.quoted_match = null;
} else if (!Array.isArray(options.quoted_match)) {
options.quoted_match = [options.quoted_match];
}
}
if (options.cast.bool) {
// Backward compatibility
options.cast.boolean = options.cast.bool;
} // Custom cast
if (options.quoted_match) {
ref = options.quoted_match;
for (j = 0, len = ref.length; j < len; j++) {
quoted_match = ref[j];
isString = typeof quoted_match === 'string';
isRegExp = quoted_match instanceof RegExp;
if ((base = options.cast).string == null) {
base.string = function (value) {
return value;
};
}
if (!isString && !isRegExp) {
throw Error("Invalid Option: quoted_match must be a string or a regex, got ".concat(JSON.stringify(quoted_match)));
}
}
}
if ((base1 = options.cast).date == null) {
base1.date = function (value) {
// Cast date to timestamp string by default
return '' + value.getTime();
};
}
if (options.cast.bool) {
// Backward compatibility
options.cast.boolean = options.cast.bool;
} // Custom cast
if ((base2 = options.cast).boolean == null) {
base2.boolean = function (value) {
// Cast boolean to string by default
if (value) {
return '1';
} else {
return '';
}
};
}
if ((base3 = options.cast).number == null) {
base3.number = function (value) {
// Cast number to string using native casting by default
return '' + value;
};
}
if ((base = options.cast).string == null) {
base.string = function (value) {
return value;
};
}
if ((base4 = options.cast).object == null) {
base4.object = function (value) {
// Stringify object as JSON by default
return JSON.stringify(value);
};
}
if ((base1 = options.cast).date == null) {
base1.date = function (value) {
// Cast date to timestamp string by default
return '' + value.getTime();
};
}
if (options.record_delimiter === void 0 || options.record_delimiter === null || options.record_delimiter === false) {
if (options.record_delimiter == null) {
options.record_delimiter = '\n';
if ((base2 = options.cast).boolean == null) {
base2.boolean = function (value) {
// Cast boolean to string by default
if (value) {
return '1';
} else {
return '';
}
};
}
} else if (typeof options.record_delimiter === 'string') {
switch (options.record_delimiter) {
case 'auto':
options.record_delimiter = null;
break;
case 'unix':
options.record_delimiter = "\n";
break;
if ((base3 = options.cast).number == null) {
base3.number = function (value) {
// Cast number to string using native casting by default
return '' + value;
};
}
case 'mac':
options.record_delimiter = "\r";
break;
if ((base4 = options.cast).object == null) {
base4.object = function (value) {
// Stringify object as JSON by default
return JSON.stringify(value);
};
}
case 'windows':
options.record_delimiter = "\r\n";
break;
if (options.record_delimiter === void 0 || options.record_delimiter === null || options.record_delimiter === false) {
if (options.record_delimiter == null) {
options.record_delimiter = '\n';
}
} else if (typeof options.record_delimiter === 'string') {
switch (options.record_delimiter) {
case 'auto':
options.record_delimiter = null;
break;
case 'ascii':
options.record_delimiter = "\x1E";
break;
case 'unix':
options.record_delimiter = "\n";
break;
case 'unicode':
options.record_delimiter = "\u2028";
}
} else if (Buffer.isBuffer(options.record_delimiter)) {
options.record_delimiter = options.record_delimiter.toString();
} else {
throw Error("Invalid Option: record_delimiter must be a string or a buffer, got ".concat(JSON.stringify(options.record_delimiter)));
} // Internal usage, state related
case 'mac':
options.record_delimiter = "\r";
break;
case 'windows':
options.record_delimiter = "\r\n";
break;
if (this.countWriten == null) {
this.countWriten = 0;
} // Expose options
case 'ascii':
options.record_delimiter = "\x1E";
break;
case 'unicode':
options.record_delimiter = "\u2028";
}
} else if (Buffer.isBuffer(options.record_delimiter)) {
options.record_delimiter = options.record_delimiter.toString();
} else {
throw Error("Invalid Option: record_delimiter must be a string or a buffer, got ".concat(JSON.stringify(options.record_delimiter)));
} // Expose options
this.options = options;
return this;
};
util.inherits(_Stringifier, stream.Transform);
module.exports.Stringifier = _Stringifier; // ## `Stringifier.prototype._transform(chunk, encoding, callback)`
// Implementation of the [transform._transform function](https://nodejs.org/api/stream.html#stream_transform_transform_chunk_encoding_callback).
_this.options = options; // Internal state
_Stringifier.prototype._transform = function (chunk, encoding, callback) {
var base, e, preserve; // Nothing to do if null or undefined
_this.state = {
stop: false
}; // Information
if (chunk == null) {
return;
}
_this.info = {
records: 0
};
preserve = _typeof(chunk) !== 'object'; // Emit and stringify the record if an object or an array
_assertThisInitialized(_assertThisInitialized(_this));
if (!preserve) {
// Detect columns from the first record
if (this.countWriten === 0 && !Array.isArray(chunk)) {
if ((base = this.options).columns == null) {
base.columns = _Stringifier.normalize_columns(Object.keys(chunk));
}
}
return _this;
} // ## `Stringifier.prototype._transform(chunk, encoding, callback)`
// Implementation of the [transform._transform function](https://nodejs.org/api/stream.html#stream_transform_transform_chunk_encoding_callback).
try {
this.emit('record', chunk, this.countWriten);
} catch (error) {
e = error;
return this.emit('error', e);
} // Convert the record into a string
_createClass(Stringifier, [{
key: "_transform",
value: function _transform(chunk, encoding, callback) {
var base, e;
if (this.options.eof) {
chunk = this.stringify(chunk);
if (chunk == null) {
if (this.state.stop === true) {
return;
}
} // Chunk validation
chunk = chunk + this.options.record_delimiter;
} else {
chunk = this.stringify(chunk);
if (chunk == null) {
return;
if (!(Array.isArray(chunk) || _typeof(chunk) === 'object')) {
this.state.stop = true;
return callback(Error("Invalid Record: expect an array or an object, got ".concat(JSON.stringify(chunk))));
} // Detect columns from the first record
if (this.info.records === 0) {
if (Array.isArray(chunk)) {
if (this.options.header === true && !this.options.columns) {
this.state.stop = true;
return callback(Error('Undiscoverable Columns: header option requires column option or object records'));
}
} else {
if ((base = this.options).columns == null) {
base.columns = this.normalize_columns(Object.keys(chunk));
}
}
}
if (this.options.header || this.countWriten) {
chunk = this.options.record_delimiter + chunk;
if (this.info.records === 0) {
// Emit the header
this.headers();
}
}
}
if (typeof chunk === 'number') {
// Emit the csv
chunk = "".concat(chunk);
}
try {
// Emit and stringify the record if an object or an array
this.emit('record', chunk, this.info.records);
} catch (error) {
e = error;
this.state.stop = true;
return this.emit('error', e);
} // Convert the record into a string
if (this.countWriten === 0) {
this.headers();
}
if (!preserve) {
this.countWriten++;
}
if (this.options.eof) {
chunk = this.stringify(chunk);
this.push(chunk);
return callback();
}; // ## `Stringifier.prototype._flush(callback)`
// Implementation of the [transform._flush function](https://nodejs.org/api/stream.html#stream_transform_flush_callback).
if (chunk == null) {
return;
}
chunk = chunk + this.options.record_delimiter;
} else {
chunk = this.stringify(chunk);
_Stringifier.prototype._flush = function (callback) {
if (this.countWriten === 0) {
this.headers();
}
if (chunk == null) {
return;
}
return callback();
}; // ## `Stringifier.prototype.stringify(line)`
// Convert a line to a string. Line may be an object, an array or a string.
if (this.options.header || this.info.records) {
chunk = this.options.record_delimiter + chunk;
}
} // Emit the csv
_Stringifier.prototype.stringify = function (record) {
var _record, column, columns, containsEscape, containsQuote, containsRowDelimiter, containsdelimiter, delimiter, err, escape, field, i, j, l, newrecord, quote, quoted, quotedMatch, quotedString, ref, ref1, regexp, shouldQuote, type, value;
this.info.records++;
this.push(chunk);
return callback();
} // ## `Stringifier.prototype._flush(callback)`
// Implementation of the [transform._flush function](https://nodejs.org/api/stream.html#stream_transform_flush_callback).
if (_typeof(record) !== 'object') {
return record;
}
}, {
key: "_flush",
value: function _flush(callback) {
if (this.info.records === 0) {
this.headers();
}
columns = this.options.columns;
delimiter = this.options.delimiter;
quote = this.options.quote;
escape = this.options.escape;
return callback();
} // ## `Stringifier.prototype.stringify(line)`
// Convert a line to a string. Line may be an object, an array or a string.
if (!Array.isArray(record)) {
_record = [];
}, {
key: "stringify",
value: function stringify(record) {
var _record, column, columns, containsEscape, containsQuote, containsRowDelimiter, containsdelimiter, delimiter, err, escape, field, header, i, j, l, len, m, newrecord, quote, quoted, quotedMatch, quotedString, ref, ref1, regexp, shouldQuote, value;
if (columns) {
for (i = j = 0, ref = columns.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
value = get(record, columns[i].key);
_record[i] = typeof value === 'undefined' || value === null ? '' : value;
if (_typeof(record) !== 'object') {
return record;
}
} else {
for (column in record) {
_record.push(record[column]);
}
}
record = _record;
_record = null;
} else if (columns) {
// Note, we used to have @options.columns
// We are getting an array but the user want specified output columns. In
// this case, we respect the columns indexes
record.splice(columns.length);
}
var _this$options = this.options;
columns = _this$options.columns;
delimiter = _this$options.delimiter;
header = _this$options.header;
quote = _this$options.quote;
escape = _this$options.escape;
if (Array.isArray(record)) {
newrecord = '';
// Record is an array
if (Array.isArray(record)) {
if (columns) {
// We are getting an array but the user has specified output columns. In
// this case, we respect the columns indexes
record.splice(columns.length);
} // Cast record elements
for (i = l = 0, ref1 = record.length; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) {
field = record[i];
type = _typeof(field);
try {
if (type === 'string') {
// fine 99% of the cases
field = this.options.cast.string(field);
} else if (type === 'number') {
field = this.options.cast.number(field);
} else if (type === 'boolean') {
field = this.options.cast.boolean(field);
} else if (field instanceof Date) {
field = this.options.cast.date(field);
} else if (type === 'object' && field !== null) {
field = this.options.cast.object(field);
}
} catch (error) {
err = error;
this.emit('error', err);
return;
}
for (i = j = 0, len = record.length; j < len; i = ++j) {
field = record[i];
if (field) {
if (typeof field !== 'string') {
this.emit('error', Error('Formatter must return a string, null or undefined'));
return null;
}
var _this$__cast = this.__cast(field, {
index: i,
column: i,
records: this.info.records,
header: header && this.info.records === 0
});
containsdelimiter = field.indexOf(delimiter) >= 0;
containsQuote = quote !== '' && field.indexOf(quote) >= 0;
containsEscape = field.indexOf(escape) >= 0 && escape !== quote;
containsRowDelimiter = field.indexOf(this.options.record_delimiter) >= 0;
quoted = this.options.quoted;
quotedString = this.options.quoted_string && typeof record[i] === 'string';
quotedMatch = this.options.quoted_match && typeof record[i] === 'string' && this.options.quoted_match.filter(function (quoted_match) {
if (typeof quoted_match === 'string') {
return record[i].indexOf(quoted_match) !== -1;
} else {
return quoted_match.test(record[i]);
var _this$__cast2 = _slicedToArray(_this$__cast, 2);
err = _this$__cast2[0];
value = _this$__cast2[1];
if (err) {
this.emit('error', err);
return;
}
});
quotedMatch = quotedMatch && quotedMatch.length > 0;
shouldQuote = containsQuote || containsdelimiter || containsRowDelimiter || quoted || quotedString || quotedMatch;
if (shouldQuote && containsEscape) {
regexp = escape === '\\' ? new RegExp(escape + escape, 'g') : new RegExp(escape, 'g');
field = field.replace(regexp, escape + escape);
record[i] = [value, field];
}
} else {
// Record is a literal object
_record = [];
if (containsQuote) {
regexp = new RegExp(quote, 'g');
field = field.replace(regexp, escape + quote);
}
if (columns) {
for (i = l = 0, ref = columns.length; 0 <= ref ? l < ref : l > ref; i = 0 <= ref ? ++l : --l) {
field = get(record, columns[i].key);
if (shouldQuote) {
field = quote + field + quote;
var _this$__cast3 = this.__cast(field, {
index: i,
column: columns[i].key,
records: this.info.records,
header: header && this.info.records === 0
});
var _this$__cast4 = _slicedToArray(_this$__cast3, 2);
err = _this$__cast4[0];
value = _this$__cast4[1];
if (err) {
this.emit('error', err);
return;
}
_record[i] = [value, field];
}
} else {
for (column in record) {
field = record[column];
var _this$__cast5 = this.__cast(field, {
index: i,
column: columns[i].key,
records: this.info.records,
header: header && this.info.records === 0
});
var _this$__cast6 = _slicedToArray(_this$__cast5, 2);
err = _this$__cast6[0];
value = _this$__cast6[1];
if (err) {
this.emit('error', err);
return;
}
_record.push([value, field]);
}
}
newrecord += field;
} else if (this.options.quoted_empty || this.options.quoted_empty == null && record[i] === '' && this.options.quoted_string) {
newrecord += quote + quote;
record = _record;
_record = null;
}
if (i !== record.length - 1) {
newrecord += delimiter;
}
}
if (Array.isArray(record)) {
newrecord = '';
record = newrecord;
}
for (i = m = 0, ref1 = record.length; 0 <= ref1 ? m < ref1 : m > ref1; i = 0 <= ref1 ? ++m : --m) {
var _record$i = _slicedToArray(record[i], 2);
return record;
}; // ## `Stringifier.prototype.headers`
// Print the header line if the option "header" is "true".
value = _record$i[0];
field = _record$i[1];
if (err) {
this.emit('error', err);
return;
}
_Stringifier.prototype.headers = function () {
var headers;
if (value) {
if (typeof value !== 'string') {
this.emit('error', Error("Formatter must return a string, null or undefined, got ".concat(JSON.stringify(value))));
return null;
}
if (!this.options.header) {
return;
}
containsdelimiter = value.indexOf(delimiter) >= 0;
containsQuote = quote !== '' && value.indexOf(quote) >= 0;
containsEscape = value.indexOf(escape) >= 0 && escape !== quote;
containsRowDelimiter = value.indexOf(this.options.record_delimiter) >= 0;
quoted = this.options.quoted;
quotedString = this.options.quoted_string && typeof field === 'string';
quotedMatch = this.options.quoted_match && typeof field === 'string' && this.options.quoted_match.filter(function (quoted_match) {
if (typeof quoted_match === 'string') {
return value.indexOf(quoted_match) !== -1;
} else {
return quoted_match.test(value);
}
});
quotedMatch = quotedMatch && quotedMatch.length > 0;
shouldQuote = containsQuote || containsdelimiter || containsRowDelimiter || quoted || quotedString || quotedMatch;
if (!this.options.columns) {
return;
}
if (shouldQuote && containsEscape) {
regexp = escape === '\\' ? new RegExp(escape + escape, 'g') : new RegExp(escape, 'g');
value = value.replace(regexp, escape + escape);
}
headers = this.options.columns.map(function (column) {
return column.header;
});
if (containsQuote) {
regexp = new RegExp(quote, 'g');
value = value.replace(regexp, escape + quote);
}
if (this.options.eof) {
headers = this.stringify(headers) + this.options.record_delimiter;
} else {
headers = this.stringify(headers);
}
if (shouldQuote) {
value = quote + value + quote;
}
return this.push(headers);
}; // ## `Stringifier.prototype.headers`
// Print the header line if the option "header" is "true".
newrecord += value;
} else if (this.options.quoted_empty || this.options.quoted_empty == null && field === '' && this.options.quoted_string) {
newrecord += quote + quote;
}
if (i !== record.length - 1) {
newrecord += delimiter;
}
}
_Stringifier.normalize_columns = function (columns) {
var column, k, v;
record = newrecord;
}
if (columns == null) {
return null;
}
return record;
} // ## `Stringifier.prototype.headers`
// Print the header line if the option "header" is "true".
if (columns != null) {
if (_typeof(columns) !== 'object') {
throw Error('Invalid option "columns": expect an array or an object');
}, {
key: "headers",
value: function headers() {
var headers;
if (!this.options.header) {
return;
}
if (!this.options.columns) {
return;
}
headers = this.options.columns.map(function (column) {
return column.header;
});
if (this.options.eof) {
headers = this.stringify(headers) + this.options.record_delimiter;
} else {
headers = this.stringify(headers);
}
return this.push(headers);
}
}, {
key: "__cast",
value: function __cast(value, context) {
var err, type;
type = _typeof(value);
if (!Array.isArray(columns)) {
columns = function () {
var results;
results = [];
try {
if (type === 'string') {
// Fine for 99% of the cases
return [void 0, this.options.cast.string(value, context)];
} else if (type === 'number') {
return [void 0, this.options.cast.number(value, context)];
} else if (type === 'boolean') {
return [void 0, this.options.cast.boolean(value, context)];
} else if (value instanceof Date) {
return [void 0, this.options.cast.date(value, context)];
} else if (type === 'object' && value !== null) {
return [void 0, this.options.cast.object(value, context)];
} else {
return [void 0, value, value];
}
} catch (error) {
err = error;
return [err];
}
} // ## `Stringifier.prototype.normalize_columns`
for (k in columns) {
v = columns[k];
results.push({
key: k,
header: v
});
}, {
key: "normalize_columns",
value: function normalize_columns(columns) {
var column, k, v;
if (columns == null) {
return null;
}
if (columns != null) {
if (_typeof(columns) !== 'object') {
throw Error('Invalid option "columns": expect an array or an object');
}
return results;
}();
} else {
columns = function () {
var j, len, results;
results = [];
if (!Array.isArray(columns)) {
columns = function () {
var results;
results = [];
for (j = 0, len = columns.length; j < len; j++) {
column = columns[j];
if (typeof column === 'string') {
results.push({
key: column,
header: column
});
} else if (_typeof(column) === 'object' && column != null && !Array.isArray(column)) {
if (!column.key) {
throw Error('Invalid column definition: property "key" is required');
for (k in columns) {
v = columns[k];
results.push({
key: k,
header: v
});
}
if (column.header == null) {
column.header = column.key;
return results;
}();
} else {
columns = function () {
var j, len, results;
results = [];
for (j = 0, len = columns.length; j < len; j++) {
column = columns[j];
if (typeof column === 'string') {
results.push({
key: column,
header: column
});
} else if (_typeof(column) === 'object' && column != null && !Array.isArray(column)) {
if (!column.key) {
throw Error('Invalid column definition: property "key" is required');
}
if (column.header == null) {
column.header = column.key;
}
results.push(column);
} else {
throw Error('Invalid column definition: expect a string or an object');
}
}
results.push(column);
} else {
throw Error('Invalid column definition: expect a string or an object');
}
return results;
}();
}
}
return results;
}();
return columns;
}
}
}]);
return columns;
};
return Stringifier;
}(stream.Transform);
module.exports.Stringifier = Stringifier;
underscore = function underscore(str) {

@@ -558,0 +691,0 @@ return str.replace(/([A-Z])/g, function (_, match, index) {

@@ -8,17 +8,27 @@ /// <reference types="node" />

declare function stringify(callback?: stringify.Callback): stringify.Stringifier
declare function stringify(options?: stringify.Options, callback?: stringify.Callback): stringify.Stringifier
declare function stringify(options: stringify.Options, callback?: stringify.Callback): stringify.Stringifier
declare function stringify(input: stringify.Input, callback?: stringify.Callback): stringify.Stringifier
declare function stringify(input: stringify.Input, options?: stringify.Options, callback?: stringify.Callback): stringify.Stringifier
declare namespace stringify {
type Callback = (err: any | Error, output: any) => void
type Callback = (err?: null | Error, output?: string) => void
type RowDelimiter = string | 'auto' | 'unix' | 'windows' | 'ascii' | 'unicode'
type RowDelimiter = string | 'auto' | 'unix' | 'mac' | 'windows' | 'ascii' | 'unicode'
type Formatter<T> = (value: T) => string
type Cast<T> = (value: T, CastingContext) => string
interface PlainObject<T> {
[key: string]: T
type PlainObject<T> = Record<string, T>
type Input = any[]
interface ColumnOption {
key: string
header?: string
}
type Input = any[] | PlainObject<any>
interface CastingContext {
readonly column?: number | string;
readonly header: boolean;
readonly index: number;
readonly records: number;
}

@@ -34,3 +44,3 @@ interface Options {

*/
columns?: string[] | PlainObject<string>
columns?: string[] | PlainObject<string> | ColumnOption[]

@@ -85,12 +95,12 @@ /**

/**
* Key-value object which defines custom formatters for certain data types
* Key-value object which defines custom cast for certain data types
*/
formatters?: {
boolean?: Formatter<boolean>
date?: Formatter<Date>
number?: Formatter<number>
cast?: {
boolean?: Cast<boolean>
date?: Cast<Date>
number?: Cast<number>
/**
* Custom formatter for generic object values
*/
object?: Formatter<any>
object?: Cast<Record<string, any>>
}

@@ -97,0 +107,0 @@ }

@@ -97,162 +97,177 @@ // Generated by CoffeeScript 2.3.2

// Options are documented [here](http://csv.adaltas.com/stringify/).
Stringifier = function(opts = {}) {
var base, base1, base2, base3, base4, isRegExp, isString, j, k, len, options, quoted_match, ref, v;
stream.Transform.call(this, {...options, ...{
writableObjectMode: true
}});
options = {};
for (k in opts) {
v = opts[k];
// Immutable options and camelcase conversion
options[underscore(k)] = v;
}
//# Default options
if (options.delimiter == null) {
options.delimiter = ',';
}
if (options.quote == null) {
options.quote = '"';
}
if (options.quoted == null) {
options.quoted = false;
}
if (options.quoted_empty == null) {
options.quoted_empty = void 0;
}
if (options.quoted_string == null) {
options.quoted_string = false;
}
if (options.eof == null) {
options.eof = true;
}
if (options.escape == null) {
options.escape = '"';
}
if (options.header == null) {
options.header = false;
}
// Normalize the columns option
options.columns = Stringifier.normalize_columns(options.columns);
if (options.cast == null) {
options.cast = {};
}
// Normalize option `quoted_match`
if (options.quoted_match === void 0 || options.quoted_match === null || options.quoted_match === false) {
options.quoted_match = null;
} else if (!Array.isArray(options.quoted_match)) {
options.quoted_match = [options.quoted_match];
}
if (options.quoted_match) {
ref = options.quoted_match;
for (j = 0, len = ref.length; j < len; j++) {
quoted_match = ref[j];
isString = typeof quoted_match === 'string';
isRegExp = quoted_match instanceof RegExp;
if (!isString && !isRegExp) {
throw Error(`Invalid Option: quoted_match must be a string or a regex, got ${JSON.stringify(quoted_match)}`);
Stringifier = class Stringifier extends stream.Transform {
constructor(opts = {}) {
var base, base1, base2, base3, base4, isRegExp, isString, j, k, len, options, quoted_match, ref, v;
super({...{
writableObjectMode: true
}, ...options});
options = {};
for (k in opts) {
v = opts[k];
// Immutable options and camelcase conversion
options[underscore(k)] = v;
}
//# Default options
if (options.delimiter == null) {
options.delimiter = ',';
}
if (options.quote == null) {
options.quote = '"';
}
if (options.quoted == null) {
options.quoted = false;
}
if (options.quoted_empty == null) {
options.quoted_empty = void 0;
}
if (options.quoted_string == null) {
options.quoted_string = false;
}
if (options.eof == null) {
options.eof = true;
}
if (options.escape == null) {
options.escape = '"';
}
if (options.header == null) {
options.header = false;
}
// Normalize the columns option
options.columns = this.normalize_columns(options.columns);
if (options.cast == null) {
options.cast = {};
}
// Normalize option `quoted_match`
if (options.quoted_match === void 0 || options.quoted_match === null || options.quoted_match === false) {
options.quoted_match = null;
} else if (!Array.isArray(options.quoted_match)) {
options.quoted_match = [options.quoted_match];
}
if (options.quoted_match) {
ref = options.quoted_match;
for (j = 0, len = ref.length; j < len; j++) {
quoted_match = ref[j];
isString = typeof quoted_match === 'string';
isRegExp = quoted_match instanceof RegExp;
if (!isString && !isRegExp) {
throw Error(`Invalid Option: quoted_match must be a string or a regex, got ${JSON.stringify(quoted_match)}`);
}
}
}
}
if (options.cast.bool) {
// Backward compatibility
options.cast.boolean = options.cast.bool;
}
// Custom cast
if ((base = options.cast).string == null) {
base.string = function(value) {
return value;
};
}
if ((base1 = options.cast).date == null) {
base1.date = function(value) {
// Cast date to timestamp string by default
return '' + value.getTime();
};
}
if ((base2 = options.cast).boolean == null) {
base2.boolean = function(value) {
// Cast boolean to string by default
if (value) {
return '1';
} else {
return '';
if (options.cast.bool) {
// Backward compatibility
options.cast.boolean = options.cast.bool;
}
// Custom cast
if ((base = options.cast).string == null) {
base.string = function(value) {
return value;
};
}
if ((base1 = options.cast).date == null) {
base1.date = function(value) {
// Cast date to timestamp string by default
return '' + value.getTime();
};
}
if ((base2 = options.cast).boolean == null) {
base2.boolean = function(value) {
// Cast boolean to string by default
if (value) {
return '1';
} else {
return '';
}
};
}
if ((base3 = options.cast).number == null) {
base3.number = function(value) {
// Cast number to string using native casting by default
return '' + value;
};
}
if ((base4 = options.cast).object == null) {
base4.object = function(value) {
// Stringify object as JSON by default
return JSON.stringify(value);
};
}
if (options.record_delimiter === void 0 || options.record_delimiter === null || options.record_delimiter === false) {
if (options.record_delimiter == null) {
options.record_delimiter = '\n';
}
} else if (typeof options.record_delimiter === 'string') {
switch (options.record_delimiter) {
case 'auto':
options.record_delimiter = null;
break;
case 'unix':
options.record_delimiter = "\n";
break;
case 'mac':
options.record_delimiter = "\r";
break;
case 'windows':
options.record_delimiter = "\r\n";
break;
case 'ascii':
options.record_delimiter = "\u001e";
break;
case 'unicode':
options.record_delimiter = "\u2028";
}
} else if (Buffer.isBuffer(options.record_delimiter)) {
options.record_delimiter = options.record_delimiter.toString();
} else {
throw Error(`Invalid Option: record_delimiter must be a string or a buffer, got ${JSON.stringify(options.record_delimiter)}`);
}
// Expose options
this.options = options;
// Internal state
this.state = {
stop: false
};
}
if ((base3 = options.cast).number == null) {
base3.number = function(value) {
// Cast number to string using native casting by default
return '' + value;
// Information
this.info = {
records: 0
};
this;
}
if ((base4 = options.cast).object == null) {
base4.object = function(value) {
// Stringify object as JSON by default
return JSON.stringify(value);
};
}
if (options.record_delimiter === void 0 || options.record_delimiter === null || options.record_delimiter === false) {
if (options.record_delimiter == null) {
options.record_delimiter = '\n';
// ## `Stringifier.prototype._transform(chunk, encoding, callback)`
// Implementation of the [transform._transform function](https://nodejs.org/api/stream.html#stream_transform_transform_chunk_encoding_callback).
_transform(chunk, encoding, callback) {
var base, e;
if (this.state.stop === true) {
return;
}
} else if (typeof options.record_delimiter === 'string') {
switch (options.record_delimiter) {
case 'auto':
options.record_delimiter = null;
break;
case 'unix':
options.record_delimiter = "\n";
break;
case 'mac':
options.record_delimiter = "\r";
break;
case 'windows':
options.record_delimiter = "\r\n";
break;
case 'ascii':
options.record_delimiter = "\u001e";
break;
case 'unicode':
options.record_delimiter = "\u2028";
// Chunk validation
if (!(Array.isArray(chunk) || typeof chunk === 'object')) {
this.state.stop = true;
return callback(Error(`Invalid Record: expect an array or an object, got ${JSON.stringify(chunk)}`));
}
} else if (Buffer.isBuffer(options.record_delimiter)) {
options.record_delimiter = options.record_delimiter.toString();
} else {
throw Error(`Invalid Option: record_delimiter must be a string or a buffer, got ${JSON.stringify(options.record_delimiter)}`);
}
// Internal usage, state related
if (this.countWriten == null) {
this.countWriten = 0;
}
// Expose options
this.options = options;
return this;
};
util.inherits(Stringifier, stream.Transform);
module.exports.Stringifier = Stringifier;
// ## `Stringifier.prototype._transform(chunk, encoding, callback)`
// Implementation of the [transform._transform function](https://nodejs.org/api/stream.html#stream_transform_transform_chunk_encoding_callback).
Stringifier.prototype._transform = function(chunk, encoding, callback) {
var base, e, preserve;
// Nothing to do if null or undefined
if (chunk == null) {
return;
}
preserve = typeof chunk !== 'object';
// Emit and stringify the record if an object or an array
if (!preserve) {
// Detect columns from the first record
if (this.countWriten === 0 && !Array.isArray(chunk)) {
if ((base = this.options).columns == null) {
base.columns = Stringifier.normalize_columns(Object.keys(chunk));
if (this.info.records === 0) {
if (Array.isArray(chunk)) {
if (this.options.header === true && !this.options.columns) {
this.state.stop = true;
return callback(Error('Undiscoverable Columns: header option requires column option or object records'));
}
} else {
if ((base = this.options).columns == null) {
base.columns = this.normalize_columns(Object.keys(chunk));
}
}
}
if (this.info.records === 0) {
// Emit the header
this.headers();
}
try {
this.emit('record', chunk, this.countWriten);
// Emit and stringify the record if an object or an array
this.emit('record', chunk, this.info.records);
} catch (error) {
e = error;
this.state.stop = true;
return this.emit('error', e);

@@ -272,206 +287,245 @@ }

}
if (this.options.header || this.countWriten) {
if (this.options.header || this.info.records) {
chunk = this.options.record_delimiter + chunk;
}
}
}
if (typeof chunk === 'number') {
// Emit the csv
chunk = `${chunk}`;
this.info.records++;
this.push(chunk);
return callback();
}
if (this.countWriten === 0) {
this.headers();
}
if (!preserve) {
this.countWriten++;
}
this.push(chunk);
return callback();
};
// ## `Stringifier.prototype._flush(callback)`
// ## `Stringifier.prototype._flush(callback)`
// Implementation of the [transform._flush function](https://nodejs.org/api/stream.html#stream_transform_flush_callback).
Stringifier.prototype._flush = function(callback) {
if (this.countWriten === 0) {
this.headers();
// Implementation of the [transform._flush function](https://nodejs.org/api/stream.html#stream_transform_flush_callback).
_flush(callback) {
if (this.info.records === 0) {
this.headers();
}
return callback();
}
return callback();
};
// ## `Stringifier.prototype.stringify(line)`
// ## `Stringifier.prototype.stringify(line)`
// Convert a line to a string. Line may be an object, an array or a string.
Stringifier.prototype.stringify = function(record) {
var _record, column, columns, containsEscape, containsQuote, containsRowDelimiter, containsdelimiter, delimiter, err, escape, field, i, j, l, newrecord, quote, quoted, quotedMatch, quotedString, ref, ref1, regexp, shouldQuote, type, value;
if (typeof record !== 'object') {
return record;
}
columns = this.options.columns;
delimiter = this.options.delimiter;
quote = this.options.quote;
escape = this.options.escape;
if (!Array.isArray(record)) {
_record = [];
if (columns) {
for (i = j = 0, ref = columns.length; (0 <= ref ? j < ref : j > ref); i = 0 <= ref ? ++j : --j) {
value = get(record, columns[i].key);
_record[i] = (typeof value === 'undefined' || value === null) ? '' : value;
// Convert a line to a string. Line may be an object, an array or a string.
stringify(record) {
var _record, column, columns, containsEscape, containsQuote, containsRowDelimiter, containsdelimiter, delimiter, err, escape, field, header, i, j, l, len, m, newrecord, quote, quoted, quotedMatch, quotedString, ref, ref1, regexp, shouldQuote, value;
if (typeof record !== 'object') {
return record;
}
({columns, delimiter, header, quote, escape} = this.options);
// Record is an array
if (Array.isArray(record)) {
if (columns) {
// We are getting an array but the user has specified output columns. In
// this case, we respect the columns indexes
record.splice(columns.length);
}
// Cast record elements
for (i = j = 0, len = record.length; j < len; i = ++j) {
field = record[i];
[err, value] = this.__cast(field, {
index: i,
column: i,
records: this.info.records,
header: header && this.info.records === 0
});
if (err) {
this.emit('error', err);
return;
}
record[i] = [value, field];
}
} else {
for (column in record) {
_record.push(record[column]);
// Record is a literal object
_record = [];
if (columns) {
for (i = l = 0, ref = columns.length; (0 <= ref ? l < ref : l > ref); i = 0 <= ref ? ++l : --l) {
field = get(record, columns[i].key);
[err, value] = this.__cast(field, {
index: i,
column: columns[i].key,
records: this.info.records,
header: header && this.info.records === 0
});
if (err) {
this.emit('error', err);
return;
}
_record[i] = [value, field];
}
} else {
for (column in record) {
field = record[column];
[err, value] = this.__cast(field, {
index: i,
column: columns[i].key,
records: this.info.records,
header: header && this.info.records === 0
});
if (err) {
this.emit('error', err);
return;
}
_record.push([value, field]);
}
}
record = _record;
_record = null;
}
record = _record;
_record = null;
} else if (columns) { // Note, we used to have @options.columns
// We are getting an array but the user want specified output columns. In
// this case, we respect the columns indexes
record.splice(columns.length);
}
if (Array.isArray(record)) {
newrecord = '';
for (i = l = 0, ref1 = record.length; (0 <= ref1 ? l < ref1 : l > ref1); i = 0 <= ref1 ? ++l : --l) {
field = record[i];
type = typeof field;
try {
if (type === 'string') {
// fine 99% of the cases
field = this.options.cast.string(field);
} else if (type === 'number') {
field = this.options.cast.number(field);
} else if (type === 'boolean') {
field = this.options.cast.boolean(field);
} else if (field instanceof Date) {
field = this.options.cast.date(field);
} else if (type === 'object' && field !== null) {
field = this.options.cast.object(field);
if (Array.isArray(record)) {
newrecord = '';
for (i = m = 0, ref1 = record.length; (0 <= ref1 ? m < ref1 : m > ref1); i = 0 <= ref1 ? ++m : --m) {
[value, field] = record[i];
if (err) {
this.emit('error', err);
return;
}
} catch (error) {
err = error;
this.emit('error', err);
return;
}
if (field) {
if (typeof field !== 'string') {
this.emit('error', Error('Formatter must return a string, null or undefined'));
return null;
}
containsdelimiter = field.indexOf(delimiter) >= 0;
containsQuote = (quote !== '') && field.indexOf(quote) >= 0;
containsEscape = field.indexOf(escape) >= 0 && (escape !== quote);
containsRowDelimiter = field.indexOf(this.options.record_delimiter) >= 0;
quoted = this.options.quoted;
quotedString = this.options.quoted_string && typeof record[i] === 'string';
quotedMatch = this.options.quoted_match && typeof record[i] === 'string' && this.options.quoted_match.filter(function(quoted_match) {
if (typeof quoted_match === 'string') {
return record[i].indexOf(quoted_match) !== -1;
} else {
return quoted_match.test(record[i]);
if (value) {
if (typeof value !== 'string') {
this.emit('error', Error(`Formatter must return a string, null or undefined, got ${JSON.stringify(value)}`));
return null;
}
});
quotedMatch = quotedMatch && quotedMatch.length > 0;
shouldQuote = containsQuote || containsdelimiter || containsRowDelimiter || quoted || quotedString || quotedMatch;
if (shouldQuote && containsEscape) {
regexp = escape === '\\' ? new RegExp(escape + escape, 'g') : new RegExp(escape, 'g');
field = field.replace(regexp, escape + escape);
containsdelimiter = value.indexOf(delimiter) >= 0;
containsQuote = (quote !== '') && value.indexOf(quote) >= 0;
containsEscape = value.indexOf(escape) >= 0 && (escape !== quote);
containsRowDelimiter = value.indexOf(this.options.record_delimiter) >= 0;
quoted = this.options.quoted;
quotedString = this.options.quoted_string && typeof field === 'string';
quotedMatch = this.options.quoted_match && typeof field === 'string' && this.options.quoted_match.filter(function(quoted_match) {
if (typeof quoted_match === 'string') {
return value.indexOf(quoted_match) !== -1;
} else {
return quoted_match.test(value);
}
});
quotedMatch = quotedMatch && quotedMatch.length > 0;
shouldQuote = containsQuote || containsdelimiter || containsRowDelimiter || quoted || quotedString || quotedMatch;
if (shouldQuote && containsEscape) {
regexp = escape === '\\' ? new RegExp(escape + escape, 'g') : new RegExp(escape, 'g');
value = value.replace(regexp, escape + escape);
}
if (containsQuote) {
regexp = new RegExp(quote, 'g');
value = value.replace(regexp, escape + quote);
}
if (shouldQuote) {
value = quote + value + quote;
}
newrecord += value;
} else if (this.options.quoted_empty || ((this.options.quoted_empty == null) && field === '' && this.options.quoted_string)) {
newrecord += quote + quote;
}
if (containsQuote) {
regexp = new RegExp(quote, 'g');
field = field.replace(regexp, escape + quote);
if (i !== record.length - 1) {
newrecord += delimiter;
}
if (shouldQuote) {
field = quote + field + quote;
}
newrecord += field;
} else if (this.options.quoted_empty || ((this.options.quoted_empty == null) && record[i] === '' && this.options.quoted_string)) {
newrecord += quote + quote;
}
if (i !== record.length - 1) {
newrecord += delimiter;
}
record = newrecord;
}
record = newrecord;
return record;
}
return record;
};
// ## `Stringifier.prototype.headers`
// ## `Stringifier.prototype.headers`
// Print the header line if the option "header" is "true".
Stringifier.prototype.headers = function() {
var headers;
if (!this.options.header) {
return;
// Print the header line if the option "header" is "true".
headers() {
var headers;
if (!this.options.header) {
return;
}
if (!this.options.columns) {
return;
}
headers = this.options.columns.map(function(column) {
return column.header;
});
if (this.options.eof) {
headers = this.stringify(headers) + this.options.record_delimiter;
} else {
headers = this.stringify(headers);
}
return this.push(headers);
}
if (!this.options.columns) {
return;
__cast(value, context) {
var err, type;
type = typeof value;
try {
if (type === 'string') {
// Fine for 99% of the cases
return [void 0, this.options.cast.string(value, context)];
} else if (type === 'number') {
return [void 0, this.options.cast.number(value, context)];
} else if (type === 'boolean') {
return [void 0, this.options.cast.boolean(value, context)];
} else if (value instanceof Date) {
return [void 0, this.options.cast.date(value, context)];
} else if (type === 'object' && value !== null) {
return [void 0, this.options.cast.object(value, context)];
} else {
return [void 0, value, value];
}
} catch (error) {
err = error;
return [err];
}
}
headers = this.options.columns.map(function(column) {
return column.header;
});
if (this.options.eof) {
headers = this.stringify(headers) + this.options.record_delimiter;
} else {
headers = this.stringify(headers);
}
return this.push(headers);
};
// ## `Stringifier.prototype.headers`
// Print the header line if the option "header" is "true".
Stringifier.normalize_columns = function(columns) {
var column, k, v;
if (columns == null) {
return null;
}
if (columns != null) {
if (typeof columns !== 'object') {
throw Error('Invalid option "columns": expect an array or an object');
// ## `Stringifier.prototype.normalize_columns`
normalize_columns(columns) {
var column, k, v;
if (columns == null) {
return null;
}
if (!Array.isArray(columns)) {
columns = (function() {
var results;
results = [];
for (k in columns) {
v = columns[k];
results.push({
key: k,
header: v
});
}
return results;
})();
} else {
columns = (function() {
var j, len, results;
results = [];
for (j = 0, len = columns.length; j < len; j++) {
column = columns[j];
if (typeof column === 'string') {
if (columns != null) {
if (typeof columns !== 'object') {
throw Error('Invalid option "columns": expect an array or an object');
}
if (!Array.isArray(columns)) {
columns = (function() {
var results;
results = [];
for (k in columns) {
v = columns[k];
results.push({
key: column,
header: column
key: k,
header: v
});
} else if (typeof column === 'object' && (column != null) && !Array.isArray(column)) {
if (!column.key) {
throw Error('Invalid column definition: property "key" is required');
}
return results;
})();
} else {
columns = (function() {
var j, len, results;
results = [];
for (j = 0, len = columns.length; j < len; j++) {
column = columns[j];
if (typeof column === 'string') {
results.push({
key: column,
header: column
});
} else if (typeof column === 'object' && (column != null) && !Array.isArray(column)) {
if (!column.key) {
throw Error('Invalid column definition: property "key" is required');
}
if (column.header == null) {
column.header = column.key;
}
results.push(column);
} else {
throw Error('Invalid column definition: expect a string or an object');
}
if (column.header == null) {
column.header = column.key;
}
results.push(column);
} else {
throw Error('Invalid column definition: expect a string or an object');
}
}
return results;
})();
return results;
})();
}
}
return columns;
}
return columns;
};
module.exports.Stringifier = Stringifier;
underscore = function(str) {

@@ -478,0 +532,0 @@ return str.replace(/([A-Z])/g, function(_, match, index) {

{
"version": "5.0.0",
"version": "5.1.0",
"name": "csv-stringify",

@@ -20,7 +20,7 @@ "description": "CSV stringifier implementing the Node.js `stream.Transform` API",

"devDependencies": {
"@babel/cli": "^7.1.0",
"@babel/core": "^7.1.0",
"@babel/preset-env": "^7.1.0",
"coffeescript": "~2.3.1",
"csv-generate": "~2.1.0",
"@babel/cli": "^7.2.0",
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"coffeescript": "~2.3.2",
"csv-generate": "~3.2.0",
"mocha": "~5.2.0",

@@ -27,0 +27,0 @@ "should": "~13.2.3"

@@ -13,4 +13,3 @@

],{
header: true,
columns: ['year', 'phone']
header: true
}, function(err, data){

@@ -17,0 +16,0 @@ assert.equal(

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc