From c648472e6f85d6a914648b241d720768af0dfc24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 23:17:25 +0100 Subject: [PATCH] Bump csv-parse from 6.2.1 to 7.0.0 (#472) * Bump csv-parse from 6.2.1 to 7.0.0 Bumps [csv-parse](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-parse) from 6.2.1 to 7.0.0. - [Changelog](https://github.com/adaltas/node-csv/blob/master/packages/csv-parse/CHANGELOG.md) - [Commits](https://github.com/adaltas/node-csv/commits/csv-parse@7.0.0/packages/csv-parse) --- updated-dependencies: - dependency-name: csv-parse dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Help Renovate out (exec 'npm run build-dist') --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Paulo F. Oliveira --- dist/index.js | 401 +++++++++++++++++++++++++++++++++++----------- package-lock.json | 8 +- package.json | 2 +- 3 files changed, 315 insertions(+), 96 deletions(-) diff --git a/dist/index.js b/dist/index.js index c6ea6b8..d12ee16 100644 --- a/dist/index.js +++ b/dist/index.js @@ -34569,22 +34569,67 @@ class ResizeableBuffer { ;// CONCATENATED MODULE: ./node_modules/csv-parse/lib/api/init_state.js -// white space characters -// https://en.wikipedia.org/wiki/Whitespace_character -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Types -// \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff -const np = 12; -const cr = 13; // `\r`, carriage return, 0x0D in hexadécimal, 13 in decimal -const nl = 10; // `\n`, newline, 0x0A in hexadecimal, 10 in decimal -const space = 32; -const tab = 9; - const init_state = function (options) { + // ECMAScript WhiteSpace + LineTerminator codepoints, encoded under + // `options.encoding`. Aligns trimming with `String.prototype.trim()`. + // https://tc39.es/ecma262/#sec-white-space + // https://tc39.es/ecma262/#sec-line-terminators + // + // Codepoints unrepresentable in the target encoding are dropped: Node's + // Buffer substitutes them with `?` (0x3F), and including those would cause + // literal `?` bytes in the input to be trimmed under `latin1`/`ascii`. + const timchars = [ + // Basic Latin + 0x0020, // [Space](https://www.fileformat.info/info/unicode/char/0020/index.htm) + 0x0009, // [CHARACTER TABULATION (HT)](https://www.fileformat.info/info/unicode/char/0009/index.htm) + 0x000a, // [LINE FEED (LF)](https://www.fileformat.info/info/unicode/char/000a/index.htm) + 0x000d, // [CARRIAGE RETURN (CR)](https://www.fileformat.info/info/unicode/char/000d/index.htm) + 0x000c, // [FORM FEED (FF)](https://www.fileformat.info/info/unicode/char/000c/index.htm) + 0x000b, // [LINE TABULATION (VT)](https://www.fileformat.info/info/unicode/char/000b/index.htm) + // Latin-1 Supplement + 0x00a0, // [NO-BREAK SPACE (NBSP)](https://www.fileformat.info/info/unicode/char/00a0/index.htm) + // Ogham + 0x1680, // [OGHAM SPACE MARK](https://www.fileformat.info/info/unicode/char/1680/index.htm) + // General Punctuation + 0x2000, // [EN QUAD](https://www.fileformat.info/info/unicode/char/2000/index.htm) + 0x2001, // [EM QUAD](https://www.fileformat.info/info/unicode/char/2001/index.htm) + 0x2002, // [EN SPACE](https://www.fileformat.info/info/unicode/char/2002/index.htm) + 0x2003, // [EM SPACE](https://www.fileformat.info/info/unicode/char/2003/index.htm) + 0x2004, // [THREE-PER-EM SPACE](https://www.fileformat.info/info/unicode/char/2004/index.htm) + 0x2005, // [FOUR-PER-EM SPACE](https://www.fileformat.info/info/unicode/char/2005/index.htm) + 0x2006, // [SIX-PER-EM SPACE](https://www.fileformat.info/info/unicode/char/2006/index.htm) + 0x2007, // [FIGURE SPACE](https://www.fileformat.info/info/unicode/char/2007/index.htm) + 0x2008, // [PUNCTUATION SPACE](https://www.fileformat.info/info/unicode/char/2008/index.htm) + 0x2009, // [THIN SPACE](https://www.fileformat.info/info/unicode/char/2009/index.htm) + 0x200a, // [HAIR SPACE](https://www.fileformat.info/info/unicode/char/200a/index.htm) + 0x2028, // [LINE SEPARATOR](https://www.fileformat.info/info/unicode/char/2028/index.htm) + 0x2029, // [PARAGRAPH SEPARATOR](https://www.fileformat.info/info/unicode/char/2029/index.htm) + 0x202f, // [NARROW NO-BREAK SPACE (NNBSP)](https://www.fileformat.info/info/unicode/char/202f/index.htm) + 0x205f, // [MEDIUM MATHEMATICAL SPACE (MMSP)](https://www.fileformat.info/info/unicode/char/205f/index.htm) + 0x3000, // [IDEOGRAPHIC SPACE](https://www.fileformat.info/info/unicode/char/3000/index.htm) + 0xfeff, // [ZERO WIDTH NO-BREAK SPACE (BOM)](https://www.fileformat.info/info/unicode/char/feff/index.htm) + ].reduce((acc, codepoint) => { + const encoded = Buffer.from( + String.fromCharCode(codepoint), + options.encoding, + ); + if (codepoint !== 0x3f && encoded.length === 1 && encoded[0] === 0x3f) { + return acc; + } + acc.push(encoded); + return acc; + }, []); + // First-byte lookup table for `__isCharTrimable`. Non-whitespace bytes + // (the common case) bail out in O(1) without scanning every timchar. + const timcharFirstBytes = new Uint8Array(256); + for (const t of timchars) timcharFirstBytes[t[0]] = 1; return { bomSkipped: false, bufBytesStart: 0, castField: options.cast_function, commenting: false, + delimiterBufPrevious: undefined, + delimiterDiscovered: false, // Current error encountered by a record error: undefined, enabled: options.from_line === 1, @@ -34603,9 +34648,15 @@ const init_state = function (options) { // Skip if the remaining buffer smaller than comment options.comment !== null ? options.comment.length : 0, // Skip if the remaining buffer can be delimiter - ...options.delimiter.map((delimiter) => delimiter.length), + ...(options.delimiter + ? options.delimiter.map((delimiter) => delimiter.length) + : []), + // Auto discovery of delimiter is limited to 1 character + options.delimiter_auto ? 1 : 0, // Skip if the remaining buffer can be escape sequence options.quote !== null ? options.quote.length : 0, + // Skip if the remaining buffer can be a multi-byte trim character + ...timchars.map((t) => t.length), ), previousBuf: undefined, quoting: false, @@ -34624,13 +34675,8 @@ const init_state = function (options) { ], wasQuoting: false, wasRowDelimiter: false, - timchars: [ - Buffer.from(Buffer.from([cr], "utf8").toString(), options.encoding), - Buffer.from(Buffer.from([nl], "utf8").toString(), options.encoding), - Buffer.from(Buffer.from([np], "utf8").toString(), options.encoding), - Buffer.from(Buffer.from([space], "utf8").toString(), options.encoding), - Buffer.from(Buffer.from([tab], "utf8").toString(), options.encoding), - ], + timchars: timchars, + timcharFirstBytes: timcharFirstBytes, }; }; @@ -34650,6 +34696,7 @@ const underscore = function (str) { + const normalize_options = function (opts) { const options = {}; // Merge with user options @@ -34838,25 +34885,95 @@ const normalize_options = function (opts) { options, ); } - // Normalize option `delimiter` - const delimiter_json = JSON.stringify(options.delimiter); - if (!Array.isArray(options.delimiter)) - options.delimiter = [options.delimiter]; - if (options.delimiter.length === 0) { + // Normalize option `delimiter_auto` + if ( + options.delimiter_auto === undefined || + options.delimiter_auto === null || + options.delimiter_auto === false + ) { + options.delimiter_auto = false; + } else if (options.delimiter_auto === true) { + options.delimiter_auto = {}; + } else if (!is_object(options.delimiter_auto)) { throw new CsvError( - "CSV_INVALID_OPTION_DELIMITER", + "CSV_INVALID_OPTION_DELIMITER_AUTO", [ - "Invalid option delimiter:", - "delimiter must be a non empty string or buffer or array of string|buffer,", - `got ${delimiter_json}`, + "Invalid option delimiter_auto:", + "delimiter_auto must be a boolean or a configuration object,", + `got ${JSON.stringify(options.delimiter_auto)}`, ], options, ); } - options.delimiter = options.delimiter.map(function (delimiter) { - if (delimiter === undefined || delimiter === null || delimiter === false) { - return Buffer.from(",", options.encoding); + if (options.delimiter_auto) { + if (options.delimiter_auto.preferred === undefined) + options.delimiter_auto.preferred = { + [",".charCodeAt(0)]: 1.8, + ["\t".charCodeAt(0)]: 1.8, + [";".charCodeAt(0)]: 1.6, + [" ".charCodeAt(0)]: 1.6, + [":".charCodeAt(0)]: 1.5, + [".".charCodeAt(0)]: 1.4, + ["/".charCodeAt(0)]: 1.4, + }; + else if (!is_object(options.delimiter_auto.preferred)) { + throw new CsvError( + "CSV_INVALID_OPTION_DELIMITER_AUTO", + [ + "Invalid option delimiter_auto:", + "preferred must be an object,", + `got ${JSON.stringify(options.delimiter_auto.preferred)}`, + ], + options, + ); } + if (options.delimiter_auto.score === undefined) + options.delimiter_auto.score = (info, options) => { + return ( + (info.total - info.std) * (options.preferred[info.char_code] || 1) + ); + }; + else if (typeof options.delimiter_auto.score !== "function") { + throw new CsvError( + "CSV_INVALID_OPTION_DELIMITER_AUTO", + [ + "Invalid option delimiter_auto:", + "score must be a function,", + `got ${JSON.stringify(options.delimiter_auto.score)}`, + ], + options, + ); + } + if (options.delimiter_auto.size === undefined) + options.delimiter_auto.size = 2048; + else if (typeof options.delimiter_auto.size !== "number") { + throw new CsvError( + "CSV_INVALID_OPTION_DELIMITER_AUTO", + [ + "Invalid option delimiter_auto:", + "size must be a number,", + `got ${JSON.stringify(options.delimiter_auto.size)}`, + ], + options, + ); + } + } + // Normalize option `delimiter` + const delimiter_json = JSON.stringify(options.delimiter); + if (options.delimiter_auto !== false) { + options.delimiter = []; + } + if (!Array.isArray(options.delimiter)) { + if ( + options.delimiter === undefined || + options.delimiter === null || + options.delimiter === false + ) { + options.delimiter = Buffer.from(",", options.encoding); + } + options.delimiter = [options.delimiter]; + } + options.delimiter = options.delimiter.map(function (delimiter) { if (typeof delimiter === "string") { delimiter = Buffer.from(delimiter, options.encoding); } @@ -35338,12 +35455,80 @@ const normalize_options = function (opts) { +;// CONCATENATED MODULE: ./node_modules/csv-parse/lib/utils/delimiter_discover.js + + + +// Discussed in [issue #400](https://github.com/adaltas/node-csv/issues/400) +// See https://github.com/python/cpython/blob/ea1b1c579f600cc85d145c60862b2e6b98701b24/Lib/csv.py#L349 +const delimiter_discover = function (records, options) { + // Normalize the configuration + if (!options) { + ({ delimiter_auto: options } = normalize_options({ delimiter_auto: true })); + } + // Convert String to Buffer + if (typeof records === "string") { + records = Buffer.from(records); + } + // Convert Buffer to an array of records + if (Buffer.isBuffer(records)) { + records = ((data) => { + const records = []; + const parser = transform({ delimiter: [] }); + const push = (record) => records.push(record); + const close = () => {}; + const error = parser.parse(data, true, push, close); + if (error !== undefined) throw error; + return records; + })(records); + } + // Info array initialization, 127 entries, one per char code + const info = Array(127) + .fill() + .map(() => ({ lines: [] })); + // Traverse each records, count occurences per char code + records.map(([record], line) => { + for (let i = 0, l = record.length; i < l; i++) { + // Count the character frequency + const code = record.charCodeAt(i); + if (info[code].lines[line] === undefined) info[code].lines[line] = 0; + info[code].lines[line]++; + } + }); + // Traverse each char code, compute the score + info.map((info, i) => { + info.char_code = i; + info.std = std(info.lines); + info.total = info.lines.reduce((acc, val) => acc + val, 0); + info.preferred = !!options.preferred[i]; + info.score = options.score(info, options); + }); + // Extract the dominant character + const result = info.reduce( + (acc, info) => (acc.score > info.score ? acc : info), + {}, + ); + return String.fromCharCode(result.char_code); +}; + +const std = function (array) { + const n = array.length; + if (n === 0) return 0; + const mean = array.reduce((a, b) => a + b) / n; + return Math.sqrt( + array.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n, + ); +}; + + + ;// CONCATENATED MODULE: ./node_modules/csv-parse/lib/api/index.js + const isRecordEmpty = function (record) { return record.every( (field) => @@ -35351,8 +35536,8 @@ const isRecordEmpty = function (record) { ); }; -const api_cr = 13; // `\r`, carriage return, 0x0D in hexadécimal, 13 in decimal -const api_nl = 10; // `\n`, newline, 0x0A in hexadecimal, 10 in decimal +const cr = 13; // `\r`, carriage return, 0x0D in hexadécimal, 13 in decimal +const nl = 10; // `\n`, newline, 0x0A in hexadecimal, 10 in decimal const boms = { // Note, the following are equals: @@ -35411,6 +35596,7 @@ const transform = function (original_options = {}) { const { bom, comment_no_infix, + delimiter_auto, encoding, from_line, ltrim, @@ -35423,7 +35609,45 @@ const transform = function (original_options = {}) { to_line, } = this.options; let { comment, escape, quote, record_delimiter } = this.options; - const { bomSkipped, previousBuf, rawBuffer, escapeIsQuote } = this.state; + const { + bomSkipped, + delimiterDiscovered, + delimiterBufPrevious, + rawBuffer, + escapeIsQuote, + } = this.state; + // Automatic delimiter discovery + if (!delimiterDiscovered && delimiter_auto) { + let delimiterBuf; + if (delimiterBufPrevious === undefined) { + delimiterBuf = nextBuf; + } else if ( + delimiterBufPrevious !== undefined && + nextBuf === undefined + ) { + delimiterBuf = delimiterBufPrevious; + } else { + delimiterBuf = Buffer.concat([delimiterBufPrevious, nextBuf]); + } + // Ensure that nextBuf is not concatenated a second time during buffer reconciliation + nextBuf = undefined; + // this.delimiterBufPrevious = delimiterBuf; + if (end || delimiterBuf.length > delimiter_auto.size) { + this.options.delimiter = [ + Buffer.from( + delimiter_discover(delimiterBuf, this.options.delimiter_auto), + ), + ]; + this.state.previousBuf = delimiterBuf; + this.state.delimiterBufPrevious = undefined; + this.state.delimiterDiscovered = true; + } else { + this.state.delimiterBufPrevious = delimiterBuf; + return; + } + } + // Previous buffers reconciliation + const { previousBuf } = this.state; let buf; if (previousBuf === undefined) { if (nextBuf === undefined) { @@ -35505,7 +35729,7 @@ const transform = function (original_options = {}) { rawBuffer.append(chr); } if ( - (chr === api_cr || chr === api_nl) && + (chr === cr || chr === nl) && this.state.wasRowDelimiter === false ) { this.state.wasRowDelimiter = true; @@ -36078,30 +36302,6 @@ const transform = function (original_options = {}) { } return [undefined, field]; }, - // Helper to test if a character is a space or a line delimiter - __isCharTrimable: function (buf, pos) { - const isTrim = (buf, pos) => { - const { timchars } = this.state; - loop1: for (let i = 0; i < timchars.length; i++) { - const timchar = timchars[i]; - for (let j = 0; j < timchar.length; j++) { - if (timchar[j] !== buf[pos + j]) continue loop1; - } - return timchar.length; - } - return 0; - }; - return isTrim(buf, pos); - }, - // Keep it in case we implement the `cast_int` option - // __isInt(value){ - // // return Number.isInteger(parseInt(value)) - // // return !isNaN( parseInt( obj ) ); - // return /^(\-|\+)?[1-9][0-9]*$/.test(value) - // } - __isFloat: function (value) { - return value - parseFloat(value) + 1 >= 0; // Borrowed from jquery - }, __compareBytes: function (sourceBuf, targetBuf, targetPos, firstByte) { if (sourceBuf[0] !== firstByte) return 0; const sourceLength = sourceBuf.length; @@ -36110,6 +36310,22 @@ const transform = function (original_options = {}) { } return sourceLength; }, + // Helper to test if a character is trimable + __isCharTrimable: function (buf, pos) { + const { timchars, timcharFirstBytes } = this.state; + // Fast bail-out: non-whitespace bytes (the common case) are rejected + // without scanning the full timchar list. + const first = buf[pos]; + if (first === undefined || timcharFirstBytes[first] === 0) return 0; + loop1: for (let i = 0; i < timchars.length; i++) { + const timchar = timchars[i]; + for (let j = 0; j < timchar.length; j++) { + if (timchar[j] !== buf[pos + j]) continue loop1; + } + return timchar.length; + } + return 0; + }, __isDelimiter: function (buf, pos, chr) { const { delimiter, ignore_last_delimiters } = this.options; if ( @@ -36135,6 +36351,40 @@ const transform = function (original_options = {}) { } return 0; }, + __isEscape: function (buf, pos, chr) { + const { escape } = this.options; + if (escape === null) return false; + const l = escape.length; + if (escape[0] === chr) { + for (let i = 0; i < l; i++) { + if (escape[i] !== buf[pos + i]) { + return false; + } + } + return true; + } + return false; + }, + __isFloat: function (value) { + return value - parseFloat(value) + 1 >= 0; // Borrowed from jquery + }, + // Keep it in case we implement the `cast_int` option + // __isInt(value){ + // // return Number.isInteger(parseInt(value)) + // // return !isNaN( parseInt( obj ) ); + // return /^(\-|\+)?[1-9][0-9]*$/.test(value) + // } + __isQuote: function (buf, pos) { + const { quote } = this.options; + if (quote === null) return false; + const l = quote.length; + for (let i = 0; i < l; i++) { + if (quote[i] !== buf[pos + i]) { + return false; + } + } + return true; + }, __isRecordDelimiter: function (chr, buf, pos) { const { record_delimiter } = this.options; const recordDelimiterLength = record_delimiter.length; @@ -36153,31 +36403,6 @@ const transform = function (original_options = {}) { } return 0; }, - __isEscape: function (buf, pos, chr) { - const { escape } = this.options; - if (escape === null) return false; - const l = escape.length; - if (escape[0] === chr) { - for (let i = 0; i < l; i++) { - if (escape[i] !== buf[pos + i]) { - return false; - } - } - return true; - } - return false; - }, - __isQuote: function (buf, pos) { - const { quote } = this.options; - if (quote === null) return false; - const l = quote.length; - for (let i = 0; i < l; i++) { - if (quote[i] !== buf[pos + i]) { - return false; - } - } - return true; - }, __autoDiscoverRecordDelimiter: function (buf, pos) { const { encoding } = this.options; // Note, we don't need to cache this information in state, @@ -36265,11 +36490,12 @@ const transform = function (original_options = {}) { ;// CONCATENATED MODULE: ./node_modules/csv-parse/lib/sync.js + const parse = function (data, opts = {}) { if (typeof data === "string") { data = Buffer.from(data); } - const records = opts && opts.objname ? {} : []; + const records = opts && opts.objname ? Object.create(null) : []; const parser = transform(opts); const push = (record) => { if (parser.options.objname === undefined) records.push(record); @@ -36280,16 +36506,9 @@ const parse = function (data, opts = {}) { const close = () => {}; const error = parser.parse(data, true, push, close); if (error !== undefined) throw error; - // 250606: `parser.parse` was implemented as 2 calls: - // const err1 = parser.parse(data, false, push, close); - // if (err1 !== undefined) throw err1; - // const err2 = parser.parse(undefined, true, push, close); - // if (err2 !== undefined) throw err2; return records; }; -// export default parse - ;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/error.js diff --git a/package-lock.json b/package-lock.json index 32baa4c..5e6ff37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "@actions/core": "3.0.0", "@actions/exec": "3.0.0", "@actions/tool-cache": "4.0.0", - "csv-parse": "6.2.1", + "csv-parse": "7.0.0", "semver": "7.7.4", "smol-toml": "1.6.1" }, @@ -838,9 +838,9 @@ } }, "node_modules/csv-parse": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-6.2.1.tgz", - "integrity": "sha512-LRLMV+UCyfMokp8Wb411duBf1gaBKJfOfBWU9eHMJ+b+cJYZsNu3AFmjJf3+yPGd59Exz1TsMjaSFyxnYB9+IQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-7.0.0.tgz", + "integrity": "sha512-CSssqPAK5us09FhMI9juM0jnqXUJP+rtWeIfivTYBLNH/8rnxkQlZvoRemF6MAyfNov9XU8mN2wwF/pP68sxTA==", "license": "MIT" }, "node_modules/debug": { diff --git a/package.json b/package.json index 8d12aba..0a19f87 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@actions/core": "3.0.0", "@actions/exec": "3.0.0", "@actions/tool-cache": "4.0.0", - "csv-parse": "6.2.1", + "csv-parse": "7.0.0", "semver": "7.7.4", "smol-toml": "1.6.1" },