Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ var CsvWriteStream = function(opts) {

this.sendHeaders = opts.sendHeaders !== false
this.headers = opts.headers || null
this.separator = opts.separator || opts.seperator || ','
this.separator = opts.separator === undefined || opts.separator === null ? ',' : opts.separator
this.sendMetadata = !!opts.sendMetadata
this.newline = opts.newline || '\n'

this._objRow = null
Expand All @@ -31,7 +32,7 @@ CsvWriteStream.prototype._compile = function(headers) {
return 'a'+i
})

for (var i = 0; i < headers.length; i += 500) { // do not overflowi the callstack on lots of cols
for (var i = 0; i < headers.length; i += 500) { // do not overflow the callstack on lots of cols
var part = headers.length < 500 ? headers : headers.slice(i, i + 500)
str += i ? 'result += "'+sep+'" + ' : 'var result = '
part.forEach(function(prop, j) {
Expand All @@ -42,36 +43,42 @@ CsvWriteStream.prototype._compile = function(headers) {

str += 'return result +'+JSON.stringify(newline)+'\n}'

return new Function('esc', 'return '+str)(esc)
var escape = sep === '' ? noEsc : esc;
return new Function('esc', 'return '+str)(escape)
}

CsvWriteStream.prototype._transform = function(row, enc, cb) {
var isArray = Array.isArray(row)

if (!isArray && !this.headers) this.headers = Object.keys(row)

if (this._first && this.headers) {
if (this._first) {
this._first = false

var objProps = []
var arrProps = []
var heads = []

for (var i = 0; i < this.headers.length; i++) {
arrProps.push('obj['+i+']')
objProps.push(gen('obj', this.headers[i]))
if (this.headers) {
for (var i = 0; i < this.headers.length; i++) {
arrProps.push('obj['+i+']')
objProps.push(gen('obj', this.headers[i]))
}
this._objRow = this._compile(objProps)
} else {
for (var j = 0; j < row.length; j++) {
arrProps.push('obj['+j+']')
}
this.sendHeaders = false;
}

this._objRow = this._compile(objProps)
this._arrRow = this._compile(arrProps)

if (this.sendMetadata && this.separator) this.push('sep=' + this.separator + this.newline)
if (this.sendHeaders) this.push(this._arrRow(this.headers))
}

if (isArray) {
if (!this.headers) return cb(new Error('no headers specified'))
this.push(this._arrRow(row))
} else {
if (!this.headers) return cb(new Error('no headers specified for object after the first element'))
this.push(this._objRow(row))
}

Expand All @@ -97,3 +104,6 @@ module.exports = function(opts) {
function esc(cell) {
return '"'+cell.replace(/"/g, '""')+'"'
}
function noEsc(cell) {
return cell;
}
3 changes: 2 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ var writer = csvWriter()
separator: ',',
newline: '\n',
headers: undefined,
sendHeaders: true
sendHeaders: true,
sendMetadata: false
}
```

Expand Down
8 changes: 4 additions & 4 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ test('encode from object w/ auto headers', function(t) {
writer.end()
})

test('no headers specified', function(t) {
test('no headers specified for array', function(t) {
var writer = csv()

writer.on('error', function(err) {
t.equal(err.message, 'no headers specified')
writer.pipe(concat(function(data) {
t.equal('foo,bar\n', data.toString())
t.end()
})
}))

writer.write(['foo', 'bar'])
writer.end()
Expand Down