Socket
Socket
Sign inDemoInstall

csv-parse

Package Overview
Dependencies
Maintainers
1
Versions
141
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

csv-parse - npm Package Compare versions

Comparing version 4.6.5 to 4.7.0

28

CHANGELOG.md

@@ -11,2 +11,26 @@

## Version 4.7.0
New Feature:
* on_record: user function to alter and filter records
Minor improvements:
* test: ensure every sample is valid
* from_line: honours inferred column names
* from_line: new sample
* errors: expose CSV_INVALID_ARGUMENT
* errors: expose CSV_INVALID_COLUMN_DEFINITION
* errors: expose CSV_OPTION_COLUMNS_MISSING_NAME
* errors: expose CSV_INVALID_OPTION_BOM
* errors: expose CSV_INVALID_OPTION_CAST
* errors: expose CSV_INVALID_OPTION_CAST_DATE
* errors: expose CSV_INVALID_OPTION_COLUMNS
* errors: expose CSV_INVALID_OPTION_COMMENT
* errors: expose CSV_INVALID_OPTION_DELIMITER
* error: fix call to supper
Project management:
* package: contributing
* package: code of conduct
## Version 4.6.5

@@ -113,3 +137,3 @@

Project managements:
Project management:
* babel: include .babelrc to git

@@ -192,3 +216,3 @@

API management
API management:
* Multiple tests have been rewritten with easier data sample

@@ -195,0 +219,0 @@ * Source code is now written in ES6 instead of CoffeeScript

@@ -120,2 +120,6 @@ // Original definitions in https://github.com/DefinitelyTyped/DefinitelyTyped by: David Muller <https://github.com/davidm77>

/**
* Alter and filter records by executing a user defined function.
*/
on_record?: (record: any, context: CastingContext) => any;
/**
* Optional character surrounding a field, one character only, defaults to double quotes.

@@ -122,0 +126,0 @@ */

124

lib/es5/index.js

@@ -93,3 +93,3 @@ "use strict";

} else if (options.bom !== true) {
throw new Error("Invalid Option: bom must be true, got ".concat(JSON.stringify(options.bom)));
throw new CsvError('CSV_INVALID_OPTION_BOM', ['Invalid option bom:', 'bom must be true,', "got ".concat(JSON.stringify(options.bom))]);
} // Normalize option `cast`

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

} else if (options.cast !== true) {
throw new Error('Invalid Option: cast must be true or a function');
throw new CsvError('CSV_INVALID_OPTION_CAST', ['Invalid option cast:', 'cast must be true or a function,', "got ".concat(JSON.stringify(options.cast))]);
} // Normalize option `cast_date`

@@ -119,3 +119,3 @@

} else if (typeof options.cast_date !== 'function') {
throw new Error('Invalid Option: cast_date must be true or a function');
throw new CsvError('CSV_INVALID_OPTION_CAST_DATE', ['Invalid option cast_date:', 'cast_date must be true or a function,', "got ".concat(JSON.stringify(options.cast_date))]);
} // Normalize option `columns`

@@ -137,3 +137,3 @@

} else {
throw new Error("Invalid Option columns: expect an object or true, got ".concat(JSON.stringify(options.columns)));
throw new CsvError('CSV_INVALID_OPTION_COLUMNS', ['Invalid option columns:', 'expect an object, a function or true,', "got ".concat(JSON.stringify(options.columns))]);
} // Normalize option `comment`

@@ -150,3 +150,3 @@

if (!Buffer.isBuffer(options.comment)) {
throw new Error("Invalid Option: comment must be a buffer or a string, got ".concat(JSON.stringify(options.comment)));
throw new CsvError('CSV_INVALID_OPTION_COMMENT', ['Invalid option comment:', 'comment must be a buffer or a string,', "got ".concat(JSON.stringify(options.comment))]);
}

@@ -158,15 +158,6 @@ } // Normalize option `delimiter`

