csv-parse
Advanced tools
Comparing version 4.6.5 to 4.7.0
@@ -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 @@ */ |
@@ -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 @@ */ |
167
lib/index.js
@@ -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", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
126237
2607