options.delimiter = Buffer.from(',');
} else if (Buffer.isBuffer(options.delimiter)) {
if (options.delimiter.length === 0) {
throw new Error("Invalid Option: delimiter must be a non empty buffer");
} // Great, nothing to do
} else if (typeof options.delimiter === 'string') {
if (options.delimiter.length === 0) {
throw new Error("Invalid Option: delimiter must be a non empty string");
}
} else if (typeof options.delimiter === 'string' && options.delimiter.length !== 0) {
options.delimiter = Buffer.from(options.delimiter);
} else {
throw new Error("Invalid Option: delimiter must be a string or a buffer, got ".concat(options.delimiter));
} else if (Buffer.isBuffer(options.delimiter) && options.delimiter.length === 0 || typeof options.delimiter === 'string' && options.delimiter.length === 0 || !Buffer.isBuffer(options.delimiter) && typeof options.delimiter !== 'string') {
throw new CsvError('CSV_INVALID_OPTION_DELIMITER', ['Invalid option delimiter:', 'delimiter must be a non empty string or buffer,', "got ".concat(JSON.stringify(options.delimiter))]);
} // Normalize option `escape`

@@ -256,2 +247,9 @@

throw new Error("Invalid Option: objname must be a string or a buffer, got ".concat(options.objname));
} // Normalize option `on_record`
if (options.on_record === undefined || options.on_record === null) {
options.on_record = undefined;
} else if (typeof options.on_record !== 'function') {
throw new CsvError('CSV_INVALID_OPTION_ON_RECORD', ['Invalid option `on_record`:', 'expect a function,', "got ".concat(JSON.stringify(options.on_record))]);
} // Normalize option `quote`

@@ -585,4 +583,4 @@

// Escape is only active inside quoted fields
// We are quoting, the char is an escape chr and there is a chr to escape
if (this.state.quoting === true && chr === escape && pos + 1 < bufLen) {
// We are quoting, the char is an escape chr and there is a chr to escape
if (escapeIsQuote) {

@@ -743,2 +741,3 @@ if (buf[pos + 1] === quote) {

if (end === true) {
// Ensure we are not ending in a quoting state
if (this.state.quoting === true) {

@@ -791,4 +790,11 @@ var _err4 = this.__error(new CsvError('CSV_QUOTE_NOT_CLOSED', ['Quote Not Closed:', "the parsing is finished with an opening quote at line ".concat(this.info.lines)], this.__context()));

enabled = _this$state2.enabled,
record = _this$state2.record; // Convert the first line into column names
record = _this$state2.record;
if (enabled === false) {
return this.__resetRow();
} // Convert the first line into column names
var recordLength = record.length;
if (columns === true) {

@@ -798,24 +804,22 @@ return this.__firstLineToColumns(record);

var recordLength = record.length;
if (columns === false && this.info.records === 0) {
this.state.expectedRecordLength = recordLength;
} else if (enabled === true) {
if (recordLength !== this.state.expectedRecordLength) {
if (relax_column_count === true) {
this.info.invalid_field_length++;
}
if (recordLength !== this.state.expectedRecordLength) {
if (relax_column_count === true) {
this.info.invalid_field_length++;
} else {
if (columns === false) {
var err = this.__error(new CsvError('CSV_INVALID_RECORD_LENGTH_DONT_PREVIOUS_RECORDS', ['Invalid Record Length:', "expect ".concat(this.state.expectedRecordLength, ","), "got ".concat(recordLength, " on line ").concat(this.info.lines)], this.__context(), {
record: record
}));
if (err !== undefined) return err;
} else {
if (columns === false) {
var err = this.__error(new CsvError('CSV_INVALID_RECORD_LENGTH_DONT_PREVIOUS_RECORDS', ['Invalid Record Length:', "expect ".concat(this.state.expectedRecordLength, ","), "got ".concat(recordLength, " on line ").concat(this.info.lines)], this.__context(), {
record: record
}));
var _err5 = this.__error(new CsvError('CSV_INVALID_RECORD_LENGTH_DONT_MATCH_COLUMNS', ['Invalid Record Length:', "header length is ".concat(columns.length, ","), "got ".concat(recordLength, " on line ").concat(this.info.lines)], this.__context(), {
record: record
}));
if (err !== undefined) return err;
} else {
var _err5 = this.__error(new CsvError('CSV_INVALID_RECORD_LENGTH_DONT_MATCH_COLUMNS', ['Invalid Record Length:', "header length is ".concat(columns.length, ","), "got ".concat(recordLength, " on line ").concat(this.info.lines)], this.__context(), {
record: record
}));
if (_err5 !== undefined) return _err5;
}
if (_err5 !== undefined) return _err5;
}

@@ -825,6 +829,2 @@ }

if (enabled === false) {
return this.__resetRow();
}
if (skip_lines_with_empty_values === true) {

@@ -862,3 +862,3 @@ if (record.every(function (field) {

if (raw === true || info === true) {
this.push(Object.assign({
this.__push(Object.assign({
record: obj

@@ -871,7 +871,7 @@ }, raw === true ? {

} else {
this.push(obj);
this.__push(obj);
}
} else {
if (raw === true || info === true) {
this.push(Object.assign({
this.__push(Object.assign({
record: [obj[objname], obj]

@@ -884,3 +884,3 @@ }, raw === true ? {

} else {
this.push([obj[objname], obj]);
this.__push([obj[objname], obj]);
}

@@ -890,3 +890,3 @@ }

if (raw === true || info === true) {
this.push(Object.assign({
this.__push(Object.assign({
record: record

@@ -899,3 +899,3 @@ }, raw === true ? {

} else {
this.push(record);
this.__push(record);
}

@@ -951,5 +951,6 @@ }

enabled = _this$state3.enabled,
wasQuoting = _this$state3.wasQuoting; // Deal with from_to options
wasQuoting = _this$state3.wasQuoting; // Short circuit for the from_line options
if (this.options.columns !== true && enabled === false) {
if (enabled === false) {
/* this.options.columns !== true && */
return this.__resetField();

@@ -987,2 +988,19 @@ }

this.state.wasQuoting = false;
}
}, {
key: "__push",
value: function __push(record) {
var on_record = this.options.on_record;
if (on_record !== undefined) {
var context = this.__context();
record = on_record.call(null, record, context);
if (record === undefined || record === null) {
return;
}
}
this.push(record);
} // Return a tuple with the error and the casted value

@@ -1180,3 +1198,3 @@

} else {
throw new Error("Invalid argument: got ".concat(JSON.stringify(argument), " at index ").concat(i));
throw new CsvError('CSV_INVALID_ARGUMENT', ['Invalid argument:', "got ".concat(JSON.stringify(argument), " at index ").concat(i)]);
}

@@ -1227,3 +1245,3 @@ }

if (Array.isArray(message)) message = message.join(' ');
_this2 = _possibleConstructorReturn(this, _getPrototypeOf(CsvError).call(this, [message]));
_this2 = _possibleConstructorReturn(this, _getPrototypeOf(CsvError).call(this, message));
Error.captureStackTrace(_assertThisInitialized(_this2), CsvError);

@@ -1281,3 +1299,3 @@ _this2.code = code;

if (typeof column.name !== 'string') {
throw new Error("Invalid Option columns: property \"name\" is required at position ".concat(i, " when column is an object literal"));
throw new CsvError('CSV_OPTION_COLUMNS_MISSING_NAME', ['Option columns missing name:', "property \"name\" is required at position ".concat(i), 'when column is an object literal']);
}

@@ -1287,3 +1305,3 @@

} else {
throw new Error("Invalid Option columns: expect a string or an object, got ".concat(JSON.stringify(column), " at position ").concat(i));
throw new CsvError('CSV_INVALID_COLUMN_DEFINITION', ['Invalid column definition:', 'expect a string or a literal object,', "got ".concat(JSON.stringify(column), " at position ").concat(i)]);
}

@@ -1290,0 +1308,0 @@ }

@@ -120,2 +120,6 @@ // Original definitions in https://github.com/DefinitelyTyped/DefinitelyTyped by: David Muller <https://github.com/davidm77>

/**
* Alter and filter records by executing a user defined function.
*/
on_record?: (record: any, context: CastingContext) => any;
/**
* Optional character surrounding a field, one character only, defaults to double quotes.

@@ -122,0 +126,0 @@ */

@@ -30,3 +30,6 @@

}else if(options.bom !== true){
throw new Error(`Invalid Option: bom must be true, got ${JSON.stringify(options.bom)}`)
throw new CsvError('CSV_INVALID_OPTION_BOM', [
'Invalid option bom:', 'bom must be true,',
`got ${JSON.stringify(options.bom)}`
])
}

@@ -41,3 +44,6 @@ // Normalize option `cast`

}else if(options.cast !== true){
throw new Error('Invalid Option: cast must be true or a function')
throw new CsvError('CSV_INVALID_OPTION_CAST', [
'Invalid option cast:', 'cast must be true or a function,',
`got ${JSON.stringify(options.cast)}`
])
}

@@ -53,3 +59,6 @@ // Normalize option `cast_date`

}else if(typeof options.cast_date !== 'function'){
throw new Error('Invalid Option: cast_date must be true or a function')
throw new CsvError('CSV_INVALID_OPTION_CAST_DATE', [
'Invalid option cast_date:', 'cast_date must be true or a function,',
`got ${JSON.stringify(options.cast_date)}`
])
}

@@ -69,3 +78,7 @@ // Normalize option `columns`

}else{
throw new Error(`Invalid Option columns: expect an object or true, got ${JSON.stringify(options.columns)}`)
throw new CsvError('CSV_INVALID_OPTION_COLUMNS', [
'Invalid option columns:',
'expect an object, a function or true,',
`got ${JSON.stringify(options.columns)}`
])
}

@@ -80,3 +93,7 @@ // Normalize option `comment`

if(!Buffer.isBuffer(options.comment)){
throw new Error(`Invalid Option: comment must be a buffer or a string, got ${JSON.stringify(options.comment)}`)
throw new CsvError('CSV_INVALID_OPTION_COMMENT', [
'Invalid option comment:',
'comment must be a buffer or a string,',
`got ${JSON.stringify(options.comment)}`
])
}

@@ -87,14 +104,14 @@ }

options.delimiter = Buffer.from(',')
}else if(Buffer.isBuffer(options.delimiter)){
if(options.delimiter.length === 0){
throw new Error(`Invalid Option: delimiter must be a non empty buffer`)
}
// Great, nothing to do
}else if(typeof options.delimiter === 'string'){
if(options.delimiter.length === 0){
throw new Error(`Invalid Option: delimiter must be a non empty string`)
}
}else if(typeof options.delimiter === 'string' && options.delimiter.length !== 0){
options.delimiter = Buffer.from(options.delimiter)
}else{
throw new Error(`Invalid Option: delimiter must be a string or a buffer, got ${options.delimiter}`)
}else if(
(Buffer.isBuffer(options.delimiter) && options.delimiter.length === 0) ||
(typeof options.delimiter === 'string' && options.delimiter.length === 0) ||
(!Buffer.isBuffer(options.delimiter) && typeof options.delimiter !== 'string')
){
throw new CsvError('CSV_INVALID_OPTION_DELIMITER', [
'Invalid option delimiter:',
'delimiter must be a non empty string or buffer,',
`got ${JSON.stringify(options.delimiter)}`
])
}

@@ -176,2 +193,12 @@ // Normalize option `escape`

}
// Normalize option `on_record`
if(options.on_record === undefined || options.on_record === null){
options.on_record = undefined
}else if(typeof options.on_record !== 'function'){
throw new CsvError('CSV_INVALID_OPTION_ON_RECORD', [
'Invalid option `on_record`:',
'expect a function,',
`got ${JSON.stringify(options.on_record)}`
])
}
// Normalize option `quote`

@@ -441,4 +468,4 @@ if(options.quote === null || options.quote === false || options.quote === ''){

// Escape is only active inside quoted fields
// We are quoting, the char is an escape chr and there is a chr to escape
if(this.state.quoting === true && chr === escape && pos + 1 < bufLen){
// We are quoting, the char is an escape chr and there is a chr to escape
if(escapeIsQuote){

@@ -596,2 +623,3 @@ if(buf[pos+1] === quote){

if(end === true){
// Ensure we are not ending in a quoting state
if(this.state.quoting === true){

@@ -633,43 +661,42 @@ const err = this.__error(

const {enabled, record} = this.state
if(enabled === false){
return this.__resetRow()
}
// Convert the first line into column names
const recordLength = record.length
if(columns === true){
return this.__firstLineToColumns(record)
}
const recordLength = record.length
if(columns === false && this.info.records === 0){
this.state.expectedRecordLength = recordLength
}else if(enabled === true){
if(recordLength !== this.state.expectedRecordLength){
if(relax_column_count === true){
this.info.invalid_field_length++
}
if(recordLength !== this.state.expectedRecordLength){
if(relax_column_count === true){
this.info.invalid_field_length++
}else{
if(columns === false){
const err = this.__error(
new CsvError('CSV_INVALID_RECORD_LENGTH_DONT_PREVIOUS_RECORDS', [
'Invalid Record Length:',
`expect ${this.state.expectedRecordLength},`,
`got ${recordLength} on line ${this.info.lines}`,
], this.__context(), {
record: record,
})
)
if(err !== undefined) return err
}else{
if(columns === false){
const err = this.__error(
new CsvError('CSV_INVALID_RECORD_LENGTH_DONT_PREVIOUS_RECORDS', [
'Invalid Record Length:',
`expect ${this.state.expectedRecordLength},`,
`got ${recordLength} on line ${this.info.lines}`,
], this.__context(), {
record: record,
})
)
if(err !== undefined) return err
}else{
const err = this.__error(
new CsvError('CSV_INVALID_RECORD_LENGTH_DONT_MATCH_COLUMNS', [
'Invalid Record Length:',
`header length is ${columns.length},`,
`got ${recordLength} on line ${this.info.lines}`,
], this.__context(), {
record: record,
})
)
if(err !== undefined) return err
}
const err = this.__error(
new CsvError('CSV_INVALID_RECORD_LENGTH_DONT_MATCH_COLUMNS', [
'Invalid Record Length:',
`header length is ${columns.length},`,
`got ${recordLength} on line ${this.info.lines}`,
], this.__context(), {
record: record,
})
)
if(err !== undefined) return err
}
}
}
if(enabled === false){
return this.__resetRow()
}
if(skip_lines_with_empty_values === true){

@@ -698,3 +725,3 @@ if(record.every( (field) => field == null || field.toString && field.toString().trim() === '' )){

if(raw === true || info === true){
this.push(Object.assign(
this.__push(Object.assign(
{record: obj},

@@ -705,7 +732,7 @@ (raw === true ? {raw: this.state.rawBuffer.toString()}: {}),

}else{
this.push(obj)
this.__push(obj)
}
}else{
if(raw === true || info === true){
this.push(Object.assign(
this.__push(Object.assign(
{record: [obj[objname], obj]},

@@ -716,3 +743,3 @@ raw === true ? {raw: this.state.rawBuffer.toString()}: {},

}else{
this.push([obj[objname], obj])
this.__push([obj[objname], obj])
}

@@ -722,3 +749,3 @@ }

if(raw === true || info === true){
this.push(Object.assign(
this.__push(Object.assign(
{record: record},

@@ -729,3 +756,3 @@ raw === true ? {raw: this.state.rawBuffer.toString()}: {},

}else{
this.push(record)
this.__push(record)
}

@@ -770,4 +797,4 @@ }

const {enabled, wasQuoting} = this.state
// Deal with from_to options
if(this.options.columns !== true && enabled === false){
// Short circuit for the from_line options
if(enabled === false){ /* this.options.columns !== true && */
return this.__resetField()

@@ -795,2 +822,11 @@ }

}
__push(record){
const {on_record} = this.options
if(on_record !== undefined){
const context = this.__context()
record = on_record.call(null, record, context)
if(record === undefined || record === null){ return }
}
this.push(record)
}
// Return a tuple with the error and the casted value

@@ -951,3 +987,6 @@ __cast(field){

}else{
throw new Error(`Invalid argument: got ${JSON.stringify(argument)} at index ${i}`)
throw new CsvError('CSV_INVALID_ARGUMENT', [
'Invalid argument:',
`got ${JSON.stringify(argument)} at index ${i}`
])
}

@@ -985,3 +1024,3 @@ }

if(Array.isArray(message)) message = message.join(' ')
super([message])
super(message)
Error.captureStackTrace(this, CsvError)

@@ -1025,7 +1064,15 @@ this.code = code

if(typeof column.name !== 'string'){
throw new Error(`Invalid Option columns: property "name" is required at position ${i} when column is an object literal`)
throw new CsvError('CSV_OPTION_COLUMNS_MISSING_NAME', [
'Option columns missing name:',
`property "name" is required at position ${i}`,
'when column is an object literal'
])
}
normalizedColumns[i] = column
}else{
throw new Error(`Invalid Option columns: expect a string or an object, got ${JSON.stringify(column)} at position ${i}`)
throw new CsvError('CSV_INVALID_COLUMN_DEFINITION', [
'Invalid column definition:',
'expect a string or a literal object,',
`got ${JSON.stringify(column)} at position ${i}`
])
}

@@ -1032,0 +1079,0 @@ }

{
"version": "4.6.5",
"version": "4.7.0",
"name": "csv-parse",

@@ -4,0 +4,0 @@ "description": "CSV parsing implementing the Node.js `stream.Transform` API",

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