diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index 7e82ead..26f9e38 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -18,20 +18,20 @@ } }, "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", - "content-type": "^1.0.5", + "content-type": "^2.0.0", "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" }, "engines": { "node": ">=18" @@ -41,6 +41,19 @@ "url": "https://opencollective.com/express" } }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -193,9 +206,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -372,9 +385,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -553,9 +566,9 @@ } }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", @@ -576,12 +589,13 @@ } }, "node_modules/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -688,14 +702,14 @@ "license": "ISC" }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -707,13 +721,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -778,17 +792,34 @@ } }, "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", "license": "MIT", "dependencies": { - "content-type": "^1.0.5", + "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/unpipe": { diff --git a/node_modules/body-parser/README.md b/node_modules/body-parser/README.md index 39d320f..335743d 100644 --- a/node_modules/body-parser/README.md +++ b/node_modules/body-parser/README.md @@ -51,7 +51,14 @@ $ npm install body-parser ## API ```js +// Import all parsers const bodyParser = require('body-parser') + +// Or import individual parsers directly +const json = require('body-parser/json') +const urlencoded = require('body-parser/urlencoded') +const raw = require('body-parser/raw') +const text = require('body-parser/text') ``` The `bodyParser` object exposes various factories to create middlewares. All @@ -93,11 +100,13 @@ specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults to `'100kb'`. +> It’s recommended not to configure a very high limit and to use the default value whenever possible. Allowing larger payloads increases memory usage because of the resources required for decoding and transformations, and it can also lead to longer response times as more data is processed. By ‘very high’, we mean values above the default, for example payloads of 5 MB or more can already start to introduce these risks. With the default limits, these issues do not occur. + ##### reviver The `reviver` option is passed directly to `JSON.parse` as the second argument. You can find more information on this argument -[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter). +[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#the_reviver_parameter). ##### strict @@ -149,6 +158,8 @@ specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults to `'100kb'`. +> It’s recommended not to configure a very high limit and to use the default value whenever possible. Allowing larger payloads increases memory usage because of the resources required for decoding and transformations, and it can also lead to longer response times as more data is processed. By ‘very high’, we mean values above the default, for example payloads of 5 MB or more can already start to introduce these risks. With the default limits, these issues do not occur. + ##### type The `type` option is used to determine what media type the middleware will @@ -200,6 +211,8 @@ specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults to `'100kb'`. +> It’s recommended not to configure a very high limit and to use the default value whenever possible. Allowing larger payloads increases memory usage because of the resources required for decoding and transformations, and it can also lead to longer response times as more data is processed. By ‘very high’, we mean values above the default, for example payloads of 5 MB or more can already start to introduce these risks. With the default limits, these issues do not occur. + ##### type The `type` option is used to determine what media type the middleware will @@ -255,6 +268,8 @@ specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults to `'100kb'`. +> It’s recommended not to configure a very high limit and to use the default value whenever possible. Allowing larger payloads increases memory usage because of the resources required for decoding and transformations, and it can also lead to longer response times as more data is processed. By ‘very high’, we mean values above the default, for example payloads of 5 MB or more can already start to introduce these risks. With the default limits, these issues do not occur. + ##### parameterLimit The `parameterLimit` option controls the maximum number of parameters that diff --git a/node_modules/body-parser/index.js b/node_modules/body-parser/index.js index 013ce5c..c0526e1 100644 --- a/node_modules/body-parser/index.js +++ b/node_modules/body-parser/index.js @@ -24,41 +24,25 @@ exports = module.exports = bodyParser * JSON parser. * @public */ -Object.defineProperty(exports, 'json', { - configurable: true, - enumerable: true, - get: () => require('./lib/types/json') -}) +exports.json = require('./lib/types/json') /** * Raw parser. * @public */ -Object.defineProperty(exports, 'raw', { - configurable: true, - enumerable: true, - get: () => require('./lib/types/raw') -}) +exports.raw = require('./lib/types/raw') /** * Text parser. * @public */ -Object.defineProperty(exports, 'text', { - configurable: true, - enumerable: true, - get: () => require('./lib/types/text') -}) +exports.text = require('./lib/types/text') /** * URL-encoded parser. * @public */ -Object.defineProperty(exports, 'urlencoded', { - configurable: true, - enumerable: true, - get: () => require('./lib/types/urlencoded') -}) +exports.urlencoded = require('./lib/types/urlencoded') /** * Create a middleware to parse json and urlencoded bodies. diff --git a/node_modules/body-parser/lib/read.js b/node_modules/body-parser/lib/read.js index d1f3f48..bf1a1df 100644 --- a/node_modules/body-parser/lib/read.js +++ b/node_modules/body-parser/lib/read.js @@ -11,13 +11,13 @@ * @private */ -var createError = require('http-errors') -var getBody = require('raw-body') -var iconv = require('iconv-lite') -var onFinished = require('on-finished') -var zlib = require('node:zlib') -var hasBody = require('type-is').hasBody -var { getCharset } = require('./utils') +const createError = require('http-errors') +const getBody = require('raw-body') +const iconv = require('iconv-lite') +const onFinished = require('on-finished') +const zlib = require('node:zlib') +const hasBody = require('type-is').hasBody +const { getCharset } = require('./utils') /** * Module exports. @@ -63,7 +63,7 @@ function read (req, res, next, parse, debug, options) { return } - var encoding = null + let encoding = null if (options?.skipCharset !== true) { encoding = getCharset(req) || options.defaultCharset @@ -78,12 +78,12 @@ function read (req, res, next, parse, debug, options) { } } - var length - var opts = options - var stream + let length + const opts = options + let stream // read options - var verify = opts.verify + const verify = opts.verify try { // get the content stream @@ -112,7 +112,7 @@ function read (req, res, next, parse, debug, options) { debug('read body') getBody(stream, opts, function (error, body) { if (error) { - var _error + let _error if (error.type === 'encoding.unsupported') { // echo back charset @@ -153,7 +153,7 @@ function read (req, res, next, parse, debug, options) { } // parse - var str = body + let str = body try { debug('parse body') str = typeof body !== 'string' && encoding !== null @@ -182,8 +182,8 @@ function read (req, res, next, parse, debug, options) { * @private */ function contentstream (req, debug, inflate) { - var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() - var length = req.headers['content-length'] + const encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() + const length = req.headers['content-length'] debug('content-encoding "%s"', encoding) @@ -199,7 +199,7 @@ function contentstream (req, debug, inflate) { return req } - var stream = createDecompressionStream(encoding, debug) + const stream = createDecompressionStream(encoding, debug) req.pipe(stream) return stream } diff --git a/node_modules/body-parser/lib/types/json.js b/node_modules/body-parser/lib/types/json.js index 23c7357..14ca3e4 100644 --- a/node_modules/body-parser/lib/types/json.js +++ b/node_modules/body-parser/lib/types/json.js @@ -12,9 +12,9 @@ * @private */ -var debug = require('debug')('body-parser:json') -var read = require('../read') -var { normalizeOptions } = require('../utils') +const debug = require('debug')('body-parser:json') +const read = require('../read') +const { normalizeOptions } = require('../utils') /** * Module exports. @@ -33,10 +33,10 @@ module.exports = json * %x0A / ; Line feed or New line * %x0D ) ; Carriage return */ -var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex +const FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex -var JSON_SYNTAX_CHAR = '#' -var JSON_SYNTAX_REGEXP = /#+/g +const JSON_SYNTAX_CHAR = '#' +const JSON_SYNTAX_REGEXP = /#+/g /** * Create a middleware to parse JSON bodies. @@ -48,35 +48,7 @@ var JSON_SYNTAX_REGEXP = /#+/g function json (options) { const normalizedOptions = normalizeOptions(options, 'application/json') - var reviver = options?.reviver - var strict = options?.strict !== false - - function parse (body) { - if (body.length === 0) { - // special-case empty json body, as it's a common client-side mistake - // TODO: maybe make this configurable or part of "strict" option - return {} - } - - if (strict) { - var first = firstchar(body) - - if (first !== '{' && first !== '[') { - debug('strict violation') - throw createStrictSyntaxError(body, first) - } - } - - try { - debug('parse json') - return JSON.parse(body, reviver) - } catch (e) { - throw normalizeJsonSyntaxError(e, { - message: e.message, - stack: e.stack - }) - } - } + const parse = createJsonParser(options) const readOptions = { ...normalizedOptions, @@ -89,6 +61,62 @@ function json (options) { } } +/** + * Create a JSON parse function + * + * @param {object} [options] + * @return {function} + * @private + */ +function createJsonParser (options) { + const reviver = options?.reviver + const strict = options?.strict !== false + + if (strict) { + return function parse (body) { + if (body.length === 0) { + // special-case empty json body, as it's a common client-side mistake + // TODO: maybe make this configurable or part of "strict" option + return {} + } + + const first = firstchar(body) + if (first !== '{' && first !== '[') { + debug('strict violation') + throw createStrictSyntaxError(body, first) + } + + try { + debug('parse json') + return JSON.parse(body, reviver) + } catch (e) { + throw normalizeJsonSyntaxError(e, { + message: e.message, + stack: e.stack + }) + } + } + } + + return function parse (body) { + if (body.length === 0) { + // special-case empty json body, as it's a common client-side mistake + // TODO: maybe make this configurable or part of "strict" option + return {} + } + + try { + debug('parse json') + return JSON.parse(body, reviver) + } catch (e) { + throw normalizeJsonSyntaxError(e, { + message: e.message, + stack: e.stack + }) + } + } +} + /** * Create strict violation syntax error matching native error. * @@ -98,8 +126,8 @@ function json (options) { * @private */ function createStrictSyntaxError (str, char) { - var index = str.indexOf(char) - var partial = '' + const index = str.indexOf(char) + let partial = '' if (index !== -1) { partial = str.substring(0, index) + JSON_SYNTAX_CHAR.repeat(str.length - index) @@ -125,7 +153,7 @@ function createStrictSyntaxError (str, char) { * @private */ function firstchar (str) { - var match = FIRST_CHAR_REGEXP.exec(str) + const match = FIRST_CHAR_REGEXP.exec(str) return match ? match[1] @@ -141,10 +169,10 @@ function firstchar (str) { * @private */ function normalizeJsonSyntaxError (error, obj) { - var keys = Object.getOwnPropertyNames(error) + const keys = Object.getOwnPropertyNames(error) - for (var i = 0; i < keys.length; i++) { - var key = keys[i] + for (let i = 0; i < keys.length; i++) { + const key = keys[i] if (key !== 'stack' && key !== 'message') { delete error[key] } diff --git a/node_modules/body-parser/lib/types/raw.js b/node_modules/body-parser/lib/types/raw.js index ad4854d..c84083b 100644 --- a/node_modules/body-parser/lib/types/raw.js +++ b/node_modules/body-parser/lib/types/raw.js @@ -10,9 +10,9 @@ * Module dependencies. */ -var debug = require('debug')('body-parser:raw') -var read = require('../read') -var { normalizeOptions, passthrough } = require('../utils') +const debug = require('debug')('body-parser:raw') +const read = require('../read') +const { normalizeOptions, passthrough } = require('../utils') /** * Module exports. diff --git a/node_modules/body-parser/lib/types/text.js b/node_modules/body-parser/lib/types/text.js index 9df73be..893c801 100644 --- a/node_modules/body-parser/lib/types/text.js +++ b/node_modules/body-parser/lib/types/text.js @@ -10,9 +10,9 @@ * Module dependencies. */ -var debug = require('debug')('body-parser:text') -var read = require('../read') -var { normalizeOptions, passthrough } = require('../utils') +const debug = require('debug')('body-parser:text') +const read = require('../read') +const { normalizeOptions, passthrough } = require('../utils') /** * Module exports. diff --git a/node_modules/body-parser/lib/types/urlencoded.js b/node_modules/body-parser/lib/types/urlencoded.js index 4a3227c..1db964c 100644 --- a/node_modules/body-parser/lib/types/urlencoded.js +++ b/node_modules/body-parser/lib/types/urlencoded.js @@ -12,11 +12,11 @@ * @private */ -var createError = require('http-errors') -var debug = require('debug')('body-parser:urlencoded') -var read = require('../read') -var qs = require('qs') -var { normalizeOptions } = require('../utils') +const createError = require('http-errors') +const debug = require('debug')('body-parser:urlencoded') +const read = require('../read') +const qs = require('qs') +const { normalizeOptions } = require('../utils') /** * Module exports. @@ -39,13 +39,7 @@ function urlencoded (options) { } // create the appropriate query parser - var queryparse = createQueryParser(options) - - function parse (body, encoding) { - return body.length - ? queryparse(body, encoding) - : {} - } + const parse = createQueryParser(options) const readOptions = { ...normalizedOptions, @@ -66,13 +60,13 @@ function urlencoded (options) { * @private */ function createQueryParser (options) { - var extended = Boolean(options?.extended) - var parameterLimit = options?.parameterLimit !== undefined + const extended = Boolean(options?.extended) + let parameterLimit = options?.parameterLimit !== undefined ? options?.parameterLimit : 1000 - var charsetSentinel = options?.charsetSentinel - var interpretNumericEntities = options?.interpretNumericEntities - var depth = extended ? (options?.depth !== undefined ? options?.depth : 32) : 0 + const charsetSentinel = options?.charsetSentinel + const interpretNumericEntities = options?.interpretNumericEntities + const depth = extended ? (options?.depth !== undefined ? options?.depth : 32) : 0 if (isNaN(parameterLimit) || parameterLimit < 1) { throw new TypeError('option parameterLimit must be a positive number') @@ -86,8 +80,10 @@ function createQueryParser (options) { parameterLimit = parameterLimit | 0 } - return function queryparse (body, encoding) { - var paramCount = parameterCount(body, parameterLimit) + return function parse (body, encoding) { + if (!body.length) return {} + + const paramCount = parameterCount(body, parameterLimit) if (paramCount === undefined) { debug('too many parameters') @@ -96,7 +92,7 @@ function createQueryParser (options) { }) } - var arrayLimit = extended ? Math.max(100, paramCount) : paramCount + const arrayLimit = extended ? Math.max(100, paramCount) : paramCount debug('parse ' + (extended ? 'extended ' : '') + 'urlencoding') try { diff --git a/node_modules/body-parser/lib/utils.js b/node_modules/body-parser/lib/utils.js index e0bf974..7a0dda4 100644 --- a/node_modules/body-parser/lib/utils.js +++ b/node_modules/body-parser/lib/utils.js @@ -4,9 +4,9 @@ * Module dependencies. */ -var bytes = require('bytes') -var contentType = require('content-type') -var typeis = require('type-is') +const bytes = require('bytes') +const contentType = require('content-type') +const typeis = require('type-is') /** * Module exports. @@ -25,11 +25,9 @@ module.exports = { * @private */ function getCharset (req) { - try { - return (contentType.parse(req).parameters.charset || '').toLowerCase() - } catch { - return undefined - } + const header = req.headers['content-type'] + if (!header) return undefined + return contentType.parse(header).parameters.charset?.toLowerCase() } /** @@ -59,20 +57,24 @@ function normalizeOptions (options, defaultType) { throw new TypeError('defaultType must be provided') } - var inflate = options?.inflate !== false - var limit = typeof options?.limit !== 'number' - ? bytes.parse(options?.limit || '100kb') - : options?.limit - var type = options?.type || defaultType - var verify = options?.verify || false - var defaultCharset = options?.defaultCharset || 'utf-8' + const inflate = options?.inflate !== false + const limit = typeof options?.limit === 'undefined' || options?.limit === null + ? 102400 // 100kb default + : bytes.parse(options.limit) + const type = options?.type || defaultType + const verify = options?.verify || false + const defaultCharset = options?.defaultCharset || 'utf-8' + + if (limit === null) { + throw new TypeError(`option limit "${String(options.limit)}" is invalid`) + } if (verify !== false && typeof verify !== 'function') { throw new TypeError('option verify must be function') } // create the appropriate type checking function - var shouldParse = typeof type !== 'function' + const shouldParse = typeof type !== 'function' ? typeChecker(type) : type diff --git a/node_modules/body-parser/node_modules/content-type/LICENSE b/node_modules/body-parser/node_modules/content-type/LICENSE new file mode 100644 index 0000000..34b1a2d --- /dev/null +++ b/node_modules/body-parser/node_modules/content-type/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2015 Douglas Christopher Wilson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/body-parser/node_modules/content-type/README.md b/node_modules/body-parser/node_modules/content-type/README.md new file mode 100644 index 0000000..7f6847d --- /dev/null +++ b/node_modules/body-parser/node_modules/content-type/README.md @@ -0,0 +1,69 @@ +# content-type + +[![NPM version][npm-image]][npm-url] +[![NPM downloads][downloads-image]][downloads-url] +[![Build status][build-image]][build-url] +[![Build coverage][coverage-image]][coverage-url] +[![License][license-image]][license-url] + +Create and parse HTTP `Content-Type` header. + +## Installation + +```sh +npm install content-type +``` + +## API + +```js +const contentType = require("content-type"); +``` + +### contentType.parse(string, options?) + +```js +const obj = contentType.parse("image/svg+xml; charset=utf-8"); +``` + +Parse a `Content-Type` header. This will return an object with the following properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`): + +- `type`: The media type. Example: `'image/svg+xml'`. +- `parameters`: An object of the parameters in the media type (parameter name is always lower case). Example: `{charset: 'utf-8'}`. + +The parser is lenient and does not error. You should validate `type` and `parameters` before trusting them. + +#### Options + +- `parameters` (default: `true`): Set to `false` to skip parameters. + +### contentType.format(obj) + +```js +const str = contentType.format({ + type: "image/svg+xml", + parameters: { charset: "utf-8" }, +}); +``` + +Format an object into a `Content-Type` header. This will return a string of the content type for the given object with the following properties (examples are shown that produce the string `'image/svg+xml; charset=utf-8'`): + +- `type`: The media type. Example: `'image/svg+xml'`. +- `parameters`: An optional object of the parameters in the media type. Example: `{charset: 'utf-8'}`. + +Throws a `TypeError` if the object contains an invalid type or parameter names. + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/content-type +[npm-url]: https://npmjs.org/package/content-type +[downloads-image]: https://img.shields.io/npm/dm/content-type +[downloads-url]: https://npmjs.org/package/content-type +[build-image]: https://img.shields.io/github/actions/workflow/status/jshttp/content-type/ci.yml?branch=master +[build-url]: https://github.com/jshttp/content-type/actions/workflows/ci.yml?query=branch%3Amaster +[coverage-image]: https://img.shields.io/codecov/c/gh/jshttp/content-type +[coverage-url]: https://codecov.io/gh/jshttp/content-type +[license-image]: http://img.shields.io/npm/l/content-type.svg?style=flat +[license-url]: LICENSE diff --git a/node_modules/body-parser/node_modules/content-type/dist/index.d.ts b/node_modules/body-parser/node_modules/content-type/dist/index.d.ts new file mode 100644 index 0000000..7e72898 --- /dev/null +++ b/node_modules/body-parser/node_modules/content-type/dist/index.d.ts @@ -0,0 +1,26 @@ +/*! + * content-type + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ +/** + * The content type object contains a type string and optional parameters. + */ +export interface ContentType { + type: string; + parameters: Record; +} +/** + * Format an object into a `Content-Type` header. + */ +export declare function format(obj: Partial): string; +/** + * Options for parsing a `Content-Type` header. + */ +export interface ParseOptions { + parameters?: boolean; +} +/** + * Parse a `Content-Type` header. + */ +export declare function parse(header: string, options?: ParseOptions): ContentType; diff --git a/node_modules/body-parser/node_modules/content-type/dist/index.js b/node_modules/body-parser/node_modules/content-type/dist/index.js new file mode 100644 index 0000000..4026f97 --- /dev/null +++ b/node_modules/body-parser/node_modules/content-type/dist/index.js @@ -0,0 +1,170 @@ +"use strict"; +/*! + * content-type + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.format = format; +exports.parse = parse; +const TEXT_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]*$/; +const TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; +/** + * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4 + */ +const QUOTE_REGEXP = /[\\"]/g; +/** + * RegExp to match type in RFC 9110 sec 8.3.1 + * + * media-type = type "/" subtype + * type = token + * subtype = token + */ +const TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; +/** + * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`. + */ +const NullObject = /* @__PURE__ */ (() => { + const C = function () { }; + C.prototype = Object.create(null); + return C; +})(); +/** + * Format an object into a `Content-Type` header. + */ +function format(obj) { + const { type, parameters } = obj; + if (!type || !TYPE_REGEXP.test(type)) { + throw new TypeError(`Invalid type: ${type}`); + } + let result = type; + if (parameters) { + for (const param of Object.keys(parameters)) { + if (!TOKEN_REGEXP.test(param)) { + throw new TypeError(`Invalid parameter name: ${param}`); + } + result += `; ${param}=${qstring(parameters[param])}`; + } + } + return result; +} +/** + * Parse a `Content-Type` header. + */ +function parse(header, options) { + const len = header.length; + let index = skipOWS(header, 0, len); + const valueStart = index; + index = skipValue(header, index, len); + const valueEnd = trailingOWS(header, valueStart, index); + const type = header.slice(valueStart, valueEnd).toLowerCase(); + const parameters = options?.parameters === false + ? new NullObject() + : parseParameters(header, index, len); + return { type, parameters }; +} +const SP = 32; // " " +const HTAB = 9; // "\t" +const SEMI = 59; // ";" +const EQ = 61; // "=" +const DQUOTE = 34; // '"' +const BSLASH = 92; // "\\" +/** + * Parses the parameters of a `Content-Type` header starting at the given index. + */ +function parseParameters(header, index, len) { + const parameters = new NullObject(); + parameter: while (index < len) { + index = skipOWS(header, index + 1 /* Skip over ; */, len); + const keyStart = index; + while (index < len) { + const code = header.charCodeAt(index); + if (code === SEMI) + continue parameter; + if (code === EQ) { + const keyEnd = trailingOWS(header, keyStart, index); + const key = header.slice(keyStart, keyEnd).toLowerCase(); + index = skipOWS(header, index + 1, len); + if (index < len && header.charCodeAt(index) === DQUOTE) { + index++; + let value = ""; + while (index < len) { + const code = header.charCodeAt(index++); + if (code === DQUOTE) { + index = skipValue(header, index, len); + if (parameters[key] === undefined) + parameters[key] = value; + break; + } + if (code === BSLASH && index < len) { + value += header[index++]; + continue; + } + value += String.fromCharCode(code); + } + continue parameter; + } + const valueStart = index; + index = skipValue(header, index, len); + if (parameters[key] === undefined) { + const valueEnd = trailingOWS(header, valueStart, index); + parameters[key] = header.slice(valueStart, valueEnd); + } + continue parameter; + } + index++; + } + } + return parameters; +} +/** + * Skip over characters until a semicolon. + */ +function skipValue(str, index, len) { + while (index < len) { + const char = str.charCodeAt(index); + if (char === SEMI) + break; + index++; + } + return index; +} +/** + * Skip optional whitespace (OWS) in an HTTP header value. + * + * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t"). + */ +function skipOWS(header, index, len) { + while (index < len) { + const char = header.charCodeAt(index); + if (char !== SP && char !== HTAB) + break; + index++; + } + return index; +} +/** + * Trim optional whitespace (OWS) from the end of a substring. + * + * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t"). + */ +function trailingOWS(header, start, end) { + while (end > start) { + const char = header.charCodeAt(end - 1); + if (char !== SP && char !== HTAB) + break; + end--; + } + return end; +} +/** + * Serialize a parameter value. + */ +function qstring(str) { + if (TOKEN_REGEXP.test(str)) + return str; + if (TEXT_REGEXP.test(str)) + return `"${str.replace(QUOTE_REGEXP, "\\$&")}"`; + throw new TypeError(`Invalid parameter value: ${str}`); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/body-parser/node_modules/content-type/dist/index.js.map b/node_modules/body-parser/node_modules/content-type/dist/index.js.map new file mode 100644 index 0000000..db5da25 --- /dev/null +++ b/node_modules/body-parser/node_modules/content-type/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * content-type\n * Copyright(c) 2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\nconst TEXT_REGEXP = /^[\\u0009\\u0020-\\u007e\\u0080-\\u00ff]*$/;\nconst TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\n\n/**\n * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4\n */\nconst QUOTE_REGEXP = /[\\\\\"]/g;\n\n/**\n * RegExp to match type in RFC 9110 sec 8.3.1\n *\n * media-type = type \"/\" subtype\n * type = token\n * subtype = token\n */\nconst TYPE_REGEXP =\n /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\n\n/**\n * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`.\n */\nconst NullObject = /* @__PURE__ */ (() => {\n const C = function () {};\n C.prototype = Object.create(null);\n return C;\n})() as unknown as { new (): any };\n\n/**\n * The content type object contains a type string and optional parameters.\n */\nexport interface ContentType {\n type: string;\n parameters: Record;\n}\n\n/**\n * Format an object into a `Content-Type` header.\n */\nexport function format(obj: Partial): string {\n const { type, parameters } = obj;\n\n if (!type || !TYPE_REGEXP.test(type)) {\n throw new TypeError(`Invalid type: ${type}`);\n }\n\n let result = type;\n\n if (parameters) {\n for (const param of Object.keys(parameters)) {\n if (!TOKEN_REGEXP.test(param)) {\n throw new TypeError(`Invalid parameter name: ${param}`);\n }\n\n result += `; ${param}=${qstring(parameters[param])}`;\n }\n }\n\n return result;\n}\n\n/**\n * Options for parsing a `Content-Type` header.\n */\nexport interface ParseOptions {\n parameters?: boolean;\n}\n\n/**\n * Parse a `Content-Type` header.\n */\nexport function parse(header: string, options?: ParseOptions): ContentType {\n const len = header.length;\n let index = skipOWS(header, 0, len);\n\n const valueStart = index;\n index = skipValue(header, index, len);\n const valueEnd = trailingOWS(header, valueStart, index);\n const type = header.slice(valueStart, valueEnd).toLowerCase();\n const parameters =\n options?.parameters === false\n ? new NullObject()\n : parseParameters(header, index, len);\n\n return { type, parameters };\n}\n\nconst SP = 32; // \" \"\nconst HTAB = 9; // \"\\t\"\nconst SEMI = 59; // \";\"\nconst EQ = 61; // \"=\"\nconst DQUOTE = 34; // '\"'\nconst BSLASH = 92; // \"\\\\\"\n\n/**\n * Parses the parameters of a `Content-Type` header starting at the given index.\n */\nfunction parseParameters(\n header: string,\n index: number,\n len: number,\n): Record {\n const parameters: Record = new NullObject();\n\n parameter: while (index < len) {\n index = skipOWS(header, index + 1 /* Skip over ; */, len);\n\n const keyStart = index;\n\n while (index < len) {\n const code = header.charCodeAt(index);\n if (code === SEMI) continue parameter;\n\n if (code === EQ) {\n const keyEnd = trailingOWS(header, keyStart, index);\n const key = header.slice(keyStart, keyEnd).toLowerCase();\n\n index = skipOWS(header, index + 1, len);\n\n if (index < len && header.charCodeAt(index) === DQUOTE) {\n index++;\n\n let value = \"\";\n while (index < len) {\n const code = header.charCodeAt(index++);\n if (code === DQUOTE) {\n index = skipValue(header, index, len);\n if (parameters[key] === undefined) parameters[key] = value;\n break;\n }\n\n if (code === BSLASH && index < len) {\n value += header[index++];\n continue;\n }\n\n value += String.fromCharCode(code);\n }\n\n continue parameter;\n }\n\n const valueStart = index;\n index = skipValue(header, index, len);\n\n if (parameters[key] === undefined) {\n const valueEnd = trailingOWS(header, valueStart, index);\n parameters[key] = header.slice(valueStart, valueEnd);\n }\n\n continue parameter;\n }\n\n index++;\n }\n }\n\n return parameters;\n}\n\n/**\n * Skip over characters until a semicolon.\n */\nfunction skipValue(str: string, index: number, len: number): number {\n while (index < len) {\n const char = str.charCodeAt(index);\n if (char === SEMI) break;\n index++;\n }\n return index;\n}\n\n/**\n * Skip optional whitespace (OWS) in an HTTP header value.\n *\n * OWS is defined in RFC 9110 sec 5.6.3 as SP (\" \") or HTAB (\"\\t\").\n */\nfunction skipOWS(header: string, index: number, len: number): number {\n while (index < len) {\n const char = header.charCodeAt(index);\n if (char !== SP && char !== HTAB) break;\n index++;\n }\n return index;\n}\n\n/**\n * Trim optional whitespace (OWS) from the end of a substring.\n *\n * OWS is defined in RFC 9110 sec 5.6.3 as SP (\" \") or HTAB (\"\\t\").\n */\nfunction trailingOWS(header: string, start: number, end: number): number {\n while (end > start) {\n const char = header.charCodeAt(end - 1);\n if (char !== SP && char !== HTAB) break;\n end--;\n }\n return end;\n}\n\n/**\n * Serialize a parameter value.\n */\nfunction qstring(str: string): string {\n if (TOKEN_REGEXP.test(str)) return str;\n if (TEXT_REGEXP.test(str)) return `\"${str.replace(QUOTE_REGEXP, \"\\\\$&\")}\"`;\n\n throw new TypeError(`Invalid parameter value: ${str}`);\n}\n"]} \ No newline at end of file diff --git a/node_modules/body-parser/node_modules/content-type/package.json b/node_modules/body-parser/node_modules/content-type/package.json new file mode 100644 index 0000000..482cbc8 --- /dev/null +++ b/node_modules/body-parser/node_modules/content-type/package.json @@ -0,0 +1,52 @@ +{ + "name": "content-type", + "version": "2.0.0", + "description": "Create and parse HTTP Content-Type header", + "keywords": [ + "content-type", + "http", + "req", + "res", + "rfc7231", + "rfc9110" + ], + "repository": "jshttp/content-type", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + }, + "license": "MIT", + "author": "Douglas Christopher Wilson ", + "type": "commonjs", + "exports": "./dist/index.js", + "main": "./dist/index.js", + "typings": "./dist/index.d.ts", + "files": [ + "dist/" + ], + "scripts": { + "bench": "vitest bench", + "build": "ts-scripts build", + "format": "ts-scripts format", + "prepare": "ts-scripts install && npm run build", + "specs": "ts-scripts specs", + "test": "ts-scripts test" + }, + "devDependencies": { + "@borderless/ts-scripts": "^0.15.0", + "@vitest/coverage-v8": "^3.0.5", + "typescript": "^5.7.3", + "vitest": "^3.2.4" + }, + "engines": { + "node": ">=18" + }, + "ts-scripts": { + "dist": [ + "dist" + ], + "project": [ + "tsconfig.build.json" + ] + } +} diff --git a/node_modules/body-parser/package.json b/node_modules/body-parser/package.json index 486878a..842cfbd 100644 --- a/node_modules/body-parser/package.json +++ b/node_modules/body-parser/package.json @@ -1,7 +1,7 @@ { "name": "body-parser", "description": "Node.js body parsing middleware", - "version": "2.2.2", + "version": "2.3.0", "contributors": [ "Douglas Christopher Wilson ", "Jonathan Ong (http://jongleberry.com)" @@ -12,28 +12,41 @@ "type": "opencollective", "url": "https://opencollective.com/express" }, + "type": "commonjs", + "exports": { + ".": "./index.js", + "./package.json": "./package.json", + "./json": "./lib/types/json.js", + "./raw": "./lib/types/raw.js", + "./text": "./lib/types/text.js", + "./urlencoded": "./lib/types/urlencoded.js", + "./lib/*": "./lib/*.js", + "./lib/*.js": "./lib/*.js", + "./lib/types/*": "./lib/types/*.js", + "./lib/types/*.js": "./lib/types/*.js" + }, "dependencies": { "bytes": "^3.1.2", - "content-type": "^1.0.5", + "content-type": "^2.0.0", "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" }, "devDependencies": { "eslint": "^8.57.1", "eslint-config-standard": "^14.1.1", - "eslint-plugin-import": "^2.31.0", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-markdown": "^3.0.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.6.0", "eslint-plugin-standard": "^4.1.0", - "mocha": "^11.1.0", + "mocha": "^11.7.6", "nyc": "^17.1.0", - "supertest": "^7.0.0" + "supertest": "^7.2.2" }, "files": [ "lib/", diff --git a/node_modules/es-object-atoms/CHANGELOG.md b/node_modules/es-object-atoms/CHANGELOG.md index fdd2abe..8efc7ba 100644 --- a/node_modules/es-object-atoms/CHANGELOG.md +++ b/node_modules/es-object-atoms/CHANGELOG.md @@ -5,33 +5,40 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [v1.1.1](https://github.com/ljharb/es-object-atoms/compare/v1.1.0...v1.1.1) - 2025-01-14 +## [v1.1.2](https://github.com/es-shims/es-object-atoms/compare/v1.1.1...v1.1.2) - 2026-05-22 ### Commits -- [types] `ToObject`: improve types [`cfe8c8a`](https://github.com/ljharb/es-object-atoms/commit/cfe8c8a105c44820cb22e26f62d12ef0ad9715c8) +- [Dev Deps] update `@ljharb/eslint-config`, `@ljharb/tsconfig`, `auto-changelog`, `eslint`, `npmignore` [`41e3d94`](https://github.com/es-shims/es-object-atoms/commit/41e3d94f6b49237fa490ec598e068f170c8b161e) +- [types] improve `isObject` type [`758edc2`](https://github.com/es-shims/es-object-atoms/commit/758edc2280fa6993a294a55957a43cee5951bf51) -## [v1.1.0](https://github.com/ljharb/es-object-atoms/compare/v1.0.1...v1.1.0) - 2025-01-14 +## [v1.1.1](https://github.com/es-shims/es-object-atoms/compare/v1.1.0...v1.1.1) - 2025-01-14 ### Commits -- [New] add `isObject` [`51e4042`](https://github.com/ljharb/es-object-atoms/commit/51e4042df722eb3165f40dc5f4bf33d0197ecb07) +- [types] `ToObject`: improve types [`cfe8c8a`](https://github.com/es-shims/es-object-atoms/commit/cfe8c8a105c44820cb22e26f62d12ef0ad9715c8) -## [v1.0.1](https://github.com/ljharb/es-object-atoms/compare/v1.0.0...v1.0.1) - 2025-01-13 +## [v1.1.0](https://github.com/es-shims/es-object-atoms/compare/v1.0.1...v1.1.0) - 2025-01-14 ### Commits -- [Dev Deps] update `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/tape`, `auto-changelog`, `tape` [`38ab9eb`](https://github.com/ljharb/es-object-atoms/commit/38ab9eb00b62c2f4668644f5e513d9b414ebd595) -- [types] improve types [`7d1beb8`](https://github.com/ljharb/es-object-atoms/commit/7d1beb887958b78b6a728a210a1c8370ab7e2aa1) -- [Tests] replace `aud` with `npm audit` [`25863ba`](https://github.com/ljharb/es-object-atoms/commit/25863baf99178f1d1ad33d1120498db28631907e) -- [Dev Deps] add missing peer dep [`c012309`](https://github.com/ljharb/es-object-atoms/commit/c0123091287e6132d6f4240496340c427433df28) +- [New] add `isObject` [`51e4042`](https://github.com/es-shims/es-object-atoms/commit/51e4042df722eb3165f40dc5f4bf33d0197ecb07) + +## [v1.0.1](https://github.com/es-shims/es-object-atoms/compare/v1.0.0...v1.0.1) - 2025-01-13 + +### Commits + +- [Dev Deps] update `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/tape`, `auto-changelog`, `tape` [`38ab9eb`](https://github.com/es-shims/es-object-atoms/commit/38ab9eb00b62c2f4668644f5e513d9b414ebd595) +- [types] improve types [`7d1beb8`](https://github.com/es-shims/es-object-atoms/commit/7d1beb887958b78b6a728a210a1c8370ab7e2aa1) +- [Tests] replace `aud` with `npm audit` [`25863ba`](https://github.com/es-shims/es-object-atoms/commit/25863baf99178f1d1ad33d1120498db28631907e) +- [Dev Deps] add missing peer dep [`c012309`](https://github.com/es-shims/es-object-atoms/commit/c0123091287e6132d6f4240496340c427433df28) ## v1.0.0 - 2024-03-16 ### Commits -- Initial implementation, tests, readme, types [`f1499db`](https://github.com/ljharb/es-object-atoms/commit/f1499db7d3e1741e64979c61d645ab3137705e82) -- Initial commit [`99eedc7`](https://github.com/ljharb/es-object-atoms/commit/99eedc7b5fde38a50a28d3c8b724706e3e4c5f6a) -- [meta] rename repo [`fc851fa`](https://github.com/ljharb/es-object-atoms/commit/fc851fa70616d2d182aaf0bd02c2ed7084dea8fa) -- npm init [`b909377`](https://github.com/ljharb/es-object-atoms/commit/b909377c50049bd0ec575562d20b0f9ebae8947f) -- Only apps should have lockfiles [`7249edd`](https://github.com/ljharb/es-object-atoms/commit/7249edd2178c1b9ddfc66ffcc6d07fdf0d28efc1) +- Initial implementation, tests, readme, types [`f1499db`](https://github.com/es-shims/es-object-atoms/commit/f1499db7d3e1741e64979c61d645ab3137705e82) +- Initial commit [`99eedc7`](https://github.com/es-shims/es-object-atoms/commit/99eedc7b5fde38a50a28d3c8b724706e3e4c5f6a) +- [meta] rename repo [`fc851fa`](https://github.com/es-shims/es-object-atoms/commit/fc851fa70616d2d182aaf0bd02c2ed7084dea8fa) +- npm init [`b909377`](https://github.com/es-shims/es-object-atoms/commit/b909377c50049bd0ec575562d20b0f9ebae8947f) +- Only apps should have lockfiles [`7249edd`](https://github.com/es-shims/es-object-atoms/commit/7249edd2178c1b9ddfc66ffcc6d07fdf0d28efc1) diff --git a/node_modules/es-object-atoms/isObject.d.ts b/node_modules/es-object-atoms/isObject.d.ts index 43bee3b..9490fbb 100644 --- a/node_modules/es-object-atoms/isObject.d.ts +++ b/node_modules/es-object-atoms/isObject.d.ts @@ -1,3 +1,3 @@ -declare function isObject(x: unknown): x is object; +declare function isObject(x: T): x is T & object & Record; export = isObject; diff --git a/node_modules/es-object-atoms/package.json b/node_modules/es-object-atoms/package.json index f4cec71..cb6bc7b 100644 --- a/node_modules/es-object-atoms/package.json +++ b/node_modules/es-object-atoms/package.json @@ -1,6 +1,6 @@ { "name": "es-object-atoms", - "version": "1.1.1", + "version": "1.1.2", "description": "ES Object-related atoms: Object, ToObject, RequireObjectCoercible", "main": "index.js", "exports": { @@ -46,16 +46,15 @@ "es-errors": "^1.3.0" }, "devDependencies": { - "@ljharb/eslint-config": "^21.1.1", - "@ljharb/tsconfig": "^0.2.3", + "@ljharb/eslint-config": "^22.2.3", + "@ljharb/tsconfig": "^0.3.2", "@types/tape": "^5.8.1", - "auto-changelog": "^2.5.0", + "auto-changelog": "^2.5.1", "eclint": "^2.8.1", - "encoding": "^0.1.13", - "eslint": "^8.8.0", + "eslint": "^8.57.1", "evalmd": "^0.0.19", "in-publish": "^2.0.1", - "npmignore": "^0.3.1", + "npmignore": "^0.3.5", "nyc": "^10.3.2", "safe-publish-latest": "^2.0.0", "tape": "^5.9.0", diff --git a/node_modules/es-object-atoms/tsconfig.json b/node_modules/es-object-atoms/tsconfig.json index 1f73cb7..c1ef790 100644 --- a/node_modules/es-object-atoms/tsconfig.json +++ b/node_modules/es-object-atoms/tsconfig.json @@ -2,5 +2,6 @@ "extends": "@ljharb/tsconfig", "compilerOptions": { "target": "es5", + "ignoreDeprecations": "6.0", }, } diff --git a/node_modules/hasown/.eslintrc b/node_modules/hasown/.eslintrc deleted file mode 100644 index 3b5d9e9..0000000 --- a/node_modules/hasown/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "root": true, - - "extends": "@ljharb", -} diff --git a/node_modules/hasown/CHANGELOG.md b/node_modules/hasown/CHANGELOG.md index 2b0a980..90a43dc 100644 --- a/node_modules/hasown/CHANGELOG.md +++ b/node_modules/hasown/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.0.4](https://github.com/inspect-js/hasOwn/compare/v2.0.3...v2.0.4) - 2026-05-28 + +### Commits + +- [types] drop the dead key-narrowing overload [`fdab00e`](https://github.com/inspect-js/hasOwn/commit/fdab00e2703e65411424e19bf86a7e72a8f10da9) +- [Dev Deps] update `@ljharb/eslint-config`, `auto-changelog`, `eslint` [`91f6247`](https://github.com/inspect-js/hasOwn/commit/91f624768dd0f7db0d019b89d4d86bd66e20ec30) + +## [v2.0.3](https://github.com/inspect-js/hasOwn/compare/v2.0.2...v2.0.3) - 2026-04-17 + +### Commits + +- [actions] update workflows [`fb837b8`](https://github.com/inspect-js/hasOwn/commit/fb837b849bcdb8416fdc8fd344edfacd5574696c) +- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/tape`, `auto-changelog`, `eslint`, `mock-property`, `npmignore`, `tape` [`f4b279b`](https://github.com/inspect-js/hasOwn/commit/f4b279bd682be34b3f0ede2a58d4e8acb58d6d47) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`; migrate to flat config [`7e415ce`](https://github.com/inspect-js/hasOwn/commit/7e415cee55ebf43b3c34d7fd86db73a9928b05f7) +- [Dev Deps] update `eslint` [`ef313da`](https://github.com/inspect-js/hasOwn/commit/ef313da342d33b60e23e738b9f5a86f6065f39ef) +- [meta] use `npm audit` instead of `aud` [`d5c6d4d`](https://github.com/inspect-js/hasOwn/commit/d5c6d4d7a19c6ca4f14ac173b30d8bf25abcabee) +- [types] add overload that narrows the key [`cc03a09`](https://github.com/inspect-js/hasOwn/commit/cc03a097e9402fb8b86d413050e67f790dd6c8c5) + ## [v2.0.2](https://github.com/inspect-js/hasOwn/compare/v2.0.1...v2.0.2) - 2024-03-10 ### Commits diff --git a/node_modules/hasown/eslint.config.mjs b/node_modules/hasown/eslint.config.mjs new file mode 100644 index 0000000..3d634a0 --- /dev/null +++ b/node_modules/hasown/eslint.config.mjs @@ -0,0 +1,6 @@ +import ljharbConfig from '@ljharb/eslint-config/flat'; + +export default [ + ...ljharbConfig, + { rules: { 'no-extra-parens': 'off' } }, +]; diff --git a/node_modules/hasown/package.json b/node_modules/hasown/package.json index 8502e13..fb86cc3 100644 --- a/node_modules/hasown/package.json +++ b/node_modules/hasown/package.json @@ -1,6 +1,6 @@ { "name": "hasown", - "version": "2.0.2", + "version": "2.0.4", "description": "A robust, ES3 compatible, \"has own property\" predicate.", "main": "index.js", "exports": { @@ -14,14 +14,14 @@ "prepublish": "not-in-publish || npm run prepublishOnly", "prepublishOnly": "safe-publish-latest", "prelint": "evalmd README.md", - "lint": "eslint --ext=js,mjs .", + "lint": "eslint .", "postlint": "npm run tsc", "pretest": "npm run lint", "tsc": "tsc -p .", "posttsc": "attw -P", "tests-only": "nyc tape 'test/**/*.js'", "test": "npm run tests-only", - "posttest": "aud --production", + "posttest": "npx npm@\">= 10.2\" audit --production", "version": "auto-changelog && git add CHANGELOG.md", "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" }, @@ -51,22 +51,21 @@ "function-bind": "^1.1.2" }, "devDependencies": { - "@arethetypeswrong/cli": "^0.15.1", - "@ljharb/eslint-config": "^21.1.0", - "@ljharb/tsconfig": "^0.2.0", + "@arethetypeswrong/cli": "^0.18.2", + "@ljharb/eslint-config": "^22.2.3", + "@ljharb/tsconfig": "^0.3.2", "@types/function-bind": "^1.1.10", - "@types/mock-property": "^1.0.2", - "@types/tape": "^5.6.4", - "aud": "^2.0.4", - "auto-changelog": "^2.4.0", - "eslint": "=8.8.0", + "@types/tape": "^5.8.1", + "auto-changelog": "^2.5.1", + "eslint": "^10.4.0", "evalmd": "^0.0.19", "in-publish": "^2.0.1", - "mock-property": "^1.0.3", - "npmignore": "^0.3.1", + "jiti": "^0.0.0", + "mock-property": "^1.1.0", + "npmignore": "^0.3.5", "nyc": "^10.3.2", "safe-publish-latest": "^2.0.0", - "tape": "^5.7.5", + "tape": "^5.9.0", "typescript": "next" }, "engines": { diff --git a/node_modules/path-to-regexp/Readme.md b/node_modules/path-to-regexp/Readme.md index f5df40a..f33e392 100644 --- a/node_modules/path-to-regexp/Readme.md +++ b/node_modules/path-to-regexp/Readme.md @@ -153,7 +153,7 @@ The `parse` function accepts a string and returns `TokenData`, which can be used `TokenData` has two properties: -- **tokens** A sequence of tokens, currently of types `text`, `parameter`, `wildcard`, or `group`. +- **tokens** A sequence of tokens, currently of types `text`, `param`, `wildcard`, or `group`. - **originalPath** The original path used with `parse`, shown in error messages to assist debugging. ### Custom path @@ -165,13 +165,13 @@ import { match } from "path-to-regexp"; const tokens = [ { type: "text", value: "/" }, - { type: "parameter", name: "foo" }, + { type: "param", name: "foo" }, ]; const originalPath = "/[foo]"; // To help debug error messages. const path = { tokens, originalPath }; const fn = match(path); -fn("/test"); //=> { path: '/test', index: 0, params: { foo: 'test' } } +fn("/test"); //=> { path: '/test', params: { foo: 'test' } } ``` ## Errors diff --git a/node_modules/path-to-regexp/dist/index.d.ts b/node_modules/path-to-regexp/dist/index.d.ts index b59dff0..c173a44 100644 --- a/node_modules/path-to-regexp/dist/index.d.ts +++ b/node_modules/path-to-regexp/dist/index.d.ts @@ -134,6 +134,9 @@ export type Path = string | TokenData; * Transform a path into a match function. */ export declare function match

(path: Path | Path[], options?: MatchOptions & ParseOptions): MatchFunction

; +/** + * Transform a path into a regular expression and capture keys. + */ export declare function pathToRegexp(path: Path | Path[], options?: PathToRegexpOptions & ParseOptions): { regexp: RegExp; keys: Keys; diff --git a/node_modules/path-to-regexp/dist/index.js b/node_modules/path-to-regexp/dist/index.js index 9331ae0..97f36e8 100644 --- a/node_modules/path-to-regexp/dist/index.js +++ b/node_modules/path-to-regexp/dist/index.js @@ -10,19 +10,7 @@ const DEFAULT_DELIMITER = "/"; const NOOP_VALUE = (value) => value; const ID_START = /^[$_\p{ID_Start}]$/u; const ID_CONTINUE = /^[$\u200c\u200d\p{ID_Continue}]$/u; -const SIMPLE_TOKENS = { - // Groups. - "{": "{", - "}": "}", - // Reserved. - "(": "(", - ")": ")", - "[": "[", - "]": "]", - "+": "+", - "?": "?", - "!": "!", -}; +const ID = /^[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*$/u; /** * Escape text for stringify to path. */ @@ -65,96 +53,91 @@ exports.PathError = PathError; function parse(str, options = {}) { const { encodePath = NOOP_VALUE } = options; const chars = [...str]; - const tokens = []; let index = 0; - let pos = 0; - function name() { - let value = ""; - if (ID_START.test(chars[index])) { - do { - value += chars[index++]; - } while (ID_CONTINUE.test(chars[index])); - } - else if (chars[index] === '"') { - let quoteStart = index; - while (index++ < chars.length) { - if (chars[index] === '"') { - index++; - quoteStart = 0; - break; - } - // Increment over escape characters. - if (chars[index] === "\\") - index++; - value += chars[index]; - } - if (quoteStart) { - throw new PathError(`Unterminated quote at index ${quoteStart}`, str); - } - } - if (!value) { - throw new PathError(`Missing parameter name at index ${index}`, str); - } - return value; - } - while (index < chars.length) { - const value = chars[index]; - const type = SIMPLE_TOKENS[value]; - if (type) { - tokens.push({ type, index: index++, value }); - } - else if (value === "\\") { - tokens.push({ type: "escape", index: index++, value: chars[index++] }); - } - else if (value === ":") { - tokens.push({ type: "param", index: index++, value: name() }); - } - else if (value === "*") { - tokens.push({ type: "wildcard", index: index++, value: name() }); - } - else { - tokens.push({ type: "char", index: index++, value }); - } - } - tokens.push({ type: "end", index, value: "" }); - function consumeUntil(endType) { + function consumeUntil(end) { const output = []; - while (true) { - const token = tokens[pos++]; - if (token.type === endType) - break; - if (token.type === "char" || token.type === "escape") { - let path = token.value; - let cur = tokens[pos]; - while (cur.type === "char" || cur.type === "escape") { - path += cur.value; - cur = tokens[++pos]; + let path = ""; + function writePath() { + if (!path) + return; + output.push({ + type: "text", + value: encodePath(path), + }); + path = ""; + } + while (index < chars.length) { + const value = chars[index++]; + if (value === end) { + writePath(); + return output; + } + if (value === "\\") { + if (index === chars.length) { + throw new PathError(`Unexpected end after \\ at index ${index}`, str); } - output.push({ - type: "text", - value: encodePath(path), - }); + path += chars[index++]; continue; } - if (token.type === "param" || token.type === "wildcard") { - output.push({ - type: token.type, - name: token.value, - }); + if (value === ":" || value === "*") { + const type = value === ":" ? "param" : "wildcard"; + let name = ""; + if (ID_START.test(chars[index])) { + do { + name += chars[index++]; + } while (ID_CONTINUE.test(chars[index])); + } + else if (chars[index] === '"') { + let quoteStart = index; + while (index < chars.length) { + if (chars[++index] === '"') { + index++; + quoteStart = 0; + break; + } + // Increment over escape characters. + if (chars[index] === "\\") + index++; + name += chars[index]; + } + if (quoteStart) { + throw new PathError(`Unterminated quote at index ${quoteStart}`, str); + } + } + if (!name) { + throw new PathError(`Missing parameter name at index ${index}`, str); + } + writePath(); + output.push({ type, name }); continue; } - if (token.type === "{") { + if (value === "{") { + writePath(); output.push({ type: "group", tokens: consumeUntil("}"), }); continue; } - throw new PathError(`Unexpected ${token.type} at index ${token.index}, expected ${endType}`, str); + if (value === "}" || + value === "(" || + value === ")" || + value === "[" || + value === "]" || + value === "+" || + value === "?" || + value === "!") { + throw new PathError(`Unexpected ${value} at index ${index - 1}`, str); + } + path += value; } + if (end) { + throw new PathError(`Unexpected end at index ${index}, expected ${end}`, str); + } + writePath(); return output; } - return new TokenData(consumeUntil("end"), str); + return new TokenData(consumeUntil(""), str); } /** * Compile a string to a template function for the path. @@ -164,7 +147,8 @@ function compile(path, options = {}) { const data = typeof path === "object" ? path : parse(path, options); const fn = tokensToFunction(data.tokens, delimiter, encode); return function path(params = {}) { - const [path, ...missing] = fn(params); + const missing = []; + const path = fn(params, missing); if (missing.length) { throw new TypeError(`Missing parameters: ${missing.join(", ")}`); } @@ -173,12 +157,10 @@ function compile(path, options = {}) { } function tokensToFunction(tokens, delimiter, encode) { const encoders = tokens.map((token) => tokenToFunction(token, delimiter, encode)); - return (data) => { - const result = [""]; + return (data, missing) => { + let result = ""; for (const encoder of encoders) { - const [value, ...extras] = encoder(data); - result[0] += value; - result.push(...extras); + result += encoder(data, missing); } return result; }; @@ -188,45 +170,51 @@ function tokensToFunction(tokens, delimiter, encode) { */ function tokenToFunction(token, delimiter, encode) { if (token.type === "text") - return () => [token.value]; + return () => token.value; if (token.type === "group") { const fn = tokensToFunction(token.tokens, delimiter, encode); - return (data) => { - const [value, ...missing] = fn(data); - if (!missing.length) - return [value]; - return [""]; + return (data, missing) => { + const len = missing.length; + const value = fn(data, missing); + if (missing.length === len) + return value; + missing.length = len; // Reset optional group. + return ""; }; } const encodeValue = encode || NOOP_VALUE; if (token.type === "wildcard" && encode !== false) { - return (data) => { + return (data, missing) => { const value = data[token.name]; - if (value == null) - return ["", token.name]; + if (value == null) { + missing.push(token.name); + return ""; + } if (!Array.isArray(value) || value.length === 0) { throw new TypeError(`Expected "${token.name}" to be a non-empty array`); } - return [ - value - .map((value, index) => { - if (typeof value !== "string") { - throw new TypeError(`Expected "${token.name}/${index}" to be a string`); - } - return encodeValue(value); - }) - .join(delimiter), - ]; + let result = ""; + for (let i = 0; i < value.length; i++) { + if (typeof value[i] !== "string") { + throw new TypeError(`Expected "${token.name}/${i}" to be a string`); + } + if (i > 0) + result += delimiter; + result += encodeValue(value[i]); + } + return result; }; } - return (data) => { + return (data, missing) => { const value = data[token.name]; - if (value == null) - return ["", token.name]; + if (value == null) { + missing.push(token.name); + return ""; + } if (typeof value !== "string") { throw new TypeError(`Expected "${token.name}" to be a string`); } - return [encodeValue(value)]; + return encodeValue(value); }; } /** @@ -258,54 +246,53 @@ function match(path, options = {}) { return { path, params }; }; } +/** + * Transform a path into a regular expression and capture keys. + */ function pathToRegexp(path, options = {}) { const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true, } = options; const keys = []; - const flags = sensitive ? "" : "i"; - const sources = []; - for (const input of pathsToArray(path, [])) { - const data = typeof input === "object" ? input : parse(input, options); - for (const tokens of flatten(data.tokens, 0, [])) { - sources.push(toRegExpSource(tokens, delimiter, keys, data.originalPath)); + let source = ""; + let combinations = 0; + function process(path) { + if (Array.isArray(path)) { + for (const p of path) + process(p); + return; } + const data = typeof path === "object" ? path : parse(path, options); + flatten(data.tokens, 0, [], (tokens) => { + if (combinations >= 256) { + throw new PathError("Too many path combinations", data.originalPath); + } + if (combinations > 0) + source += "|"; + source += toRegExpSource(tokens, delimiter, keys, data.originalPath); + combinations++; + }); } - let pattern = `^(?:${sources.join("|")})`; + process(path); + let pattern = `^(?:${source})`; if (trailing) - pattern += `(?:${escape(delimiter)}$)?`; - pattern += end ? "$" : `(?=${escape(delimiter)}|$)`; - const regexp = new RegExp(pattern, flags); - return { regexp, keys }; -} -/** - * Convert a path or array of paths into a flat array. - */ -function pathsToArray(paths, init) { - if (Array.isArray(paths)) { - for (const p of paths) - pathsToArray(p, init); - } - else { - init.push(paths); - } - return init; + pattern += "(?:" + escape(delimiter) + "$)?"; + pattern += end ? "$" : "(?=" + escape(delimiter) + "|$)"; + return { regexp: new RegExp(pattern, sensitive ? "" : "i"), keys }; } /** * Generate a flat list of sequence tokens from the given tokens. */ -function* flatten(tokens, index, init) { - if (index === tokens.length) { - return yield init; - } - const token = tokens[index]; - if (token.type === "group") { - for (const seq of flatten(token.tokens, 0, init.slice())) { - yield* flatten(tokens, index + 1, seq); +function flatten(tokens, index, result, callback) { + while (index < tokens.length) { + const token = tokens[index++]; + if (token.type === "group") { + const len = result.length; + flatten(token.tokens, 0, result, (seq) => flatten(tokens, index, seq, callback)); + result.length = len; + continue; } + result.push(token); } - else { - init.push(token); - } - yield* flatten(tokens, index + 1, init); + callback(result); } /** * Transform a flat sequence of tokens into a regular expression. @@ -313,72 +300,111 @@ function* flatten(tokens, index, init) { function toRegExpSource(tokens, delimiter, keys, originalPath) { let result = ""; let backtrack = ""; - let isSafeSegmentParam = true; - for (const token of tokens) { + let wildcardBacktrack = ""; + let prevCaptureType = 0; + let hasSegmentCapture = 0; + let index = 0; + function hasInSegment(index, type) { + while (index < tokens.length) { + const token = tokens[index++]; + if (token.type === type) + return true; + if (token.type === "text") { + if (token.value.includes(delimiter)) + break; + } + } + return false; + } + function peekText(index) { + let result = ""; + while (index < tokens.length) { + const token = tokens[index++]; + if (token.type !== "text") + break; + result += token.value; + } + return result; + } + while (index < tokens.length) { + const token = tokens[index++]; if (token.type === "text") { result += escape(token.value); backtrack += token.value; - isSafeSegmentParam || (isSafeSegmentParam = token.value.includes(delimiter)); + if (prevCaptureType === 2) + wildcardBacktrack += token.value; + if (token.value.includes(delimiter)) + hasSegmentCapture = 0; continue; } if (token.type === "param" || token.type === "wildcard") { - if (!isSafeSegmentParam && !backtrack) { + if (prevCaptureType && !backtrack) { throw new PathError(`Missing text before "${token.name}" ${token.type}`, originalPath); } if (token.type === "param") { - result += `(${negate(delimiter, isSafeSegmentParam ? "" : backtrack)}+)`; + result += + hasSegmentCapture & 2 // Seen wildcard in segment. + ? `(${negate(delimiter, backtrack)}+)` + : hasInSegment(index, "wildcard") // See wildcard later in segment. + ? `(${negate(delimiter, peekText(index))}+)` + : hasSegmentCapture & 1 // Seen parameter in segment. + ? `(${negate(delimiter, backtrack)}+|${escape(backtrack)})` + : `(${negate(delimiter, "")}+)`; + hasSegmentCapture |= prevCaptureType = 1; } else { - result += `([\\s\\S]+)`; + result += + hasSegmentCapture & 2 // Seen wildcard in segment. + ? `(${negate(backtrack, "")}+)` + : wildcardBacktrack // No capture in segment, seen wildcard in path. + ? `(${negate(wildcardBacktrack, "")}+|${negate(delimiter, "")}+)` + : `([^]+)`; + wildcardBacktrack = ""; + hasSegmentCapture |= prevCaptureType = 2; } keys.push(token); backtrack = ""; - isSafeSegmentParam = false; continue; } + throw new TypeError(`Unknown token type: ${token.type}`); } return result; } /** - * Block backtracking on previous text and ignore delimiter string. + * Block backtracking on previous text/delimiter. */ -function negate(delimiter, backtrack) { - if (backtrack.length < 2) { - if (delimiter.length < 2) - return `[^${escape(delimiter + backtrack)}]`; - return `(?:(?!${escape(delimiter)})[^${escape(backtrack)}])`; - } - if (delimiter.length < 2) { - return `(?:(?!${escape(backtrack)})[^${escape(delimiter)}])`; - } - return `(?:(?!${escape(backtrack)}|${escape(delimiter)})[\\s\\S])`; +function negate(a, b) { + if (b.length > a.length) + return negate(b, a); // Longest string first. + if (a === b) + b = ""; // Cleaner regex strings, no duplication. + if (b.length > 1) + return `(?:(?!${escape(a)}|${escape(b)})[^])`; + if (a.length > 1) + return `(?:(?!${escape(a)})[^${escape(b)}])`; + return `[^${escape(a + b)}]`; } /** * Stringify an array of tokens into a path string. */ -function stringifyTokens(tokens) { +function stringifyTokens(tokens, index) { let value = ""; - let i = 0; - function name(value) { - const isSafe = isNameSafe(value) && isNextNameSafe(tokens[i]); - return isSafe ? value : JSON.stringify(value); - } - while (i < tokens.length) { - const token = tokens[i++]; + while (index < tokens.length) { + const token = tokens[index++]; if (token.type === "text") { value += escapeText(token.value); continue; } if (token.type === "group") { - value += `{${stringifyTokens(token.tokens)}}`; + value += "{" + stringifyTokens(token.tokens, 0) + "}"; continue; } if (token.type === "param") { - value += `:${name(token.name)}`; + value += ":" + stringifyName(token.name, tokens[index]); continue; } if (token.type === "wildcard") { - value += `*${name(token.name)}`; + value += "*" + stringifyName(token.name, tokens[index]); continue; } throw new TypeError(`Unknown token type: ${token.type}`); @@ -389,21 +415,17 @@ function stringifyTokens(tokens) { * Stringify token data into a path string. */ function stringify(data) { - return stringifyTokens(data.tokens); + return stringifyTokens(data.tokens, 0); } /** - * Validate the parameter name contains valid ID characters. + * Stringify a parameter name, escaping when it cannot be emitted directly. */ -function isNameSafe(name) { - const [first, ...rest] = name; - return ID_START.test(first) && rest.every((char) => ID_CONTINUE.test(char)); -} -/** - * Validate the next token does not interfere with the current param name. - */ -function isNextNameSafe(token) { - if (token && token.type === "text") - return !ID_CONTINUE.test(token.value[0]); - return true; +function stringifyName(name, next) { + if (!ID.test(name)) + return JSON.stringify(name); + if ((next === null || next === void 0 ? void 0 : next.type) === "text" && ID_CONTINUE.test(next.value[0])) { + return JSON.stringify(name); + } + return name; } //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/path-to-regexp/dist/index.js.map b/node_modules/path-to-regexp/dist/index.js.map index ec14c73..0c65186 100644 --- a/node_modules/path-to-regexp/dist/index.js.map +++ b/node_modules/path-to-regexp/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AA4LA,sBA8GC;AAKD,0BAgBC;AAgHD,sBA+BC;AAED,oCA2BC;AAmJD,8BAEC;AAhoBD,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC;AAC5C,MAAM,QAAQ,GAAG,qBAAqB,CAAC;AACvC,MAAM,WAAW,GAAG,mCAAmC,CAAC;AAkFxD,MAAM,aAAa,GAA8B;IAC/C,UAAU;IACV,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,YAAY;IACZ,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;CACT,CAAC;AAEF;;GAEG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,SAAS,MAAM,CAAC,GAAW;IACzB,OAAO,GAAG,CAAC,OAAO,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAiDD;;GAEG;AACH,MAAa,SAAS;IACpB,YACkB,MAAe,EACf,YAAqB;QADrB,WAAM,GAAN,MAAM,CAAS;QACf,iBAAY,GAAZ,YAAY,CAAS;IACpC,CAAC;CACL;AALD,8BAKC;AAED;;GAEG;AACH,MAAa,SAAU,SAAQ,SAAS;IACtC,YACE,OAAe,EACC,YAAgC;QAEhD,IAAI,IAAI,GAAG,OAAO,CAAC;QACnB,IAAI,YAAY;YAAE,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC9C,IAAI,IAAI,oDAAoD,CAAC;QAC7D,KAAK,CAAC,IAAI,CAAC,CAAC;QALI,iBAAY,GAAZ,YAAY,CAAoB;IAMlD,CAAC;CACF;AAVD,8BAUC;AAED;;GAEG;AACH,SAAgB,KAAK,CAAC,GAAW,EAAE,UAAwB,EAAE;IAC3D,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IACvB,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,SAAS,IAAI;QACX,IAAI,KAAK,GAAG,EAAE,CAAC;QAEf,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAChC,GAAG,CAAC;gBACF,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1B,CAAC,QAAQ,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;QAC3C,CAAC;aAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;YAChC,IAAI,UAAU,GAAG,KAAK,CAAC;YAEvB,OAAO,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC9B,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;oBACzB,KAAK,EAAE,CAAC;oBACR,UAAU,GAAG,CAAC,CAAC;oBACf,MAAM;gBACR,CAAC;gBAED,oCAAoC;gBACpC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI;oBAAE,KAAK,EAAE,CAAC;gBAEnC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;YACxB,CAAC;YAED,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,IAAI,SAAS,CAAC,+BAA+B,UAAU,EAAE,EAAE,GAAG,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,SAAS,CAAC,mCAAmC,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAElC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/C,CAAC;aAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACzE,CAAC;aAAM,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAChE,CAAC;aAAM,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IAE/C,SAAS,YAAY,CAAC,OAAkB;QACtC,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;gBAAE,MAAM;YAElC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,IAAI,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;gBACvB,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;gBAEtB,OAAO,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACpD,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC;oBAClB,GAAG,GAAG,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;gBACtB,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC;iBACxB,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACxD,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,IAAI,EAAE,KAAK,CAAC,KAAK;iBAClB,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC;iBAC1B,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,MAAM,IAAI,SAAS,CACjB,cAAc,KAAK,CAAC,IAAI,aAAa,KAAK,CAAC,KAAK,cAAc,OAAO,EAAE,EACvE,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,SAAgB,OAAO,CACrB,IAAU,EACV,UAAyC,EAAE;IAE3C,MAAM,EAAE,MAAM,GAAG,kBAAkB,EAAE,SAAS,GAAG,iBAAiB,EAAE,GAClE,OAAO,CAAC;IACV,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpE,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAE5D,OAAO,SAAS,IAAI,CAAC,SAAY,EAAO;QACtC,MAAM,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,SAAS,CAAC,uBAAuB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAKD,SAAS,gBAAgB,CACvB,MAAe,EACf,SAAiB,EACjB,MAAsB;IAEtB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACpC,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAC1C,CAAC;IAEF,OAAO,CAAC,IAAe,EAAE,EAAE;QACzB,MAAM,MAAM,GAAa,CAAC,EAAE,CAAC,CAAC;QAE9B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACzB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CACtB,KAAY,EACZ,SAAiB,EACjB,MAAsB;IAEtB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEtD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAE7D,OAAO,CAAC,IAAI,EAAE,EAAE;YACd,MAAM,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACpC,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,IAAI,UAAU,CAAC;IAEzC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QAClD,OAAO,CAAC,IAAI,EAAE,EAAE;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,KAAK,IAAI,IAAI;gBAAE,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAE3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChD,MAAM,IAAI,SAAS,CAAC,aAAa,KAAK,CAAC,IAAI,2BAA2B,CAAC,CAAC;YAC1E,CAAC;YAED,OAAO;gBACL,KAAK;qBACF,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;oBACpB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;wBAC9B,MAAM,IAAI,SAAS,CACjB,aAAa,KAAK,CAAC,IAAI,IAAI,KAAK,kBAAkB,CACnD,CAAC;oBACJ,CAAC;oBAED,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;gBAC5B,CAAC,CAAC;qBACD,IAAI,CAAC,SAAS,CAAC;aACnB,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE3C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,SAAS,CAAC,aAAa,KAAK,CAAC,IAAI,kBAAkB,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC;AACJ,CAAC;AAyBD;;GAEG;AACH,SAAgB,KAAK,CACnB,IAAmB,EACnB,UAAuC,EAAE;IAEzC,MAAM,EAAE,MAAM,GAAG,kBAAkB,EAAE,SAAS,GAAG,iBAAiB,EAAE,GAClE,OAAO,CAAC;IACV,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAChC,IAAI,MAAM,KAAK,KAAK;YAAE,OAAO,UAAU,CAAC;QACxC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,MAAM,CAAC;QACxC,OAAO,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,OAAO,SAAS,KAAK,CAAC,KAAa;QACjC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAErB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAE,SAAS;YAEjC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxB,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC;AAED,SAAgB,YAAY,CAC1B,IAAmB,EACnB,UAA8C,EAAE;IAEhD,MAAM,EACJ,SAAS,GAAG,iBAAiB,EAC7B,GAAG,GAAG,IAAI,EACV,SAAS,GAAG,KAAK,EACjB,QAAQ,GAAG,IAAI,GAChB,GAAG,OAAO,CAAC;IACZ,MAAM,IAAI,GAAS,EAAE,CAAC;IACtB,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACnC,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACvE,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,IAAI,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC1C,IAAI,QAAQ;QAAE,OAAO,IAAI,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;IACtD,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;IAEpD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,KAAoB,EAAE,IAAY;IACtD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,KAAK;YAAE,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAOD;;GAEG;AACH,QAAQ,CAAC,CAAC,OAAO,CACf,MAAe,EACf,KAAa,EACb,IAAiB;IAEjB,IAAI,KAAK,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QAC5B,OAAO,MAAM,IAAI,CAAC;IACpB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE5B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;YACzD,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,MAAmB,EACnB,SAAiB,EACjB,IAAU,EACV,YAAgC;IAEhC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,kBAAkB,GAAG,IAAI,CAAC;IAE9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC9B,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC;YACzB,kBAAkB,KAAlB,kBAAkB,GAAK,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAC;YACvD,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACxD,IAAI,CAAC,kBAAkB,IAAI,CAAC,SAAS,EAAE,CAAC;gBACtC,MAAM,IAAI,SAAS,CACjB,wBAAwB,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,EACnD,YAAY,CACb,CAAC;YACJ,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC3B,MAAM,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;YAC3E,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,aAAa,CAAC;YAC1B,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjB,SAAS,GAAG,EAAE,CAAC;YACf,kBAAkB,GAAG,KAAK,CAAC;YAC3B,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,MAAM,CAAC,SAAiB,EAAE,SAAiB;IAClD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC;QACvE,OAAO,SAAS,MAAM,CAAC,SAAS,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;IAC/D,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,SAAS,MAAM,CAAC,SAAS,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;IAC/D,CAAC;IACD,OAAO,SAAS,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,MAAe;IACtC,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,SAAS,IAAI,CAAC,KAAa;QACzB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;QAE1B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,KAAK,IAAI,IAAI,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;YAC9C,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9B,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,SAAS;QACX,CAAC;QAED,MAAM,IAAI,SAAS,CAAC,uBAAwB,KAAa,CAAC,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,IAAe;IACvC,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9B,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,KAAwB;IAC9C,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["const DEFAULT_DELIMITER = \"/\";\nconst NOOP_VALUE = (value: string) => value;\nconst ID_START = /^[$_\\p{ID_Start}]$/u;\nconst ID_CONTINUE = /^[$\\u200c\\u200d\\p{ID_Continue}]$/u;\n\n/**\n * Encode a string into another string.\n */\nexport type Encode = (value: string) => string;\n\n/**\n * Decode a string into another string.\n */\nexport type Decode = (value: string) => string;\n\nexport interface ParseOptions {\n /**\n * A function for encoding input strings.\n */\n encodePath?: Encode;\n}\n\nexport interface PathToRegexpOptions {\n /**\n * Matches the path completely without trailing characters. (default: `true`)\n */\n end?: boolean;\n /**\n * Allows optional trailing delimiter to match. (default: `true`)\n */\n trailing?: boolean;\n /**\n * Match will be case sensitive. (default: `false`)\n */\n sensitive?: boolean;\n /**\n * The default delimiter for segments. (default: `'/'`)\n */\n delimiter?: string;\n}\n\nexport interface MatchOptions extends PathToRegexpOptions {\n /**\n * Function for decoding strings for params, or `false` to disable entirely. (default: `decodeURIComponent`)\n */\n decode?: Decode | false;\n}\n\nexport interface CompileOptions {\n /**\n * Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)\n */\n encode?: Encode | false;\n /**\n * The default delimiter for segments. (default: `'/'`)\n */\n delimiter?: string;\n}\n\ntype TokenType =\n | \"{\"\n | \"}\"\n | \"wildcard\"\n | \"param\"\n | \"char\"\n | \"escape\"\n | \"end\"\n // Reserved for use or ambiguous due to past use.\n | \"(\"\n | \")\"\n | \"[\"\n | \"]\"\n | \"+\"\n | \"?\"\n | \"!\";\n\n/**\n * Tokenizer results.\n */\ninterface LexToken {\n type: TokenType;\n index: number;\n value: string;\n}\n\nconst SIMPLE_TOKENS: Record = {\n // Groups.\n \"{\": \"{\",\n \"}\": \"}\",\n // Reserved.\n \"(\": \"(\",\n \")\": \")\",\n \"[\": \"[\",\n \"]\": \"]\",\n \"+\": \"+\",\n \"?\": \"?\",\n \"!\": \"!\",\n};\n\n/**\n * Escape text for stringify to path.\n */\nfunction escapeText(str: string) {\n return str.replace(/[{}()\\[\\]+?!:*\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Escape a regular expression string.\n */\nfunction escape(str: string) {\n return str.replace(/[.+*?^${}()[\\]|/\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Plain text.\n */\nexport interface Text {\n type: \"text\";\n value: string;\n}\n\n/**\n * A parameter designed to match arbitrary text within a segment.\n */\nexport interface Parameter {\n type: \"param\";\n name: string;\n}\n\n/**\n * A wildcard parameter designed to match multiple segments.\n */\nexport interface Wildcard {\n type: \"wildcard\";\n name: string;\n}\n\n/**\n * A set of possible tokens to expand when matching.\n */\nexport interface Group {\n type: \"group\";\n tokens: Token[];\n}\n\n/**\n * A token that corresponds with a regexp capture.\n */\nexport type Key = Parameter | Wildcard;\n\n/**\n * A sequence of `path-to-regexp` keys that match capturing groups.\n */\nexport type Keys = Array;\n\n/**\n * A sequence of path match characters.\n */\nexport type Token = Text | Parameter | Wildcard | Group;\n\n/**\n * Tokenized path instance.\n */\nexport class TokenData {\n constructor(\n public readonly tokens: Token[],\n public readonly originalPath?: string,\n ) {}\n}\n\n/**\n * ParseError is thrown when there is an error processing the path.\n */\nexport class PathError extends TypeError {\n constructor(\n message: string,\n public readonly originalPath: string | undefined,\n ) {\n let text = message;\n if (originalPath) text += `: ${originalPath}`;\n text += `; visit https://git.new/pathToRegexpError for info`;\n super(text);\n }\n}\n\n/**\n * Parse a string for the raw tokens.\n */\nexport function parse(str: string, options: ParseOptions = {}): TokenData {\n const { encodePath = NOOP_VALUE } = options;\n const chars = [...str];\n const tokens: Array = [];\n let index = 0;\n let pos = 0;\n\n function name() {\n let value = \"\";\n\n if (ID_START.test(chars[index])) {\n do {\n value += chars[index++];\n } while (ID_CONTINUE.test(chars[index]));\n } else if (chars[index] === '\"') {\n let quoteStart = index;\n\n while (index++ < chars.length) {\n if (chars[index] === '\"') {\n index++;\n quoteStart = 0;\n break;\n }\n\n // Increment over escape characters.\n if (chars[index] === \"\\\\\") index++;\n\n value += chars[index];\n }\n\n if (quoteStart) {\n throw new PathError(`Unterminated quote at index ${quoteStart}`, str);\n }\n }\n\n if (!value) {\n throw new PathError(`Missing parameter name at index ${index}`, str);\n }\n\n return value;\n }\n\n while (index < chars.length) {\n const value = chars[index];\n const type = SIMPLE_TOKENS[value];\n\n if (type) {\n tokens.push({ type, index: index++, value });\n } else if (value === \"\\\\\") {\n tokens.push({ type: \"escape\", index: index++, value: chars[index++] });\n } else if (value === \":\") {\n tokens.push({ type: \"param\", index: index++, value: name() });\n } else if (value === \"*\") {\n tokens.push({ type: \"wildcard\", index: index++, value: name() });\n } else {\n tokens.push({ type: \"char\", index: index++, value });\n }\n }\n\n tokens.push({ type: \"end\", index, value: \"\" });\n\n function consumeUntil(endType: TokenType): Token[] {\n const output: Token[] = [];\n\n while (true) {\n const token = tokens[pos++];\n if (token.type === endType) break;\n\n if (token.type === \"char\" || token.type === \"escape\") {\n let path = token.value;\n let cur = tokens[pos];\n\n while (cur.type === \"char\" || cur.type === \"escape\") {\n path += cur.value;\n cur = tokens[++pos];\n }\n\n output.push({\n type: \"text\",\n value: encodePath(path),\n });\n continue;\n }\n\n if (token.type === \"param\" || token.type === \"wildcard\") {\n output.push({\n type: token.type,\n name: token.value,\n });\n continue;\n }\n\n if (token.type === \"{\") {\n output.push({\n type: \"group\",\n tokens: consumeUntil(\"}\"),\n });\n continue;\n }\n\n throw new PathError(\n `Unexpected ${token.type} at index ${token.index}, expected ${endType}`,\n str,\n );\n }\n\n return output;\n }\n\n return new TokenData(consumeUntil(\"end\"), str);\n}\n\n/**\n * Compile a string to a template function for the path.\n */\nexport function compile

(\n path: Path,\n options: CompileOptions & ParseOptions = {},\n) {\n const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } =\n options;\n const data = typeof path === \"object\" ? path : parse(path, options);\n const fn = tokensToFunction(data.tokens, delimiter, encode);\n\n return function path(params: P = {} as P) {\n const [path, ...missing] = fn(params);\n if (missing.length) {\n throw new TypeError(`Missing parameters: ${missing.join(\", \")}`);\n }\n return path;\n };\n}\n\nexport type ParamData = Partial>;\nexport type PathFunction

= (data?: P) => string;\n\nfunction tokensToFunction(\n tokens: Token[],\n delimiter: string,\n encode: Encode | false,\n) {\n const encoders = tokens.map((token) =>\n tokenToFunction(token, delimiter, encode),\n );\n\n return (data: ParamData) => {\n const result: string[] = [\"\"];\n\n for (const encoder of encoders) {\n const [value, ...extras] = encoder(data);\n result[0] += value;\n result.push(...extras);\n }\n\n return result;\n };\n}\n\n/**\n * Convert a single token into a path building function.\n */\nfunction tokenToFunction(\n token: Token,\n delimiter: string,\n encode: Encode | false,\n): (data: ParamData) => string[] {\n if (token.type === \"text\") return () => [token.value];\n\n if (token.type === \"group\") {\n const fn = tokensToFunction(token.tokens, delimiter, encode);\n\n return (data) => {\n const [value, ...missing] = fn(data);\n if (!missing.length) return [value];\n return [\"\"];\n };\n }\n\n const encodeValue = encode || NOOP_VALUE;\n\n if (token.type === \"wildcard\" && encode !== false) {\n return (data) => {\n const value = data[token.name];\n if (value == null) return [\"\", token.name];\n\n if (!Array.isArray(value) || value.length === 0) {\n throw new TypeError(`Expected \"${token.name}\" to be a non-empty array`);\n }\n\n return [\n value\n .map((value, index) => {\n if (typeof value !== \"string\") {\n throw new TypeError(\n `Expected \"${token.name}/${index}\" to be a string`,\n );\n }\n\n return encodeValue(value);\n })\n .join(delimiter),\n ];\n };\n }\n\n return (data) => {\n const value = data[token.name];\n if (value == null) return [\"\", token.name];\n\n if (typeof value !== \"string\") {\n throw new TypeError(`Expected \"${token.name}\" to be a string`);\n }\n\n return [encodeValue(value)];\n };\n}\n\n/**\n * A match result contains data about the path match.\n */\nexport interface MatchResult

{\n path: string;\n params: P;\n}\n\n/**\n * A match is either `false` (no match) or a match result.\n */\nexport type Match

= false | MatchResult

;\n\n/**\n * The match function takes a string and returns whether it matched the path.\n */\nexport type MatchFunction

= (path: string) => Match

;\n\n/**\n * Supported path types.\n */\nexport type Path = string | TokenData;\n\n/**\n * Transform a path into a match function.\n */\nexport function match

(\n path: Path | Path[],\n options: MatchOptions & ParseOptions = {},\n): MatchFunction

{\n const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } =\n options;\n const { regexp, keys } = pathToRegexp(path, options);\n\n const decoders = keys.map((key) => {\n if (decode === false) return NOOP_VALUE;\n if (key.type === \"param\") return decode;\n return (value: string) => value.split(delimiter).map(decode);\n });\n\n return function match(input: string) {\n const m = regexp.exec(input);\n if (!m) return false;\n\n const path = m[0];\n const params = Object.create(null);\n\n for (let i = 1; i < m.length; i++) {\n if (m[i] === undefined) continue;\n\n const key = keys[i - 1];\n const decoder = decoders[i - 1];\n params[key.name] = decoder(m[i]);\n }\n\n return { path, params };\n };\n}\n\nexport function pathToRegexp(\n path: Path | Path[],\n options: PathToRegexpOptions & ParseOptions = {},\n) {\n const {\n delimiter = DEFAULT_DELIMITER,\n end = true,\n sensitive = false,\n trailing = true,\n } = options;\n const keys: Keys = [];\n const flags = sensitive ? \"\" : \"i\";\n const sources: string[] = [];\n\n for (const input of pathsToArray(path, [])) {\n const data = typeof input === \"object\" ? input : parse(input, options);\n for (const tokens of flatten(data.tokens, 0, [])) {\n sources.push(toRegExpSource(tokens, delimiter, keys, data.originalPath));\n }\n }\n\n let pattern = `^(?:${sources.join(\"|\")})`;\n if (trailing) pattern += `(?:${escape(delimiter)}$)?`;\n pattern += end ? \"$\" : `(?=${escape(delimiter)}|$)`;\n\n const regexp = new RegExp(pattern, flags);\n return { regexp, keys };\n}\n\n/**\n * Convert a path or array of paths into a flat array.\n */\nfunction pathsToArray(paths: Path | Path[], init: Path[]): Path[] {\n if (Array.isArray(paths)) {\n for (const p of paths) pathsToArray(p, init);\n } else {\n init.push(paths);\n }\n return init;\n}\n\n/**\n * Flattened token set.\n */\ntype FlatToken = Text | Parameter | Wildcard;\n\n/**\n * Generate a flat list of sequence tokens from the given tokens.\n */\nfunction* flatten(\n tokens: Token[],\n index: number,\n init: FlatToken[],\n): Generator {\n if (index === tokens.length) {\n return yield init;\n }\n\n const token = tokens[index];\n\n if (token.type === \"group\") {\n for (const seq of flatten(token.tokens, 0, init.slice())) {\n yield* flatten(tokens, index + 1, seq);\n }\n } else {\n init.push(token);\n }\n\n yield* flatten(tokens, index + 1, init);\n}\n\n/**\n * Transform a flat sequence of tokens into a regular expression.\n */\nfunction toRegExpSource(\n tokens: FlatToken[],\n delimiter: string,\n keys: Keys,\n originalPath: string | undefined,\n): string {\n let result = \"\";\n let backtrack = \"\";\n let isSafeSegmentParam = true;\n\n for (const token of tokens) {\n if (token.type === \"text\") {\n result += escape(token.value);\n backtrack += token.value;\n isSafeSegmentParam ||= token.value.includes(delimiter);\n continue;\n }\n\n if (token.type === \"param\" || token.type === \"wildcard\") {\n if (!isSafeSegmentParam && !backtrack) {\n throw new PathError(\n `Missing text before \"${token.name}\" ${token.type}`,\n originalPath,\n );\n }\n\n if (token.type === \"param\") {\n result += `(${negate(delimiter, isSafeSegmentParam ? \"\" : backtrack)}+)`;\n } else {\n result += `([\\\\s\\\\S]+)`;\n }\n\n keys.push(token);\n backtrack = \"\";\n isSafeSegmentParam = false;\n continue;\n }\n }\n\n return result;\n}\n\n/**\n * Block backtracking on previous text and ignore delimiter string.\n */\nfunction negate(delimiter: string, backtrack: string): string {\n if (backtrack.length < 2) {\n if (delimiter.length < 2) return `[^${escape(delimiter + backtrack)}]`;\n return `(?:(?!${escape(delimiter)})[^${escape(backtrack)}])`;\n }\n if (delimiter.length < 2) {\n return `(?:(?!${escape(backtrack)})[^${escape(delimiter)}])`;\n }\n return `(?:(?!${escape(backtrack)}|${escape(delimiter)})[\\\\s\\\\S])`;\n}\n\n/**\n * Stringify an array of tokens into a path string.\n */\nfunction stringifyTokens(tokens: Token[]): string {\n let value = \"\";\n let i = 0;\n\n function name(value: string) {\n const isSafe = isNameSafe(value) && isNextNameSafe(tokens[i]);\n return isSafe ? value : JSON.stringify(value);\n }\n\n while (i < tokens.length) {\n const token = tokens[i++];\n\n if (token.type === \"text\") {\n value += escapeText(token.value);\n continue;\n }\n\n if (token.type === \"group\") {\n value += `{${stringifyTokens(token.tokens)}}`;\n continue;\n }\n\n if (token.type === \"param\") {\n value += `:${name(token.name)}`;\n continue;\n }\n\n if (token.type === \"wildcard\") {\n value += `*${name(token.name)}`;\n continue;\n }\n\n throw new TypeError(`Unknown token type: ${(token as any).type}`);\n }\n\n return value;\n}\n\n/**\n * Stringify token data into a path string.\n */\nexport function stringify(data: TokenData): string {\n return stringifyTokens(data.tokens);\n}\n\n/**\n * Validate the parameter name contains valid ID characters.\n */\nfunction isNameSafe(name: string): boolean {\n const [first, ...rest] = name;\n return ID_START.test(first) && rest.every((char) => ID_CONTINUE.test(char));\n}\n\n/**\n * Validate the next token does not interfere with the current param name.\n */\nfunction isNextNameSafe(token: Token | undefined): boolean {\n if (token && token.type === \"text\") return !ID_CONTINUE.test(token.value[0]);\n return true;\n}\n"]} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["const DEFAULT_DELIMITER = \"/\";\nconst NOOP_VALUE = (value: string) => value;\nconst ID_START = /^[$_\\p{ID_Start}]$/u;\nconst ID_CONTINUE = /^[$\\u200c\\u200d\\p{ID_Continue}]$/u;\nconst ID = /^[$_\\p{ID_Start}][$\\u200c\\u200d\\p{ID_Continue}]*$/u;\n\n/**\n * Encode a string into another string.\n */\nexport type Encode = (value: string) => string;\n\n/**\n * Decode a string into another string.\n */\nexport type Decode = (value: string) => string;\n\nexport interface ParseOptions {\n /**\n * A function for encoding input strings.\n */\n encodePath?: Encode;\n}\n\nexport interface PathToRegexpOptions {\n /**\n * Matches the path completely without trailing characters. (default: `true`)\n */\n end?: boolean;\n /**\n * Allows optional trailing delimiter to match. (default: `true`)\n */\n trailing?: boolean;\n /**\n * Match will be case sensitive. (default: `false`)\n */\n sensitive?: boolean;\n /**\n * The default delimiter for segments. (default: `'/'`)\n */\n delimiter?: string;\n}\n\nexport interface MatchOptions extends PathToRegexpOptions {\n /**\n * Function for decoding strings for params, or `false` to disable entirely. (default: `decodeURIComponent`)\n */\n decode?: Decode | false;\n}\n\nexport interface CompileOptions {\n /**\n * Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)\n */\n encode?: Encode | false;\n /**\n * The default delimiter for segments. (default: `'/'`)\n */\n delimiter?: string;\n}\n\n/**\n * Escape text for stringify to path.\n */\nfunction escapeText(str: string) {\n return str.replace(/[{}()\\[\\]+?!:*\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Escape a regular expression string.\n */\nfunction escape(str: string) {\n return str.replace(/[.+*?^${}()[\\]|/\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Plain text.\n */\nexport interface Text {\n type: \"text\";\n value: string;\n}\n\n/**\n * A parameter designed to match arbitrary text within a segment.\n */\nexport interface Parameter {\n type: \"param\";\n name: string;\n}\n\n/**\n * A wildcard parameter designed to match multiple segments.\n */\nexport interface Wildcard {\n type: \"wildcard\";\n name: string;\n}\n\n/**\n * A set of possible tokens to expand when matching.\n */\nexport interface Group {\n type: \"group\";\n tokens: Token[];\n}\n\n/**\n * A token that corresponds with a regexp capture.\n */\nexport type Key = Parameter | Wildcard;\n\n/**\n * A sequence of `path-to-regexp` keys that match capturing groups.\n */\nexport type Keys = Array;\n\n/**\n * A sequence of path match characters.\n */\nexport type Token = Text | Parameter | Wildcard | Group;\n\n/**\n * Tokenized path instance.\n */\nexport class TokenData {\n constructor(\n public readonly tokens: Token[],\n public readonly originalPath?: string,\n ) {}\n}\n\n/**\n * ParseError is thrown when there is an error processing the path.\n */\nexport class PathError extends TypeError {\n constructor(\n message: string,\n public readonly originalPath: string | undefined,\n ) {\n let text = message;\n if (originalPath) text += `: ${originalPath}`;\n text += `; visit https://git.new/pathToRegexpError for info`;\n super(text);\n }\n}\n\n/**\n * Parse a string for the raw tokens.\n */\nexport function parse(str: string, options: ParseOptions = {}): TokenData {\n const { encodePath = NOOP_VALUE } = options;\n const chars = [...str];\n let index = 0;\n\n function consumeUntil(end: string): Token[] {\n const output: Token[] = [];\n let path = \"\";\n\n function writePath() {\n if (!path) return;\n output.push({\n type: \"text\",\n value: encodePath(path),\n });\n path = \"\";\n }\n\n while (index < chars.length) {\n const value = chars[index++];\n\n if (value === end) {\n writePath();\n return output;\n }\n\n if (value === \"\\\\\") {\n if (index === chars.length) {\n throw new PathError(`Unexpected end after \\\\ at index ${index}`, str);\n }\n\n path += chars[index++];\n continue;\n }\n\n if (value === \":\" || value === \"*\") {\n const type = value === \":\" ? \"param\" : \"wildcard\";\n let name = \"\";\n\n if (ID_START.test(chars[index])) {\n do {\n name += chars[index++];\n } while (ID_CONTINUE.test(chars[index]));\n } else if (chars[index] === '\"') {\n let quoteStart = index;\n\n while (index < chars.length) {\n if (chars[++index] === '\"') {\n index++;\n quoteStart = 0;\n break;\n }\n\n // Increment over escape characters.\n if (chars[index] === \"\\\\\") index++;\n\n name += chars[index];\n }\n\n if (quoteStart) {\n throw new PathError(\n `Unterminated quote at index ${quoteStart}`,\n str,\n );\n }\n }\n\n if (!name) {\n throw new PathError(`Missing parameter name at index ${index}`, str);\n }\n\n writePath();\n output.push({ type, name });\n continue;\n }\n\n if (value === \"{\") {\n writePath();\n output.push({\n type: \"group\",\n tokens: consumeUntil(\"}\"),\n });\n continue;\n }\n\n if (\n value === \"}\" ||\n value === \"(\" ||\n value === \")\" ||\n value === \"[\" ||\n value === \"]\" ||\n value === \"+\" ||\n value === \"?\" ||\n value === \"!\"\n ) {\n throw new PathError(`Unexpected ${value} at index ${index - 1}`, str);\n }\n\n path += value;\n }\n\n if (end) {\n throw new PathError(\n `Unexpected end at index ${index}, expected ${end}`,\n str,\n );\n }\n\n writePath();\n return output;\n }\n\n return new TokenData(consumeUntil(\"\"), str);\n}\n\n/**\n * Compile a string to a template function for the path.\n */\nexport function compile

(\n path: Path,\n options: CompileOptions & ParseOptions = {},\n) {\n const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } =\n options;\n const data = typeof path === \"object\" ? path : parse(path, options);\n const fn = tokensToFunction(data.tokens, delimiter, encode);\n\n return function path(params: P = {} as P) {\n const missing: string[] = [];\n const path = fn(params, missing);\n\n if (missing.length) {\n throw new TypeError(`Missing parameters: ${missing.join(\", \")}`);\n }\n\n return path;\n };\n}\n\nexport type ParamData = Partial>;\nexport type PathFunction

= (data?: P) => string;\n\n/**\n * Internal path builder function.\n */\ntype TokenEncoder = (data: ParamData, missing: string[]) => string;\n\nfunction tokensToFunction(\n tokens: Token[],\n delimiter: string,\n encode: Encode | false,\n): TokenEncoder {\n const encoders = tokens.map((token) =>\n tokenToFunction(token, delimiter, encode),\n );\n\n return (data: ParamData, missing: string[]) => {\n let result = \"\";\n\n for (const encoder of encoders) {\n result += encoder(data, missing);\n }\n\n return result;\n };\n}\n\n/**\n * Convert a single token into a path building function.\n */\nfunction tokenToFunction(\n token: Token,\n delimiter: string,\n encode: Encode | false,\n): TokenEncoder {\n if (token.type === \"text\") return () => token.value;\n\n if (token.type === \"group\") {\n const fn = tokensToFunction(token.tokens, delimiter, encode);\n\n return (data, missing) => {\n const len = missing.length;\n const value = fn(data, missing);\n if (missing.length === len) return value;\n\n missing.length = len; // Reset optional group.\n return \"\";\n };\n }\n\n const encodeValue = encode || NOOP_VALUE;\n\n if (token.type === \"wildcard\" && encode !== false) {\n return (data, missing) => {\n const value = data[token.name];\n if (value == null) {\n missing.push(token.name);\n return \"\";\n }\n\n if (!Array.isArray(value) || value.length === 0) {\n throw new TypeError(`Expected \"${token.name}\" to be a non-empty array`);\n }\n\n let result = \"\";\n\n for (let i = 0; i < value.length; i++) {\n if (typeof value[i] !== \"string\") {\n throw new TypeError(`Expected \"${token.name}/${i}\" to be a string`);\n }\n\n if (i > 0) result += delimiter;\n result += encodeValue(value[i]);\n }\n\n return result;\n };\n }\n\n return (data, missing) => {\n const value = data[token.name];\n if (value == null) {\n missing.push(token.name);\n return \"\";\n }\n\n if (typeof value !== \"string\") {\n throw new TypeError(`Expected \"${token.name}\" to be a string`);\n }\n\n return encodeValue(value);\n };\n}\n\n/**\n * A match result contains data about the path match.\n */\nexport interface MatchResult

{\n path: string;\n params: P;\n}\n\n/**\n * A match is either `false` (no match) or a match result.\n */\nexport type Match

= false | MatchResult

;\n\n/**\n * The match function takes a string and returns whether it matched the path.\n */\nexport type MatchFunction

= (path: string) => Match

;\n\n/**\n * Supported path types.\n */\nexport type Path = string | TokenData;\n\n/**\n * Transform a path into a match function.\n */\nexport function match

(\n path: Path | Path[],\n options: MatchOptions & ParseOptions = {},\n): MatchFunction

{\n const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } =\n options;\n const { regexp, keys } = pathToRegexp(path, options);\n\n const decoders = keys.map((key) => {\n if (decode === false) return NOOP_VALUE;\n if (key.type === \"param\") return decode;\n return (value: string) => value.split(delimiter).map(decode);\n });\n\n return function match(input: string) {\n const m = regexp.exec(input);\n if (!m) return false;\n\n const path = m[0];\n const params = Object.create(null);\n\n for (let i = 1; i < m.length; i++) {\n if (m[i] === undefined) continue;\n\n const key = keys[i - 1];\n const decoder = decoders[i - 1];\n params[key.name] = decoder(m[i]);\n }\n\n return { path, params };\n };\n}\n\n/**\n * Transform a path into a regular expression and capture keys.\n */\nexport function pathToRegexp(\n path: Path | Path[],\n options: PathToRegexpOptions & ParseOptions = {},\n) {\n const {\n delimiter = DEFAULT_DELIMITER,\n end = true,\n sensitive = false,\n trailing = true,\n } = options;\n const keys: Keys = [];\n let source = \"\";\n let combinations = 0;\n\n function process(path: Path | Path[]) {\n if (Array.isArray(path)) {\n for (const p of path) process(p);\n return;\n }\n\n const data = typeof path === \"object\" ? path : parse(path, options);\n flatten(data.tokens, 0, [], (tokens) => {\n if (combinations >= 256) {\n throw new PathError(\"Too many path combinations\", data.originalPath);\n }\n\n if (combinations > 0) source += \"|\";\n source += toRegExpSource(tokens, delimiter, keys, data.originalPath);\n combinations++;\n });\n }\n\n process(path);\n\n let pattern = `^(?:${source})`;\n if (trailing) pattern += \"(?:\" + escape(delimiter) + \"$)?\";\n pattern += end ? \"$\" : \"(?=\" + escape(delimiter) + \"|$)\";\n\n return { regexp: new RegExp(pattern, sensitive ? \"\" : \"i\"), keys };\n}\n\n/**\n * Generate a flat list of sequence tokens from the given tokens.\n */\nfunction flatten(\n tokens: Token[],\n index: number,\n result: Exclude[],\n callback: (result: Exclude[]) => void,\n): void {\n while (index < tokens.length) {\n const token = tokens[index++];\n\n if (token.type === \"group\") {\n const len = result.length;\n flatten(token.tokens, 0, result, (seq) =>\n flatten(tokens, index, seq, callback),\n );\n result.length = len;\n continue;\n }\n\n result.push(token);\n }\n\n callback(result);\n}\n\n/**\n * Transform a flat sequence of tokens into a regular expression.\n */\nfunction toRegExpSource(\n tokens: Exclude[],\n delimiter: string,\n keys: Keys,\n originalPath: string | undefined,\n): string {\n let result = \"\";\n let backtrack = \"\";\n let wildcardBacktrack = \"\";\n let prevCaptureType: 0 | 1 | 2 = 0;\n let hasSegmentCapture = 0;\n let index = 0;\n\n function hasInSegment(index: number, type: Token[\"type\"]) {\n while (index < tokens.length) {\n const token = tokens[index++];\n if (token.type === type) return true;\n if (token.type === \"text\") {\n if (token.value.includes(delimiter)) break;\n }\n }\n return false;\n }\n\n function peekText(index: number) {\n let result = \"\";\n while (index < tokens.length) {\n const token = tokens[index++];\n if (token.type !== \"text\") break;\n result += token.value;\n }\n return result;\n }\n\n while (index < tokens.length) {\n const token = tokens[index++];\n\n if (token.type === \"text\") {\n result += escape(token.value);\n backtrack += token.value;\n if (prevCaptureType === 2) wildcardBacktrack += token.value;\n if (token.value.includes(delimiter)) hasSegmentCapture = 0;\n continue;\n }\n\n if (token.type === \"param\" || token.type === \"wildcard\") {\n if (prevCaptureType && !backtrack) {\n throw new PathError(\n `Missing text before \"${token.name}\" ${token.type}`,\n originalPath,\n );\n }\n\n if (token.type === \"param\") {\n result +=\n hasSegmentCapture & 2 // Seen wildcard in segment.\n ? `(${negate(delimiter, backtrack)}+)`\n : hasInSegment(index, \"wildcard\") // See wildcard later in segment.\n ? `(${negate(delimiter, peekText(index))}+)`\n : hasSegmentCapture & 1 // Seen parameter in segment.\n ? `(${negate(delimiter, backtrack)}+|${escape(backtrack)})`\n : `(${negate(delimiter, \"\")}+)`;\n\n hasSegmentCapture |= prevCaptureType = 1;\n } else {\n result +=\n hasSegmentCapture & 2 // Seen wildcard in segment.\n ? `(${negate(backtrack, \"\")}+)`\n : wildcardBacktrack // No capture in segment, seen wildcard in path.\n ? `(${negate(wildcardBacktrack, \"\")}+|${negate(delimiter, \"\")}+)`\n : `([^]+)`;\n\n wildcardBacktrack = \"\";\n hasSegmentCapture |= prevCaptureType = 2;\n }\n\n keys.push(token);\n backtrack = \"\";\n continue;\n }\n\n throw new TypeError(`Unknown token type: ${(token as any).type}`);\n }\n\n return result;\n}\n\n/**\n * Block backtracking on previous text/delimiter.\n */\nfunction negate(a: string, b: string): string {\n if (b.length > a.length) return negate(b, a); // Longest string first.\n\n if (a === b) b = \"\"; // Cleaner regex strings, no duplication.\n if (b.length > 1) return `(?:(?!${escape(a)}|${escape(b)})[^])`;\n if (a.length > 1) return `(?:(?!${escape(a)})[^${escape(b)}])`;\n return `[^${escape(a + b)}]`;\n}\n\n/**\n * Stringify an array of tokens into a path string.\n */\nfunction stringifyTokens(tokens: Token[], index: number): string {\n let value = \"\";\n\n while (index < tokens.length) {\n const token = tokens[index++];\n\n if (token.type === \"text\") {\n value += escapeText(token.value);\n continue;\n }\n\n if (token.type === \"group\") {\n value += \"{\" + stringifyTokens(token.tokens, 0) + \"}\";\n continue;\n }\n\n if (token.type === \"param\") {\n value += \":\" + stringifyName(token.name, tokens[index]);\n continue;\n }\n\n if (token.type === \"wildcard\") {\n value += \"*\" + stringifyName(token.name, tokens[index]);\n continue;\n }\n\n throw new TypeError(`Unknown token type: ${(token as any).type}`);\n }\n\n return value;\n}\n\n/**\n * Stringify token data into a path string.\n */\nexport function stringify(data: TokenData): string {\n return stringifyTokens(data.tokens, 0);\n}\n\n/**\n * Stringify a parameter name, escaping when it cannot be emitted directly.\n */\nfunction stringifyName(name: string, next: Token | undefined): string {\n if (!ID.test(name)) return JSON.stringify(name);\n\n if (next?.type === \"text\" && ID_CONTINUE.test(next.value[0])) {\n return JSON.stringify(name);\n }\n\n return name;\n}\n"]} \ No newline at end of file diff --git a/node_modules/path-to-regexp/package.json b/node_modules/path-to-regexp/package.json index 7ae266e..44ca91d 100644 --- a/node_modules/path-to-regexp/package.json +++ b/node_modules/path-to-regexp/package.json @@ -1,6 +1,6 @@ { "name": "path-to-regexp", - "version": "8.3.0", + "version": "8.4.2", "description": "Express style path to RegExp utility", "keywords": [ "express", @@ -39,7 +39,7 @@ "@types/node": "^22.7.2", "@types/semver": "^7.3.1", "@vitest/coverage-v8": "^3.0.5", - "recheck": "^4.4.5", + "recheck": "^4.5.0", "size-limit": "^11.1.2", "typescript": "^5.7.3", "vitest": "^3.0.5" diff --git a/node_modules/qs/CHANGELOG.md b/node_modules/qs/CHANGELOG.md index 66f3179..14953a4 100644 --- a/node_modules/qs/CHANGELOG.md +++ b/node_modules/qs/CHANGELOG.md @@ -1,3 +1,30 @@ +## **6.15.3** +- [Fix] `parse`: enforce `throwOnLimitExceeded` for cumulative array growth via `combine`/`merge` +- [Fix] `utils`: respect encoding of surrogate pairs across chunks (#559) +- [Robustness] `parse`: throw the `arrayLimit` error before splitting oversized comma values +- [Robustness] `utils.merge` / `utils.assign`: avoid invoking `__proto__` setter when copying own properties +- [Robustness] `utils`: enforce `arrayLimit` consistently across `merge`'s array paths +- [Perf] `utils`: make `compact` O(n) via a side-channel visited-set instead of `Array.indexOf` +- [Deps] update `side-channel` +- [Dev Deps] update `eslint`, `mock-property`, `tape` +- [Tests] `parse`: characterize current lenient handling of unbalanced bracket keys (#558) + +## **6.15.2** +- [Fix] `stringify`: skip null/undefined entries in `arrayFormat: 'comma'` + `encodeValuesOnly` instead of crashing in `encoder` +- [Fix] `stringify`: use configured `delimiter` after `charsetSentinel` (#555) +- [Fix] `stringify`: apply `formatter` to encoded key under `strictNullHandling` (#554) +- [Fix] `stringify`: skip null/undefined filter-array entries instead of crashing in `encoder` (#551) +- [Fix] `parse`: handle nested bracket groups and add regression tests (#530) +- [readme] fix grammar (#550) +- [Dev Deps] update `@ljharb/eslint-config` +- [Tests] add regression tests for keys containing percent-encoded bracket text + +## **6.15.1** +- [Fix] `parse`: `parameterLimit: Infinity` with `throwOnLimitExceeded: true` silently drops all parameters +- [Deps] update `@ljharb/eslint-config` +- [Dev Deps] update `@ljharb/eslint-config`, `iconv-lite` +- [Tests] increase coverage + ## **6.15.0** - [New] `parse`: add `strictMerge` option to wrap object/primitive conflicts in an array (#425, #122) - [Fix] `duplicates` option should not apply to bracket notation keys (#514) diff --git a/node_modules/qs/README.md b/node_modules/qs/README.md index 0980c9a..fd64e3c 100644 --- a/node_modules/qs/README.md +++ b/node_modules/qs/README.md @@ -183,7 +183,7 @@ var withDots = qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { decod assert.deepEqual(withDots, { 'name.obj': { first: 'John', last: 'Doe' }}); ``` -Option `allowEmptyArrays` can be used to allowing empty array values in object +Option `allowEmptyArrays` can be used to allow empty array values in an object ```javascript var withEmptyArrays = qs.parse('foo[]&bar=baz', { allowEmptyArrays: true }); assert.deepEqual(withEmptyArrays, { foo: [], bar: 'baz' }); diff --git a/node_modules/qs/dist/qs.js b/node_modules/qs/dist/qs.js index 9cc9e70..829e020 100644 --- a/node_modules/qs/dist/qs.js +++ b/node_modules/qs/dist/qs.js @@ -5,28 +5,31 @@ "use strict";var stringify=require(4),parse=require(3),formats=require(1);module.exports={formats:formats,parse:parse,stringify:stringify}; },{"1":1,"3":3,"4":4}],3:[function(require,module,exports){ -"use strict";var utils=require(5),has=Object.prototype.hasOwnProperty,isArray=Array.isArray,defaults={allowDots:!1,allowEmptyArrays:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decodeDotInKeys:!1,decoder:utils.decode,delimiter:"&",depth:5,duplicates:"combine",ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictDepth:!1,strictMerge:!0,strictNullHandling:!1,throwOnLimitExceeded:!1},interpretNumericEntities=function(e){return e.replace(/&#(\d+);/g,function(e,t){return String.fromCharCode(parseInt(t,10))})},parseArrayValue=function(e,t,r){if(e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1)return e.split(",");if(t.throwOnLimitExceeded&&r>=t.arrayLimit)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return e},isoSentinel="utf8=%26%2310003%3B",charsetSentinel="utf8=%E2%9C%93",parseValues=function parseQueryStringValues(e,t){var r={__proto__:null},i=t.ignoreQueryPrefix?e.replace(/^\?/,""):e;i=i.replace(/%5B/gi,"[").replace(/%5D/gi,"]");var a=t.parameterLimit===1/0?void 0:t.parameterLimit,o=i.split(t.delimiter,t.throwOnLimitExceeded?a+1:a);if(t.throwOnLimitExceeded&&o.length>a)throw new RangeError("Parameter limit exceeded. Only "+a+" parameter"+(1===a?"":"s")+" allowed.");var l,n=-1,s=t.charset;if(t.charsetSentinel)for(l=0;l-1&&(c=isArray(c)?[c]:c),t.comma&&isArray(c)&&c.length>t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");c=utils.combine([],c,t.arrayLimit,t.plainObjects)}if(null!==d){var f=has.call(r,d);f&&("combine"===t.duplicates||p.indexOf("[]=")>-1)?r[d]=utils.combine(r[d],c,t.arrayLimit,t.plainObjects):f&&"last"!==t.duplicates||(r[d]=c)}}return r},parseObject=function(e,t,r,i){var a=0;if(e.length>0&&"[]"===e[e.length-1]){var o=e.slice(0,-1).join("");a=Array.isArray(t)&&t[o]?t[o].length:0}for(var l=i?t:parseArrayValue(t,r,a),n=e.length-1;n>=0;--n){var s,d=e[n];if("[]"===d&&r.parseArrays)s=utils.isOverflow(l)?l:r.allowEmptyArrays&&(""===l||r.strictNullHandling&&null===l)?[]:utils.combine([],l,r.arrayLimit,r.plainObjects);else{s=r.plainObjects?{__proto__:null}:{};var c="["===d.charAt(0)&&"]"===d.charAt(d.length-1)?d.slice(1,-1):d,p=r.decodeDotInKeys?c.replace(/%2E/g,"."):c,u=parseInt(p,10),y=!isNaN(u)&&d!==p&&String(u)===p&&u>=0&&r.parseArrays;if(r.parseArrays||""!==p)if(y&&u-1){if(i&&t.throwOnLimitExceeded)for(var a=0,o=e.indexOf(",");o>-1;){if((a+=1)>=t.arrayLimit)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");o=e.indexOf(",",o+1)}return e.split(",")}if(t.throwOnLimitExceeded&&r>=t.arrayLimit)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return e},isoSentinel="utf8=%26%2310003%3B",charsetSentinel="utf8=%E2%9C%93",parseValues=function parseQueryStringValues(e,t){var r={__proto__:null},i=t.ignoreQueryPrefix?e.replace(/^\?/,""):e;i=i.replace(/%5B/gi,"[").replace(/%5D/gi,"]");var a=t.parameterLimit===1/0?void 0:t.parameterLimit,o=i.split(t.delimiter,t.throwOnLimitExceeded&&void 0!==a?a+1:a);if(t.throwOnLimitExceeded&&void 0!==a&&o.length>a)throw new RangeError("Parameter limit exceeded. Only "+a+" parameter"+(1===a?"":"s")+" allowed.");var l,n=-1,s=t.charset;if(t.charsetSentinel)for(l=0;l-1&&(c=isArray(c)?[c]:c),t.comma&&isArray(c)&&c.length>t.arrayLimit&&(c=utils.combine([],c,t.arrayLimit,t.plainObjects,t.throwOnLimitExceeded)),null!==d){var f=has.call(r,d);f&&("combine"===t.duplicates||p.indexOf("[]=")>-1)?r[d]=utils.combine(r[d],c,t.arrayLimit,t.plainObjects,t.throwOnLimitExceeded):f&&"last"!==t.duplicates||(r[d]=c)}}return r},parseObject=function(e,t,r,i){var a=0;if(e.length>0&&"[]"===e[e.length-1]){var o=e.slice(0,-1).join("");a=Array.isArray(t)&&t[o]?t[o].length:0}for(var l=i?t:parseArrayValue(t,r,a),n=e.length-1;n>=0;--n){var s,d=e[n];if("[]"===d&&r.parseArrays)s=utils.isOverflow(l)?l:r.allowEmptyArrays&&(""===l||r.strictNullHandling&&null===l)?[]:utils.combine([],l,r.arrayLimit,r.plainObjects,r.throwOnLimitExceeded);else{s=r.plainObjects?{__proto__:null}:{};var c="["===d.charAt(0)&&"]"===d.charAt(d.length-1)?d.slice(1,-1):d,p=r.decodeDotInKeys?c.replace(/%2E/g,"."):c,u=parseInt(p,10),y=!isNaN(u)&&d!==p&&String(u)===p&&u>=0&&r.parseArrays;if(r.parseArrays||""!==p)if(y&&u=0?r.slice(0,a):r;if(o){if(!t.plainObjects&&has.call(Object.prototype,o)&&!t.allowPrototypes)return;i[i.length]=o}for(var l=r.length,n=a,s=0;n>=0&&s=0){if(!0===t.strictDepth)throw new RangeError("Input depth exceeded depth option of "+t.depth+" and strictDepth is true");i[i.length]="["+r.slice(n)+"]"}return i},parseKeys=function parseQueryStringKeys(e,t,r,i){if(e){var a=splitKeyIntoSegments(e,r);if(a)return parseObject(a,t,r,i)}},normalizeParseOptions=function normalizeParseOptions(e){if(!e)return defaults;if(void 0!==e.allowEmptyArrays&&"boolean"!=typeof e.allowEmptyArrays)throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided");if(void 0!==e.decodeDotInKeys&&"boolean"!=typeof e.decodeDotInKeys)throw new TypeError("`decodeDotInKeys` option can only be `true` or `false`, when provided");if(null!==e.decoder&&void 0!==e.decoder&&"function"!=typeof e.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");if(void 0!==e.throwOnLimitExceeded&&"boolean"!=typeof e.throwOnLimitExceeded)throw new TypeError("`throwOnLimitExceeded` option must be a boolean");var t=void 0===e.charset?defaults.charset:e.charset,r=void 0===e.duplicates?defaults.duplicates:e.duplicates;if("combine"!==r&&"first"!==r&&"last"!==r)throw new TypeError("The duplicates option must be either combine, first, or last");return{allowDots:void 0===e.allowDots?!0===e.decodeDotInKeys||defaults.allowDots:!!e.allowDots,allowEmptyArrays:"boolean"==typeof e.allowEmptyArrays?!!e.allowEmptyArrays:defaults.allowEmptyArrays,allowPrototypes:"boolean"==typeof e.allowPrototypes?e.allowPrototypes:defaults.allowPrototypes,allowSparse:"boolean"==typeof e.allowSparse?e.allowSparse:defaults.allowSparse,arrayLimit:"number"==typeof e.arrayLimit?e.arrayLimit:defaults.arrayLimit,charset:t,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:defaults.charsetSentinel,comma:"boolean"==typeof e.comma?e.comma:defaults.comma,decodeDotInKeys:"boolean"==typeof e.decodeDotInKeys?e.decodeDotInKeys:defaults.decodeDotInKeys,decoder:"function"==typeof e.decoder?e.decoder:defaults.decoder,delimiter:"string"==typeof e.delimiter||utils.isRegExp(e.delimiter)?e.delimiter:defaults.delimiter,depth:"number"==typeof e.depth||!1===e.depth?+e.depth:defaults.depth,duplicates:r,ignoreQueryPrefix:!0===e.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof e.interpretNumericEntities?e.interpretNumericEntities:defaults.interpretNumericEntities,parameterLimit:"number"==typeof e.parameterLimit?e.parameterLimit:defaults.parameterLimit,parseArrays:!1!==e.parseArrays,plainObjects:"boolean"==typeof e.plainObjects?e.plainObjects:defaults.plainObjects,strictDepth:"boolean"==typeof e.strictDepth?!!e.strictDepth:defaults.strictDepth,strictMerge:"boolean"==typeof e.strictMerge?!!e.strictMerge:defaults.strictMerge,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:defaults.strictNullHandling,throwOnLimitExceeded:"boolean"==typeof e.throwOnLimitExceeded&&e.throwOnLimitExceeded}};module.exports=function(e,t){var r=normalizeParseOptions(t);if(""===e||null==e)return r.plainObjects?{__proto__:null}:{};for(var i="string"==typeof e?parseValues(e,r):e,a=r.plainObjects?{__proto__:null}:{},o=Object.keys(i),l=0;l0?g.join(",")||null:void 0}];else if(isArray(f))S=f;else{var N=Object.keys(g);S=u?N.sort(u):N}var T=l?String(r).replace(/\./g,"%2E"):String(r),O=o&&isArray(g)&&1===g.length?T+"[]":T;if(a&&isArray(g)&&0===g.length)return O+"[]";for(var k=0;k0?c+y:""}; +"use strict";var getSideChannel=require(46),utils=require(5),formats=require(1),has=Object.prototype.hasOwnProperty,arrayPrefixGenerators={brackets:function brackets(e){return e+"[]"},comma:"comma",indices:function indices(e,r){return e+"["+r+"]"},repeat:function repeat(e){return e}},isArray=Array.isArray,push=Array.prototype.push,pushToArray=function(e,r){push.apply(e,isArray(r)?r:[r])},toISO=Date.prototype.toISOString,defaultFormat=formats.default,defaults={addQueryPrefix:!1,allowDots:!1,allowEmptyArrays:!1,arrayFormat:"indices",charset:"utf-8",charsetSentinel:!1,commaRoundTrip:!1,delimiter:"&",encode:!0,encodeDotInKeys:!1,encoder:utils.encode,encodeValuesOnly:!1,filter:void 0,format:defaultFormat,formatter:formats.formatters[defaultFormat],indices:!1,serializeDate:function serializeDate(e){return toISO.call(e)},skipNulls:!1,strictNullHandling:!1},isNonNullishPrimitive=function isNonNullishPrimitive(e){return"string"==typeof e||"number"==typeof e||"boolean"==typeof e||"symbol"==typeof e||"bigint"==typeof e},sentinel={},stringify=function stringify(e,r,t,o,a,n,i,l,s,f,u,d,y,c,p,m,h,v){for(var g=e,w=v,b=0,A=!1;void 0!==(w=w.get(sentinel))&&!A;){var D=w.get(e);if(b+=1,void 0!==D){if(D===b)throw new RangeError("Cyclic object value");A=!0}void 0===w.get(sentinel)&&(b=0)}if("function"==typeof f?g=f(r,g):g instanceof Date?g=y(g):"comma"===t&&isArray(g)&&(g=utils.maybeMap(g,function(e){return e instanceof Date?y(e):e})),null===g){if(n)return p(s&&!m?s(r,defaults.encoder,h,"key",c):r);g=""}if(isNonNullishPrimitive(g)||utils.isBuffer(g))return s?[p(m?r:s(r,defaults.encoder,h,"key",c))+"="+p(s(g,defaults.encoder,h,"value",c))]:[p(r)+"="+p(String(g))];var S,E=[];if(void 0===g)return E;if("comma"===t&&isArray(g))m&&s&&(g=utils.maybeMap(g,function(e){return null==e?e:s(e)})),S=[{value:g.length>0?g.join(",")||null:void 0}];else if(isArray(f))S=f;else{var N=Object.keys(g);S=u?N.sort(u):N}var T=l?String(r).replace(/\./g,"%2E"):String(r),O=o&&isArray(g)&&1===g.length?T+"[]":T;if(a&&isArray(g)&&0===g.length)return O+"[]";for(var k=0;k0?c+y:""}; },{"1":1,"46":46,"5":5}],5:[function(require,module,exports){ -"use strict";var formats=require(1),getSideChannel=require(46),has=Object.prototype.hasOwnProperty,isArray=Array.isArray,overflowChannel=getSideChannel(),markOverflow=function markOverflow(e,r){return overflowChannel.set(e,r),e},isOverflow=function isOverflow(e){return overflowChannel.has(e)},getMaxIndex=function getMaxIndex(e){return overflowChannel.get(e)},setMaxIndex=function setMaxIndex(e,r){overflowChannel.set(e,r)},hexTable=function(){for(var e=[],r=0;r<256;++r)e[e.length]="%"+((r<16?"0":"")+r.toString(16)).toUpperCase();return e}(),compactQueue=function compactQueue(e){for(;e.length>1;){var r=e.pop(),t=r.obj[r.prop];if(isArray(t)){for(var n=[],o=0;ot.arrayLimit)return markOverflow(arrayToObject(e.concat(r),t),n);e[n]=r}else{if(!e||"object"!=typeof e)return[e,r];if(isOverflow(e)){var o=getMaxIndex(e)+1;e[o]=r,setMaxIndex(e,o)}else{if(t&&t.strictMerge)return[e,r];(t&&(t.plainObjects||t.allowPrototypes)||!has.call(Object.prototype,r))&&(e[r]=!0)}}return e}if(!e||"object"!=typeof e){if(isOverflow(r)){for(var a=Object.keys(r),i=t&&t.plainObjects?{__proto__:null,0:e}:{0:e},c=0;ct.arrayLimit?markOverflow(arrayToObject(l,t),l.length-1):l}var f=e;return isArray(e)&&!isArray(r)&&(f=arrayToObject(e,t)),isArray(e)&&isArray(r)?(r.forEach(function(r,n){if(has.call(e,n)){var o=e[n];o&&"object"==typeof o&&r&&"object"==typeof r?e[n]=merge(o,r,t):e[e.length]=r}else e[n]=r}),e):Object.keys(r).reduce(function(e,n){var o=r[n];if(has.call(e,n)?e[n]=merge(e[n],o,t):e[n]=o,isOverflow(r)&&!isOverflow(e)&&markOverflow(e,getMaxIndex(r)),isOverflow(e)){var a=parseInt(n,10);String(a)===n&&a>=0&&a>getMaxIndex(e)&&setMaxIndex(e,a)}return e},f)},assign=function assignSingleSource(e,r){return Object.keys(r).reduce(function(e,t){return e[t]=r[t],e},e)},decode=function(e,r,t){var n=e.replace(/\+/g," ");if("iso-8859-1"===t)return n.replace(/%[0-9a-f]{2}/gi,unescape);try{return decodeURIComponent(n)}catch(e){return n}},limit=1024,encode=function encode(e,r,t,n,o){if(0===e.length)return e;var a=e;if("symbol"==typeof e?a=Symbol.prototype.toString.call(e):"string"!=typeof e&&(a=String(e)),"iso-8859-1"===t)return escape(a).replace(/%u[0-9a-f]{4}/gi,function(e){return"%26%23"+parseInt(e.slice(2),16)+"%3B"});for(var i="",c=0;c=limit?a.slice(c,c+limit):a,f=[],s=0;s=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122||o===formats.RFC1738&&(40===u||41===u)?f[f.length]=l.charAt(s):u<128?f[f.length]=hexTable[u]:u<2048?f[f.length]=hexTable[192|u>>6]+hexTable[128|63&u]:u<55296||u>=57344?f[f.length]=hexTable[224|u>>12]+hexTable[128|u>>6&63]+hexTable[128|63&u]:(s+=1,u=65536+((1023&u)<<10|1023&l.charCodeAt(s)),f[f.length]=hexTable[240|u>>18]+hexTable[128|u>>12&63]+hexTable[128|u>>6&63]+hexTable[128|63&u])}i+=f.join("")}return i},compact=function compact(e){for(var r=[{obj:{o:e},prop:"o"}],t=[],n=0;nt?markOverflow(arrayToObject(a,{plainObjects:n}),a.length-1):a},maybeMap=function maybeMap(e,r){if(isArray(e)){for(var t=[],n=0;n1;){var r=e.pop(),t=r.obj[r.prop];if(isArray(t)){for(var n=[],a=0;a=t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(e.concat(r),t),n)}e[n]=r}else{if(!e||"object"!=typeof e)return[e,r];if(isOverflow(e)){var a=getMaxIndex(e)+1;e[a]=r,setMaxIndex(e,a)}else{if(t&&t.strictMerge)return[e,r];(t&&(t.plainObjects||t.allowPrototypes)||!has.call(Object.prototype,r))&&(e[r]=!0)}}return e}if(!e||"object"!=typeof e){if(isOverflow(r)){for(var o=Object.keys(r),i=t&&t.plainObjects?{__proto__:null,0:e}:{0:e},l=0;lt.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(c,t),c.length-1)}return c}var f=e;if(isArray(e)&&!isArray(r)&&(f=arrayToObject(e,t)),isArray(e)&&isArray(r)){if(r.forEach(function(r,n){if(has.call(e,n)){var a=e[n];a&&"object"==typeof a&&r&&"object"==typeof r?e[n]=merge(a,r,t):e[e.length]=r}else e[n]=r}),t&&"number"==typeof t.arrayLimit&&e.length>t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(e,t),e.length-1)}return e}return Object.keys(r).reduce(function(e,n){var a=r[n];if(has.call(e,n)?setProperty(e,n,merge(e[n],a,t)):setProperty(e,n,a),isOverflow(r)&&!isOverflow(e)&&markOverflow(e,getMaxIndex(r)),isOverflow(e)){var o=parseInt(n,10);String(o)===n&&o>=0&&o>getMaxIndex(e)&&setMaxIndex(e,o)}return e},f)},assign=function assignSingleSource(e,r){return Object.keys(r).reduce(function(e,t){return setProperty(e,t,r[t]),e},e)},decode=function(e,r,t){var n=e.replace(/\+/g," ");if("iso-8859-1"===t)return n.replace(/%[0-9a-f]{2}/gi,unescape);try{return decodeURIComponent(n)}catch(e){return n}},limit=1024,encode=function encode(e,r,t,n,a){if(0===e.length)return e;var o=e;if("symbol"==typeof e?o=Symbol.prototype.toString.call(e):"string"!=typeof e&&(o=String(e)),"iso-8859-1"===t)return escape(o).replace(/%u[0-9a-f]{4}/gi,function(e){return"%26%23"+parseInt(e.slice(2),16)+"%3B"});for(var i="",l=0;l=limit?o.slice(l,l+limit):o;if(l+limit=55296&&f<=56319&&(c=c.slice(0,-1),l-=1)}for(var s=[],u=0;u=48&&y<=57||y>=65&&y<=90||y>=97&&y<=122||a===formats.RFC1738&&(40===y||41===y)?s[s.length]=c.charAt(u):y<128?s[s.length]=hexTable[y]:y<2048?s[s.length]=hexTable[192|y>>6]+hexTable[128|63&y]:y<55296||y>=57344?s[s.length]=hexTable[224|y>>12]+hexTable[128|y>>6&63]+hexTable[128|63&y]:(u+=1,y=65536+((1023&y)<<10|1023&c.charCodeAt(u)),s[s.length]=hexTable[240|y>>18]+hexTable[128|y>>12&63]+hexTable[128|y>>6&63]+hexTable[128|63&y])}i+=s.join("")}return i},compact=function compact(e){for(var r=[{obj:{o:e},prop:"o"}],t=getSideChannel(),n=0;nt){if(a)throw new RangeError("Array limit exceeded. Only "+t+" element"+(1===t?"":"s")+" allowed in an array.");return markOverflow(arrayToObject(i,{plainObjects:n}),i.length-1)}return i},maybeMap=function maybeMap(e,r){if(isArray(e)){for(var t=[],n=0;n -1) { + if (isFlatArrayValue && options.throwOnLimitExceeded) { + var commaCount = 0; + var commaIndex = val.indexOf(','); + while (commaIndex > -1) { + commaCount += 1; + if (commaCount >= options.arrayLimit) { + throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); + } + commaIndex = val.indexOf(',', commaIndex + 1); + } + } return val.split(','); } @@ -67,10 +78,10 @@ var parseValues = function parseQueryStringValues(str, options) { var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit; var parts = cleanStr.split( options.delimiter, - options.throwOnLimitExceeded ? limit + 1 : limit + options.throwOnLimitExceeded && typeof limit !== 'undefined' ? limit + 1 : limit ); - if (options.throwOnLimitExceeded && parts.length > limit) { + if (options.throwOnLimitExceeded && typeof limit !== 'undefined' && parts.length > limit) { throw new RangeError('Parameter limit exceeded. Only ' + limit + ' parameter' + (limit === 1 ? '' : 's') + ' allowed.'); } @@ -114,7 +125,8 @@ var parseValues = function parseQueryStringValues(str, options) { parseArrayValue( part.slice(pos + 1), options, - isArray(obj[key]) ? obj[key].length : 0 + isArray(obj[key]) ? obj[key].length : 0, + part.indexOf('[]=') === -1 ), function (encodedVal) { return options.decoder(encodedVal, defaults.decoder, charset, 'value'); @@ -132,10 +144,7 @@ var parseValues = function parseQueryStringValues(str, options) { } if (options.comma && isArray(val) && val.length > options.arrayLimit) { - if (options.throwOnLimitExceeded) { - throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); - } - val = utils.combine([], val, options.arrayLimit, options.plainObjects); + val = utils.combine([], val, options.arrayLimit, options.plainObjects, options.throwOnLimitExceeded); } if (key !== null) { @@ -145,7 +154,8 @@ var parseValues = function parseQueryStringValues(str, options) { obj[key], val, options.arrayLimit, - options.plainObjects + options.plainObjects, + options.throwOnLimitExceeded ); } else if (!existing || options.duplicates === 'last') { obj[key] = val; @@ -180,7 +190,8 @@ var parseObject = function (chain, val, options, valuesParsed) { [], leaf, options.arrayLimit, - options.plainObjects + options.plainObjects, + options.throwOnLimitExceeded ); } } else { @@ -214,9 +225,12 @@ var parseObject = function (chain, val, options, valuesParsed) { return leaf; }; -var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { - var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; +// Split a key like "a[b][c[]]" into ['a', '[b]', '[c[]]'] while preserving +// qs parse semantics for depth/prototype guards. +var splitKeyIntoSegments = function splitKeyIntoSegments(originalKey, options) { + var key = options.allowDots ? originalKey.replace(/\.([^.[]+)/g, '[$1]') : originalKey; + // depth <= 0 keeps the whole key as one segment if (options.depth <= 0) { if (!options.plainObjects && has.call(Object.prototype, key)) { if (!options.allowPrototypes) { @@ -227,14 +241,11 @@ var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { return [key]; } - var brackets = /(\[[^[\]]*])/; - var child = /(\[[^[\]]*])/g; - - var segment = brackets.exec(key); - var parent = segment ? key.slice(0, segment.index) : key; - - var keys = []; + var segments = []; + // parent before the first '[' (may be empty if key starts with '[') + var first = key.indexOf('['); + var parent = first >= 0 ? key.slice(0, first) : key; if (parent) { if (!options.plainObjects && has.call(Object.prototype, parent)) { if (!options.allowPrototypes) { @@ -242,32 +253,62 @@ var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { } } - keys[keys.length] = parent; + segments[segments.length] = parent; } - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { - i += 1; + var n = key.length; + var open = first; + var collected = 0; - var segmentContent = segment[1].slice(1, -1); - if (!options.plainObjects && has.call(Object.prototype, segmentContent)) { - if (!options.allowPrototypes) { - return; + while (open >= 0 && collected < options.depth) { + var level = 1; + var i = open + 1; + var close = -1; + + // balance nested '[' and ']' inside this bracket group using a nesting level counter + while (i < n && close < 0) { + var cu = key.charCodeAt(i); + if (cu === 0x5B) { // '[' + level += 1; + } else if (cu === 0x5D) { // ']' + level -= 1; + if (level === 0) { + close = i; // found matching close; loop will exit by condition + } } + i += 1; } - keys[keys.length] = segment[1]; + if (close < 0) { + // Unterminated group: wrap the raw remainder in one bracket pair so it stays + // a single literal segment (e.g. "[[]b" -> "[[]b]"); we do not infer missing ']'. + segments[segments.length] = '[' + key.slice(open) + ']'; + return segments; + } + + var seg = key.slice(open, close + 1); + // prototype guard for the content of this group + var content = seg.slice(1, -1); + if (!options.plainObjects && has.call(Object.prototype, content) && !options.allowPrototypes) { + return; + } + + segments[segments.length] = seg; + collected += 1; + + // find the next '[' after this balanced group + open = key.indexOf('[', close + 1); } - if (segment) { + if (open >= 0) { if (options.strictDepth === true) { throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true'); } - keys[keys.length] = '[' + key.slice(segment.index) + ']'; + segments[segments.length] = '[' + key.slice(open) + ']'; } - return keys; + return segments; }; var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) { diff --git a/node_modules/qs/lib/stringify.js b/node_modules/qs/lib/stringify.js index 2666eaf..b661691 100644 --- a/node_modules/qs/lib/stringify.js +++ b/node_modules/qs/lib/stringify.js @@ -118,7 +118,7 @@ var stringify = function stringify( if (obj === null) { if (strictNullHandling) { - return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix; + return formatter(encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix); } obj = ''; @@ -142,7 +142,9 @@ var stringify = function stringify( if (generateArrayPrefix === 'comma' && isArray(obj)) { // we need to join elements in if (encodeValuesOnly && encoder) { - obj = utils.maybeMap(obj, encoder); + obj = utils.maybeMap(obj, function (v) { + return v == null ? v : encoder(v); + }); } objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }]; } else if (isArray(filter)) { @@ -312,6 +314,11 @@ module.exports = function (object, opts) { var sideChannel = getSideChannel(); for (var i = 0; i < objKeys.length; ++i) { var key = objKeys[i]; + + if (typeof key === 'undefined' || key === null) { + continue; + } + var value = obj[key]; if (options.skipNulls && value === null) { @@ -345,10 +352,10 @@ module.exports = function (object, opts) { if (options.charsetSentinel) { if (options.charset === 'iso-8859-1') { // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark - prefix += 'utf8=%26%2310003%3B&'; + prefix += 'utf8=%26%2310003%3B' + options.delimiter; } else { // encodeURIComponent('✓') - prefix += 'utf8=%E2%9C%93&'; + prefix += 'utf8=%E2%9C%93' + options.delimiter; } } diff --git a/node_modules/qs/lib/utils.js b/node_modules/qs/lib/utils.js index 9aa39e1..6fce590 100644 --- a/node_modules/qs/lib/utils.js +++ b/node_modules/qs/lib/utils.js @@ -2,6 +2,7 @@ var formats = require('./formats'); var getSideChannel = require('side-channel'); +var defineProperty = require('es-define-property'); var has = Object.prototype.hasOwnProperty; var isArray = Array.isArray; @@ -66,6 +67,19 @@ var arrayToObject = function arrayToObject(source, options) { return obj; }; +var setProperty = function setProperty(obj, key, value) { + if (key === '__proto__' && defineProperty) { + defineProperty(obj, key, { + configurable: true, + enumerable: true, + value: value, + writable: true + }); + } else { + obj[key] = value; + } +}; + var merge = function merge(target, source, options) { /* eslint no-param-reassign: 0 */ if (!source) { @@ -75,7 +89,10 @@ var merge = function merge(target, source, options) { if (typeof source !== 'object' && typeof source !== 'function') { if (isArray(target)) { var nextIndex = target.length; - if (options && typeof options.arrayLimit === 'number' && nextIndex > options.arrayLimit) { + if (options && typeof options.arrayLimit === 'number' && nextIndex >= options.arrayLimit) { + if (options.throwOnLimitExceeded) { + throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); + } return markOverflow(arrayToObject(target.concat(source), options), nextIndex); } target[nextIndex] = source; @@ -115,6 +132,9 @@ var merge = function merge(target, source, options) { } var combined = [target].concat(source); if (options && typeof options.arrayLimit === 'number' && combined.length > options.arrayLimit) { + if (options.throwOnLimitExceeded) { + throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); + } return markOverflow(arrayToObject(combined, options), combined.length - 1); } return combined; @@ -138,6 +158,12 @@ var merge = function merge(target, source, options) { target[i] = item; } }); + if (options && typeof options.arrayLimit === 'number' && target.length > options.arrayLimit) { + if (options.throwOnLimitExceeded) { + throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); + } + return markOverflow(arrayToObject(target, options), target.length - 1); + } return target; } @@ -145,9 +171,9 @@ var merge = function merge(target, source, options) { var value = source[key]; if (has.call(acc, key)) { - acc[key] = merge(acc[key], value, options); + setProperty(acc, key, merge(acc[key], value, options)); } else { - acc[key] = value; + setProperty(acc, key, value); } if (isOverflow(source) && !isOverflow(acc)) { @@ -166,7 +192,7 @@ var merge = function merge(target, source, options) { var assign = function assignSingleSource(target, source) { return Object.keys(source).reduce(function (acc, key) { - acc[key] = source[key]; + setProperty(acc, key, source[key]); return acc; }, target); }; @@ -212,6 +238,13 @@ var encode = function encode(str, defaultEncoder, charset, kind, format) { var out = ''; for (var j = 0; j < string.length; j += limit) { var segment = string.length >= limit ? string.slice(j, j + limit) : string; + if (j + limit < string.length) { + var last = segment.charCodeAt(segment.length - 1); + if (last >= 0xD800 && last <= 0xDBFF) { + segment = segment.slice(0, -1); + j -= 1; + } + } var arr = []; for (var i = 0; i < segment.length; ++i) { @@ -265,7 +298,7 @@ var encode = function encode(str, defaultEncoder, charset, kind, format) { var compact = function compact(value) { var queue = [{ obj: { o: value }, prop: 'o' }]; - var refs = []; + var refs = getSideChannel(); for (var i = 0; i < queue.length; ++i) { var item = queue[i]; @@ -275,9 +308,9 @@ var compact = function compact(value) { for (var j = 0; j < keys.length; ++j) { var key = keys[j]; var val = obj[key]; - if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { + if (typeof val === 'object' && val !== null && !refs.has(val)) { queue[queue.length] = { obj: obj, prop: key }; - refs[refs.length] = val; + refs.set(val, true); } } } @@ -299,9 +332,12 @@ var isBuffer = function isBuffer(obj) { return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); }; -var combine = function combine(a, b, arrayLimit, plainObjects) { +var combine = function combine(a, b, arrayLimit, plainObjects, throwOnLimitExceeded) { // If 'a' is already an overflow object, add to it if (isOverflow(a)) { + if (throwOnLimitExceeded) { + throw new RangeError('Array limit exceeded. Only ' + arrayLimit + ' element' + (arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); + } var newIndex = getMaxIndex(a) + 1; a[newIndex] = b; setMaxIndex(a, newIndex); @@ -310,6 +346,9 @@ var combine = function combine(a, b, arrayLimit, plainObjects) { var result = [].concat(a, b); if (result.length > arrayLimit) { + if (throwOnLimitExceeded) { + throw new RangeError('Array limit exceeded. Only ' + arrayLimit + ' element' + (arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); + } return markOverflow(arrayToObject(result, { plainObjects: plainObjects }), result.length - 1); } return result; diff --git a/node_modules/qs/package.json b/node_modules/qs/package.json index 73edd39..baa6795 100644 --- a/node_modules/qs/package.json +++ b/node_modules/qs/package.json @@ -2,7 +2,7 @@ "name": "qs", "description": "A querystring parser that supports nesting and arrays, with a depth limit", "homepage": "https://github.com/ljharb/qs", - "version": "6.15.0", + "version": "6.15.3", "repository": { "type": "git", "url": "https://github.com/ljharb/qs.git" @@ -31,18 +31,19 @@ "node": ">=0.6" }, "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "devDependencies": { "@browserify/envify": "^6.0.0", "@browserify/uglifyify": "^6.0.0", - "@ljharb/eslint-config": "^22.1.3", + "@ljharb/eslint-config": "^22.2.3", "browserify": "^16.5.2", "bundle-collapser": "^1.4.0", "common-shakeify": "~1.0.0", "eclint": "^2.8.1", "es-value-fixtures": "^1.7.1", - "eslint": "^9.39.2", + "eslint": "^10.5.0", "evalmd": "^0.0.19", "for-each": "^0.3.5", "glob": "=10.3.7", @@ -51,12 +52,12 @@ "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", - "iconv-lite": "^0.5.1", + "iconv-lite": "^0.5.2", "in-publish": "^2.0.1", "jackspeak": "=2.1.1", "jiti": "^0.0.0", "mkdirp": "^0.5.5", - "mock-property": "^1.1.0", + "mock-property": "^1.1.2", "module-deps": "^6.2.3", "npmignore": "^0.3.5", "nyc": "^10.3.2", @@ -64,7 +65,7 @@ "qs-iconv": "^1.0.4", "safe-publish-latest": "^2.0.0", "safer-buffer": "^2.1.2", - "tape": "^5.9.0", + "tape": "^5.10.2", "unassertify": "^3.0.1" }, "scripts": { diff --git a/node_modules/qs/test/parse.js b/node_modules/qs/test/parse.js index 292039d..17f30b6 100644 --- a/node_modules/qs/test/parse.js +++ b/node_modules/qs/test/parse.js @@ -14,6 +14,12 @@ var hasProto = require('has-proto')(); var qs = require('../'); var utils = require('../lib/utils'); +var characterizeParse = function characterizeParse(st, input, opts, expected, label) { + var result; + st.doesNotThrow(function () { result = qs.parse(input, opts); }, label + ': does not throw'); + st.deepEqual(result, expected, label + ': parses to the current lenient output'); +}; + test('parse()', function (t) { t.test('parses a simple string', function (st) { st.deepEqual(qs.parse('0=foo'), { 0: 'foo' }); @@ -210,6 +216,21 @@ test('parse()', function (t) { t.test('uses original key when depth = 0', function (st) { st.deepEqual(qs.parse('a[0]=b&a[1]=c', { depth: 0 }), { 'a[0]': 'b', 'a[1]': 'c' }); st.deepEqual(qs.parse('a[0][0]=b&a[0][1]=c&a[1]=d&e=2', { depth: 0 }), { 'a[0][0]': 'b', 'a[0][1]': 'c', 'a[1]': 'd', e: '2' }); + st.deepEqual(qs.parse('a.b=c', { depth: 0, allowDots: true }), { 'a[b]': 'c' }, 'normalizes dots before applying depth-0 behavior'); + st.deepEqual(qs.parse('toString=foo', { depth: 0 }), {}, 'respects prototype guard at depth 0'); + st.deepEqual(qs.parse('toString=foo', { depth: 0, allowPrototypes: true }), { toString: 'foo' }, 'allows prototypes at depth 0 when enabled'); + st.end(); + }); + + t.test('ignores prototype keys when depth = 0 and allowPrototypes is false', function (st) { + st.deepEqual(qs.parse('toString=foo', { depth: 0 }), {}); + st.deepEqual(qs.parse('hasOwnProperty=bar', { depth: 0 }), {}); + st.deepEqual(qs.parse('toString=foo&a=b', { depth: 0 }), { a: 'b' }); + st.end(); + }); + + t.test('allows prototype keys when depth = 0 and allowPrototypes is true', function (st) { + st.deepEqual(qs.parse('toString=foo', { depth: 0, allowPrototypes: true }), { toString: 'foo' }); st.end(); }); @@ -251,6 +272,94 @@ test('parse()', function (t) { st.end(); }); + t.test('parses keys with literal [] inside a bracket group (#493)', function (st) { + // A bracket pair inside a bracket group should be treated literally as part of the key + st.deepEqual( + qs.parse('search[withbracket[]]=foobar'), + { search: { 'withbracket[]': 'foobar' } }, + 'treats inner [] literally when inside a bracket group' + ); + + // Single-level variant + st.deepEqual( + qs.parse('a[b[]]=c'), + { a: { 'b[]': 'c' } }, + 'keeps "b[]" as a literal key' + ); + + // Nested with an array push on the outer level + st.deepEqual( + qs.parse('list[][x[]]=y'), + { list: [{ 'x[]': 'y' }] }, + 'preserves inner [] while still treating outer [] as array push' + ); + + // Multiple nested bracket pairs: inner [] remains literal as part of the key + st.deepEqual( + qs.parse('a[b[c[]]]=d'), + { a: { 'b[c[]]': 'd' } }, + 'treats "b[c[]]" as a literal key inside the bracket group' + ); + + // Depth limits with literal brackets: preserve inner [] while limiting bracket-group parsing + st.deepEqual( + qs.parse('a[b[c[]]][d]=e', { depth: 1 }), + { a: { 'b[c[]]': { '[d]': 'e' } } }, + 'respects depth: 1 and preserves literal inner [] in the parsed key' + ); + + // Unterminated inner bracket group is wrapped as a literal remainder segment + st.deepEqual( + qs.parse('a[[]b=c'), + { a: { '[[]b': 'c' } }, + 'handles unterminated inner bracket groups without throwing' + ); + + st.end(); + }); + + t.test('currently parses unbalanced bracket keys after a parent leniently to literal segments (issue #558)', function (st) { + characterizeParse(st, 'a[bc=v', undefined, { a: { '[bc': 'v' } }, 'unclosed group after a parent'); + characterizeParse(st, 'a[=v', undefined, { a: { '[': 'v' } }, 'bare unclosed bracket after a parent'); + characterizeParse(st, 'a[b][c=v', undefined, { a: { b: { '[c': 'v' } } }, 'unclosed group after a valid one'); + characterizeParse(st, 'a[b]c[d=v', undefined, { a: { b: { '[d': 'v' } } }, 'unclosed group after text following a valid one'); + characterizeParse(st, 'filters[customtags:Env: Prod=v', undefined, { filters: { '[customtags:Env: Prod': 'v' } }, 'the issue #558 reproduction'); + characterizeParse(st, '][a=v', undefined, { ']': { '[a': 'v' } }, 'stray close bracket before an unclosed group'); + characterizeParse(st, 'a][b=v', undefined, { 'a]': { '[b': 'v' } }, 'stray close bracket inside the parent'); + st.end(); + }); + + t.test('currently parses unbalanced bracket keys containing inner brackets leniently (issue #558)', function (st) { + characterizeParse(st, 'a[b[c=v', undefined, { a: { '[b[c': 'v' } }, 'unclosed group containing an inner bracket'); + characterizeParse(st, 'a[b[c]=v', undefined, { a: { '[b[c]': 'v' } }, 'unbalanced group with an inner bracket and one close'); + characterizeParse(st, 'a[b][c[d=v', undefined, { a: { b: { '[c[d': 'v' } } }, 'unclosed inner-bracket group after a valid one'); + st.end(); + }); + + t.test('currently parses bracket-prefixed unbalanced keys leniently (issue #558)', function (st) { + characterizeParse(st, '[abc=v', undefined, { '[abc': 'v' }, 'key starting with an unclosed bracket'); + characterizeParse(st, '[[]b=v', undefined, { '[[]b': 'v' }, 'key starting with an unbalanced bracket group'); + st.end(); + }); + + t.test('lenient unbalanced-bracket handling currently depends on the depth option (issue #558)', function (st) { + characterizeParse(st, 'a[b]c[d]e[f=v', { depth: 5 }, { a: { b: { d: { '[f': 'v' } } } }, 'consumes groups up to the depth budget then keeps the unclosed remainder literal'); + characterizeParse(st, 'a[b]c[d]e[f=v', { depth: 1 }, { a: { b: { '[d]e[f': 'v' } } }, 'a lower depth keeps more of the unclosed remainder literal'); + characterizeParse(st, 'a[bc=v', { depth: 0 }, { 'a[bc': 'v' }, 'depth 0 keeps the entire key literal'); + st.end(); + }); + + t.test('currently parses an allowDots key with a trailing unclosed bracket leniently (issue #558)', function (st) { + characterizeParse(st, 'a.b[c=v', { allowDots: true }, { a: { b: { '[c': 'v' } } }, 'allowDots expands the dot then keeps the unclosed bracket literal'); + st.end(); + }); + + t.test('valid and stray-close bracket keys are unaffected by unbalanced-bracket handling', function (st) { + characterizeParse(st, 'a]b=v', undefined, { 'a]b': 'v' }, 'stray close bracket with no open bracket stays a flat key'); + characterizeParse(st, 'a[b]extra=v', undefined, { a: { b: 'v' } }, 'text after a balanced group is ignored'); + st.end(); + }); + t.test('allows to specify array indices', function (st) { st.deepEqual(qs.parse('a[1]=c&a[0]=b&a[2]=d'), { a: ['b', 'c', 'd'] }); st.deepEqual(qs.parse('a[1]=c&a[0]=b'), { a: ['b', 'c'] }); @@ -665,6 +774,21 @@ test('parse()', function (t) { st.end(); }); + t.test('does not crash on multi-step circular references', function (st) { + var a = {}; + a.b = { c: { d: a } }; + + var parsed; + + st.doesNotThrow(function () { + parsed = qs.parse({ foo: a }); + }); + + st.equal('foo' in parsed, true, 'parsed has "foo" property'); + st.equal(parsed.foo.b.c.d, parsed.foo, 'the multi-step cycle is preserved'); + st.end(); + }); + t.test('does not crash when parsing deep objects', function (st) { var parsed; var str = 'foo'; @@ -898,6 +1022,22 @@ test('parse()', function (t) { st.end(); }); + t.test('object-valued input with own `__proto__` does not mutate sub-object [[Prototype]]', function (st) { + // JSON.parse creates own data `__proto__` properties (via CreateDataProperty), + // which would trigger the Object.prototype.__proto__ accessor if merged via `acc[key] = value`. + var out = qs.parse({ + 'user[name]': 'alice', + user: JSON.parse('{"__proto__":{"isAdmin":true}}') + }, { allowPrototypes: false }); + + st.equal(out.user.name, 'alice', 'name from bracket key is preserved'); + st.equal(out.user.isAdmin, undefined, 'attacker-controlled inherited property is not exposed'); + st.equal(Object.getPrototypeOf(out.user), Object.prototype, 'sub-object [[Prototype]] is unchanged'); + st.equal(Object.prototype.isAdmin, undefined, 'Object.prototype is not polluted'); + + st.end(); + }); + t.test('can return null objects', { skip: !hasProto }, function (st) { var expected = { __proto__: null, @@ -1074,6 +1214,15 @@ test('parse()', function (t) { }; st.deepEqual(qs.parse('KeY=vAlUe', { decoder: decoder }), { key: 'VALUE' }); + + var noopDecoder = function () { return 'x'; }; + noopDecoder(); + st['throws']( + function () { decoder('x', noopDecoder, 'utf-8', 'unknown'); }, + 'this should never happen! type: unknown', + 'decoder throws for unexpected type' + ); + st.end(); }); @@ -1103,6 +1252,14 @@ test('parse()', function (t) { new RangeError('Parameter limit exceeded. Only 3 parameters allowed.'), 'throws error when parameter limit is exceeded' ); + + sst['throws']( + function () { + qs.parse('a=1&b=2', { parameterLimit: 1, throwOnLimitExceeded: true }); + }, + new RangeError('Parameter limit exceeded. Only 1 parameter allowed.'), + 'throws error with singular "parameter" when parameterLimit is 1' + ); sst.end(); }); @@ -1124,6 +1281,12 @@ test('parse()', function (t) { sst.end(); }); + st.test('allows unlimited parameters when parameterLimit is Infinity and throwOnLimitExceeded is true', function (sst) { + var result = qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: Infinity, throwOnLimitExceeded: true }); + sst.deepEqual(result, { a: '1', b: '2', c: '3', d: '4', e: '5', f: '6' }, 'parses all parameters without truncation or throwing'); + sst.end(); + }); + st.end(); }); @@ -1189,6 +1352,14 @@ test('parse()', function (t) { 'throws error when a sparse index exceeds arrayLimit' ); + sst['throws']( + function () { + qs.parse('a[2]=b', { arrayLimit: 1, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'throws error with singular "element" when arrayLimit is 1' + ); + sst.end(); }); @@ -1206,6 +1377,168 @@ test('parse()', function (t) { sst.end(); }); + st.test('throws when duplicate bracket keys exceed arrayLimit with throwOnLimitExceeded', function (sst) { + sst['throws']( + function () { + qs.parse('a[]=1&a[]=2&a[]=3&a[]=4&a[]=5&a[]=6', { arrayLimit: 5, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'), + 'throws error when duplicate bracket notation exceeds array limit' + ); + sst.end(); + }); + + st.test('throws when cumulative comma + duplicate-key combine exceeds arrayLimit', function (sst) { + sst['throws']( + function () { + qs.parse('a=1,2,3&a=4,5,6', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'), + 'throws when comma groups within the limit cumulatively exceed it across duplicate keys' + ); + + sst['throws']( + function () { + qs.parse('a=v,v,v,v,v&a=v,v,v,v,v&a=v,v,v,v,v', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'), + 'throws on a subsequent part once the cumulative array is already over the limit' + ); + sst.end(); + }); + + st.test('throws when plain duplicate keys combine past arrayLimit at the boundary', function (sst) { + sst['throws']( + function () { qs.parse('a=x&a=y', { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'duplicate scalar keys' + ); + + sst['throws']( + function () { qs.parse('a[]=x&a[]=y', { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'duplicate bracket keys' + ); + sst.end(); + }); + + st.test('throws when mixed index and key notation merge past arrayLimit', function (sst) { + sst['throws']( + function () { qs.parse('a=x&a[0]=y', { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'scalar then index that overflows on merge' + ); + + sst['throws']( + function () { qs.parse('a[0]=1&a[1]=2&a=3', { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'indexed array then scalar that overflows on merge' + ); + sst.end(); + }); + + st.test('enforces arrayLimit on merge at the boundary, consistently with combine', function (sst) { + sst['throws']( + function () { qs.parse('a[0]=x&a=y', { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'a trailing scalar merged into an at-limit array throws' + ); + sst.deepEqual( + qs.parse('a[0]=x&a=y', { arrayLimit: 1 }), + { a: { 0: 'x', 1: 'y' } }, + 'and converts to an overflow object without throwOnLimitExceeded' + ); + + sst['throws']( + function () { qs.parse('a[0]=x&a[]=y', { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'mixed index and bracket notation merged past the limit throws' + ); + sst.deepEqual( + qs.parse('a[0]=x&a[]=y', { arrayLimit: 1 }), + { a: { 0: 'x', 1: 'y' } }, + 'mixed index and bracket notation converts like duplicate-bracket combine' + ); + + sst.end(); + }); + + st.test('does not throw when cumulative comma combine stays within arrayLimit', function (sst) { + var result = qs.parse('a=1,2,3&a=4', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }); + sst.deepEqual(result, { a: ['1', '2', '3', '4'] }, 'combined array within limit is preserved'); + sst.end(); + }); + + st.test('silently combines to an overflow object when throwOnLimitExceeded is not set', function (sst) { + var result = qs.parse('a=1,2,3&a=4,5,6', { comma: true, arrayLimit: 5 }); + sst.deepEqual(result, { a: { 0: '1', 1: '2', 2: '3', 3: '4', 4: '5', 5: '6' } }, 'converts to object without throwing'); + sst.end(); + }); + + st.test('does not throw for comma groups nested under bracket notation, counting each group as one element', function (sst) { + var result = qs.parse('a[]=1,2,3&a[]=4,5,6', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }); + sst.deepEqual(result, { a: [['1', '2', '3'], ['4', '5', '6']] }, 'nested comma groups count as one element each'); + sst.end(); + }); + + st.test('throws before splitting when a single comma value exceeds arrayLimit', function (sst) { + sst['throws']( + function () { + qs.parse('a=1,2,3,4,5,6', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'), + 'a flat comma value over the limit throws' + ); + + sst['throws']( + function () { + qs.parse('a=1,2', { comma: true, arrayLimit: 1, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'singular message at arrayLimit 1' + ); + + sst['throws']( + function () { + qs.parse('a[b]=1,2,3,4,5,6', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'), + 'a non-bracket nested key comma value over the limit throws' + ); + sst.end(); + }); + + st.test('does not throw for a single comma value within arrayLimit', function (sst) { + sst.deepEqual( + qs.parse('a=1,2,3', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }), + { a: ['1', '2', '3'] }, + 'within the limit' + ); + sst.deepEqual( + qs.parse('a=1,2,3,4,5', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }), + { a: ['1', '2', '3', '4', '5'] }, + 'exactly at the limit' + ); + sst.end(); + }); + + st.test('does not throw for a bracketed comma group within arrayLimit', function (sst) { + var result = qs.parse('a[]=1,2,3,4,5,6', { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }); + sst.deepEqual(result, { a: [['1', '2', '3', '4', '5', '6']] }, 'a bracketed comma group is a single element'); + sst.end(); + }); + + st.test('throws for a bracketed comma group when arrayLimit is 0', function (sst) { + sst['throws']( + function () { + qs.parse('a[]=1,2,3', { comma: true, arrayLimit: 0, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 0 elements allowed in an array.'), + 'a single bracketed element still exceeds arrayLimit 0' + ); + sst.end(); + }); + st.end(); }); @@ -1462,6 +1795,14 @@ test('comma + arrayLimit', function (t) { new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'), 'throws error when comma-split exceeds array limit' ); + + st['throws']( + function () { + qs.parse('a=1,2,3', { comma: true, arrayLimit: 1, throwOnLimitExceeded: true }); + }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'throws error with singular "element" when arrayLimit is 1' + ); st.end(); }); @@ -1564,5 +1905,29 @@ test('mixed array and object notation', function (t) { st.end(); }); + t.test('uses existing array length for currentArrayLength when parsing object input with bracket keys', function (st) { + var input = {}; + var arr = ['x', 'y']; + arr.a = ['z', 'w']; + input['a[]'] = arr; + st.deepEqual(qs.parse(input), { a: ['x', 'y'] }, 'parses object input with bracket keys using existing array values'); + st.end(); + }); + + t.test('throws with singular message when object input bracket key exceeds arrayLimit of 1', function (st) { + var input = {}; + var arr = ['x']; + arr.a = ['z', 'w']; + input['a[]'] = arr; + st['throws']( + function () { + qs.parse(input, { throwOnLimitExceeded: true, arrayLimit: 1 }); + }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'throws singular error for object input exceeding arrayLimit 1' + ); + st.end(); + }); + t.end(); }); diff --git a/node_modules/qs/test/stringify.js b/node_modules/qs/test/stringify.js index 4d77694..07324cf 100644 --- a/node_modules/qs/test/stringify.js +++ b/node_modules/qs/test/stringify.js @@ -651,6 +651,49 @@ test('stringify()', function (t) { st.end(); }); + t.test('does not crash on null/undefined entries in arrayFormat=comma with encodeValuesOnly', function (st) { + st.doesNotThrow( + function () { qs.stringify({ a: [null, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); }, + 'does not pass a raw null array entry to the encoder' + ); + st.doesNotThrow( + function () { qs.stringify({ a: [undefined, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); }, + 'does not pass a raw undefined array entry to the encoder' + ); + st.doesNotThrow( + function () { qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true }); }, + 'does not crash on a single-null array' + ); + + st.equal( + qs.stringify({ a: [null, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }), + 'a=,b', + 'null entry joins as empty, comma stays unencoded under encodeValuesOnly' + ); + st.equal( + qs.stringify({ a: [undefined, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }), + 'a=,b', + 'undefined entry joins as empty, comma stays unencoded under encodeValuesOnly' + ); + st.equal( + qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true }), + 'a=', + 'single-null array stringifies as empty value' + ); + st.equal( + qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true, strictNullHandling: true }), + 'a', + 'strictNullHandling drops the equals sign for a single-null array' + ); + st.equal( + qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true, skipNulls: true }), + '', + 'skipNulls drops a single-null array entirely' + ); + + st.end(); + }); + t.test('stringifies a null object', { skip: !hasProto }, function (st) { st.equal(qs.stringify({ __proto__: null, a: 'b' }), 'a=b'); st.end(); @@ -825,6 +868,35 @@ test('stringify()', function (t) { st.end(); }); + t.test('skips null/undefined entries in filter=array', function (st) { + st.doesNotThrow( + function () { qs.stringify({ a: 'b', undefined: 'x' }, { filter: ['a', undefined] }); }, + 'does not pass a raw undefined filter entry to the encoder' + ); + st.doesNotThrow( + function () { qs.stringify({ a: 'b', 'null': 'x' }, { filter: ['a', null] }); }, + 'does not pass a raw null filter entry to the encoder' + ); + + st.equal( + qs.stringify({ a: 'b', undefined: 'x', c: 'd' }, { filter: ['a', undefined, 'c'] }), + 'a=b&c=d', + 'undefined filter entry is skipped, remaining keys are kept' + ); + st.equal( + qs.stringify({ a: 'b', 'null': 'x', c: 'd' }, { filter: ['a', null, 'c'] }), + 'a=b&c=d', + 'null filter entry is skipped, remaining keys are kept' + ); + st.equal( + qs.stringify({ a: 'b', 'null': 'x' }, { filter: [null] }), + '', + 'filter array containing only null yields empty string' + ); + + st.end(); + }); + t.test('supports custom representations when filter=function', function (st) { var calls = 0; var obj = { a: 'b', c: 'd', e: { f: new Date(1257894000000) } }; @@ -1111,6 +1183,28 @@ test('stringify()', function (t) { st.end(); }); + t.test('strictNullHandling: applies the formatter to the encoded key (RFC1738)', function (st) { + st.equal( + qs.stringify( + { 'a b': null, 'c d': 'e f' }, + { strictNullHandling: false, format: 'RFC1738' } + ), + 'a+b=&c+d=e+f', + 'without: as expected' + ); + + st.equal( + qs.stringify( + { 'a b': null, 'c d': 'e f' }, + { strictNullHandling: true, format: 'RFC1738' } + ), + 'a+b&c+d=e+f', + 'with: as expected' + ); + + st.end(); + }); + t.test('throws if an invalid charset is specified', function (st) { st['throws'](function () { qs.stringify({ a: 'b' }, { charset: 'foobar' }); @@ -1146,6 +1240,12 @@ test('stringify()', function (t) { 'adds the right sentinel when instructed to and the charset is iso-8859-1' ); + st.equal( + qs.stringify({ a: 1, b: 2 }, { charsetSentinel: true, delimiter: ';' }), + 'utf8=%E2%9C%93;a=1;b=2', + 'uses the configured delimiter after the sentinel' + ); + st.end(); }); @@ -1188,6 +1288,15 @@ test('stringify()', function (t) { }; st.deepEqual(qs.stringify({ KeY: 'vAlUe' }, { encoder: encoder }), 'key=VALUE'); + + var noopEncoder = function () { return 'x'; }; + noopEncoder(); + st['throws']( + function () { encoder('x', noopEncoder, 'utf-8', 'unknown'); }, + 'this should never happen! type: unknown', + 'encoder throws for unexpected type' + ); + st.end(); }); @@ -1307,4 +1416,33 @@ test('stringifies empty keys', function (t) { st.end(); }); + + t.test('round-trips keys containing percent-encoded bracket text', function (st) { + var cases = [ + { 'a%5Bb': 'c' }, + { 'a%5Db': 'c' }, + { 'a%255Bb': 'c' }, + { 'a%255Db': 'c' }, + { a: { 'b%5Bc': 'd' } }, + { a: { 'b%255Bc': 'd' } }, + { 'a%5B%255Bb': 'c' } + ]; + for (var i = 0; i < cases.length; i++) { + st.deepEqual( + qs.parse(qs.stringify(cases[i])), + cases[i], + 'round-trips ' + JSON.stringify(cases[i]) + ); + } + + st.end(); + }); + + t.test('parses input containing percent-encoded bracket text without mangling', function (st) { + st.deepEqual(qs.parse('a%25255Bb=c'), { 'a%255Bb': 'c' }, 'a%25255Bb decodes to a%255Bb, not a%5Bb'); + st.deepEqual(qs.parse('a%25255Db=c'), { 'a%255Db': 'c' }, 'a%25255Db decodes to a%255Db, not a%5Db'); + st.deepEqual(qs.parse('a%5Bb%25255Bc%5D=d'), { a: { 'b%255Bc': 'd' } }, 'nested %25255B decodes to %255B inside segment, not %5B'); + + st.end(); + }); }); diff --git a/node_modules/qs/test/utils.js b/node_modules/qs/test/utils.js index dc2f444..713b89b 100644 --- a/node_modules/qs/test/utils.js +++ b/node_modules/qs/test/utils.js @@ -31,6 +31,7 @@ test('merge()', function (t) { t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true }); var func = function f() {}; + func(); t.deepEqual( utils.merge(func, { foo: 'bar' }), [func, { foo: 'bar' }], @@ -64,6 +65,7 @@ test('merge()', function (t) { observed[0] = observed[0]; // eslint-disable-line no-self-assign st.equal(setCount, 1); st.equal(getCount, 2); + st.end(); } ); @@ -77,6 +79,7 @@ test('merge()', function (t) { s2t.ok(utils.isOverflow(overflow), 'overflow object is marked'); var merged = utils.merge(overflow, 'd'); s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'adds primitive at next numeric index'); + s2t.end(); }); @@ -92,6 +95,7 @@ test('merge()', function (t) { var obj = { foo: 'bar' }; var merged = utils.merge(obj, 'baz'); s2t.deepEqual(merged, { foo: 'bar', baz: true }, 'adds primitive as key with value true'); + s2t.end(); }); @@ -109,6 +113,17 @@ test('merge()', function (t) { var merged = utils.merge('c', overflow); s2t.ok(utils.isOverflow(merged), 'result is also marked as overflow'); s2t.deepEqual(merged, { 0: 'c', 1: 'a', 2: 'b' }, 'creates object with primitive at 0, source values shifted'); + + s2t.end(); + }); + + st.test('merges overflow object into primitive with plainObjects', function (s2t) { + var overflow = utils.combine(['a'], 'b', 0, false); + s2t.ok(utils.isOverflow(overflow), 'overflow object is marked'); + var merged = utils.merge('c', overflow, { plainObjects: true }); + s2t.ok(utils.isOverflow(merged), 'result is also marked as overflow'); + s2t.deepEqual(merged, { __proto__: null, 0: 'c', 1: 'a', 2: 'b' }, 'creates null-proto object with primitive at 0'); + s2t.end(); }); @@ -118,6 +133,7 @@ test('merge()', function (t) { s2t.ok(utils.isOverflow(overflow), 'overflow object is marked'); var merged = utils.merge('a', overflow); s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'shifts all source indices by 1'); + s2t.end(); }); @@ -125,6 +141,95 @@ test('merge()', function (t) { var obj = { foo: 'bar' }; var merged = utils.merge('a', obj); s2t.deepEqual(merged, ['a', { foo: 'bar' }], 'creates array with primitive and object'); + + s2t.end(); + }); + + st.test('merges primitive into array that exceeds arrayLimit', function (s2t) { + var arr = ['a', 'b', 'c']; + var merged = utils.merge(arr, 'd', { arrayLimit: 1 }); + s2t.ok(utils.isOverflow(merged), 'result is marked as overflow'); + s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'converts to overflow object with primitive appended'); + + s2t.end(); + }); + + st.test('merges array into primitive that exceeds arrayLimit', function (s2t) { + var merged = utils.merge('a', ['b', 'c'], { arrayLimit: 1 }); + s2t.ok(utils.isOverflow(merged), 'result is marked as overflow'); + s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c' }, 'converts to overflow object'); + + s2t.end(); + }); + + st.test('merges primitive into array at the arrayLimit boundary, consistently with combine', function (s2t) { + var merged = utils.merge(['a'], 'b', { arrayLimit: 1 }); + s2t.ok(utils.isOverflow(merged), 'result is marked as overflow at the boundary'); + s2t.deepEqual(merged, { 0: 'a', 1: 'b' }, 'converts to overflow object instead of a length-2 array'); + + s2t.end(); + }); + + st.test('merges two arrays that exceed arrayLimit into an overflow object', function (s2t) { + var merged = utils.merge(['a'], ['b'], { arrayLimit: 1 }); + s2t.ok(utils.isOverflow(merged), 'result is marked as overflow'); + s2t.deepEqual(merged, { 0: 'a', 1: 'b' }, 'array-into-array merge enforces arrayLimit like combine'); + + s2t.end(); + }); + + st.test('throws at the arrayLimit boundary when merging a primitive into an array with throwOnLimitExceeded', function (s2t) { + s2t['throws']( + function () { utils.merge(['a'], 'b', { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'throws when the resulting length would exceed arrayLimit' + ); + + s2t.end(); + }); + + st.test('throws when merging two arrays past arrayLimit with throwOnLimitExceeded', function (s2t) { + s2t['throws']( + function () { utils.merge(['a'], ['b'], { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'array-into-array merge throws rather than silently exceeding arrayLimit' + ); + s2t['throws']( + function () { utils.merge(['a', 'b', 'c'], ['d', 'e', 'f'], { arrayLimit: 2, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 2 elements allowed in an array.'), + 'uses the plural message when arrayLimit is not 1' + ); + + s2t.end(); + }); + + st.test('throws instead of merging primitive into over-limit array when throwOnLimitExceeded is set', function (s2t) { + s2t['throws']( + function () { utils.merge(['a', 'b', 'c'], 'd', { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'throws rather than converting to an overflow object' + ); + s2t['throws']( + function () { utils.merge(['a', 'b', 'c'], 'd', { arrayLimit: 2, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 2 elements allowed in an array.'), + 'uses the plural message when arrayLimit is not 1' + ); + + s2t.end(); + }); + + st.test('throws instead of merging array into primitive when throwOnLimitExceeded is set', function (s2t) { + s2t['throws']( + function () { utils.merge('a', ['b', 'c'], { arrayLimit: 1, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'throws rather than converting to an overflow object' + ); + s2t['throws']( + function () { utils.merge('a', ['b', 'c', 'd'], { arrayLimit: 2, throwOnLimitExceeded: true }); }, + new RangeError('Array limit exceeded. Only 2 elements allowed in an array.'), + 'uses the plural message when arrayLimit is not 1' + ); + s2t.end(); }); @@ -249,6 +354,47 @@ test('combine()', function (t) { st.end(); }); + t.test('with throwOnLimitExceeded', function (st) { + st.test('throws when concatenation exceeds the limit', function (s2t) { + s2t['throws']( + function () { utils.combine(['a', 'b', 'c'], 'd', 3, false, true); }, + new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'), + 'throws instead of converting to an overflow object' + ); + s2t['throws']( + function () { utils.combine([], 'a', 0, false, true); }, + new RangeError('Array limit exceeded. Only 0 elements allowed in an array.'), + 'throws with the correct count at arrayLimit 0' + ); + s2t.end(); + }); + + st.test('throws when adding to an existing overflow object', function (s2t) { + var overflow = utils.combine(['a', 'b'], 'c', 0, false); + s2t.ok(utils.isOverflow(overflow), 'initial object is marked as overflow'); + + s2t['throws']( + function () { utils.combine(overflow, 'd', 0, false, true); }, + new RangeError('Array limit exceeded. Only 0 elements allowed in an array.'), + 'throws rather than appending to the overflow object' + ); + s2t['throws']( + function () { utils.combine(overflow, 'd', 1, false, true); }, + new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), + 'uses the singular message at arrayLimit 1' + ); + s2t.end(); + }); + + st.test('does not throw when within the limit', function (s2t) { + var combined = utils.combine(['a'], 'b', 5, false, true); + s2t.deepEqual(combined, ['a', 'b'], 'returns the array unchanged when under the limit'); + s2t.end(); + }); + + st.end(); + }); + t.test('with existing overflow object', function (st) { st.test('adds to existing overflow object at next index', function (s2t) { // Create overflow object first via combine: 3 elements (indices 0-2) with limit 0 @@ -347,6 +493,79 @@ test('encode', function (t) { 'encodes a long string' ); + var boundary = ''; + var expected = ''; + for (var j = 0; j < 1023; j++) { + boundary += 'a'; + expected += 'a'; + } + boundary += '😀'; + expected += '%F0%9F%98%80'; + + t.equal( + utils.encode(boundary), + expected, + 'encodes a surrogate pair split across long-string chunks' + ); + + var laterBoundary = ''; + var laterExpected = ''; + for (var k = 0; k < 2047; k++) { + laterBoundary += 'a'; + laterExpected += 'a'; + } + laterBoundary += '😀'; + laterExpected += '%F0%9F%98%80'; + + t.equal( + utils.encode(laterBoundary), + laterExpected, + 'encodes a surrogate pair split across a later chunk boundary' + ); + + var twoPairs = ''; + for (k = 0; k < 1023; k++) { + twoPairs += 'a'; + } + twoPairs += '😀'; + for (k = 0; k < 1022; k++) { + twoPairs += 'b'; + } + twoPairs += '😀'; + + t.equal( + (utils.encode(twoPairs).match(/%F0%9F%98%80/g) || []).length, + 2, + 'encodes two surrogate pairs each split across a chunk boundary' + ); + + var roundTrip = ''; + for (k = 0; k < 1023; k++) { + roundTrip += 'a'; + } + roundTrip += '😀'; + + t.equal( + decodeURIComponent(utils.encode(roundTrip)), + roundTrip, + 'a boundary-split surrogate pair round-trips through decodeURIComponent' + ); + + var loneBoundary = ''; + var loneExpected = ''; + for (k = 0; k < 1023; k++) { + loneBoundary += 'a'; + loneExpected += 'a'; + } + loneBoundary += '\uD83DX'; + loneExpected += '%F0%9F%91%98'; + + t.equal( + utils.encode(loneBoundary), + loneExpected, + 'a lone high surrogate at a chunk boundary encodes the same as mid-chunk' + ); + t.equal( utils.encode('\x28\x29'), '%28%29', @@ -376,7 +595,9 @@ test('encode', function (t) { }); test('isBuffer()', function (t) { - forEach([null, undefined, true, false, '', 'abc', 42, 0, NaN, {}, [], function () {}, /a/g], function (x) { + var fn = function () {}; + fn(); + forEach([null, undefined, true, false, '', 'abc', 42, 0, NaN, {}, [], fn, /a/g], function (x) { t.equal(utils.isBuffer(x), false, inspect(x) + ' is not a buffer'); }); @@ -386,8 +607,9 @@ test('isBuffer()', function (t) { var saferBuffer = SaferBuffer.from('abc'); t.equal(utils.isBuffer(saferBuffer), true, 'SaferBuffer instance is a buffer'); - var buffer = Buffer.from && Buffer.alloc ? Buffer.from('abc') : new Buffer('abc'); - t.equal(utils.isBuffer(buffer), true, 'real Buffer instance is a buffer'); + var buffer = SaferBuffer.from('abc'); + t.notEqual(saferBuffer, buffer, 'different buffer instances'); + t.equal(utils.isBuffer(buffer), true, 'another Buffer instance is a buffer'); t.end(); }); diff --git a/node_modules/side-channel-list/CHANGELOG.md b/node_modules/side-channel-list/CHANGELOG.md index 2ec51b7..e68bcb9 100644 --- a/node_modules/side-channel-list/CHANGELOG.md +++ b/node_modules/side-channel-list/CHANGELOG.md @@ -5,11 +5,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.0.1](https://github.com/ljharb/side-channel-list.git +/compare/v1.0.0...v1.0.1) - 2026-04-08 + +### Fixed + +- [Fix] `delete`: do not reset the list when deleting the head node of a multi-node list [`#3`](https://github.com/ljharb/side-channel-list.git +/issues/3) + +### Commits + +- [actions] update workflows [`9e79e6b`](https://github.com/ljharb/side-channel-list.git +/commit/9e79e6bf845532fafbf03b547429fe4f737214a3) +- [Deps] update `@arethetypeswrong/cli`, `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/tape`, `eslint`, `npmignore` [`babf3ca`](https://github.com/ljharb/side-channel-list.git +/commit/babf3ca4849d2fd893a470a6b82c62a80ccc9307) +- [Deps] update `object-inspect` [`9f0f4b8`](https://github.com/ljharb/side-channel-list.git +/commit/9f0f4b88ff2aa8b7b7c9e589ac1513f133d64b9f) + ## v1.0.0 - 2024-12-10 ### Commits -- Initial implementation, tests, readme, types [`5d6baee`](https://github.com/ljharb/side-channel-list/commit/5d6baee5c9054a1238007f5a1dfc109a7a816251) -- Initial commit [`3ae784c`](https://github.com/ljharb/side-channel-list/commit/3ae784c63a47895fbaeed2a91ab54a8029a7a100) -- npm init [`07055a4`](https://github.com/ljharb/side-channel-list/commit/07055a4d139895565b199dba5fe2479c1a1b9e28) -- Only apps should have lockfiles [`9573058`](https://github.com/ljharb/side-channel-list/commit/9573058a47494e2d68f8c6c77b5d7fbe441949c1) +- Initial implementation, tests, readme, types [`5d6baee`](https://github.com/ljharb/side-channel-list.git +/commit/5d6baee5c9054a1238007f5a1dfc109a7a816251) +- Initial commit [`3ae784c`](https://github.com/ljharb/side-channel-list.git +/commit/3ae784c63a47895fbaeed2a91ab54a8029a7a100) +- npm init [`07055a4`](https://github.com/ljharb/side-channel-list.git +/commit/07055a4d139895565b199dba5fe2479c1a1b9e28) +- Only apps should have lockfiles [`9573058`](https://github.com/ljharb/side-channel-list.git +/commit/9573058a47494e2d68f8c6c77b5d7fbe441949c1) diff --git a/node_modules/side-channel-list/index.js b/node_modules/side-channel-list/index.js index 8d6f98c..4460229 100644 --- a/node_modules/side-channel-list/index.js +++ b/node_modules/side-channel-list/index.js @@ -84,9 +84,8 @@ module.exports = function getSideChannelList() { } }, 'delete': function (key) { - var root = $o && $o.next; var deletedNode = listDelete($o, key); - if (deletedNode && root && root === deletedNode) { + if (deletedNode && $o && !$o.next) { $o = void undefined; } return !!deletedNode; @@ -108,6 +107,5 @@ module.exports = function getSideChannelList() { listSet(/** @type {NonNullable} */ ($o), key, value); } }; - // @ts-expect-error TODO: figure out why this is erroring return channel; }; diff --git a/node_modules/side-channel-list/package.json b/node_modules/side-channel-list/package.json index ba0f5c5..bc4c08c 100644 --- a/node_modules/side-channel-list/package.json +++ b/node_modules/side-channel-list/package.json @@ -1,6 +1,6 @@ { "name": "side-channel-list", - "version": "1.0.0", + "version": "1.0.1", "description": "Store information about any JS value in a side channel, using a linked list", "main": "index.js", "exports": { @@ -38,21 +38,21 @@ "homepage": "https://github.com/ljharb/side-channel-list#readme", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "devDependencies": { - "@arethetypeswrong/cli": "^0.17.1", - "@ljharb/eslint-config": "^21.1.1", - "@ljharb/tsconfig": "^0.2.2", + "@arethetypeswrong/cli": "^0.18.2", + "@ljharb/eslint-config": "^22.2.2", + "@ljharb/tsconfig": "^0.3.2", "@types/object-inspect": "^1.13.0", - "@types/tape": "^5.6.5", + "@types/tape": "^5.8.1", "auto-changelog": "^2.5.0", "eclint": "^2.8.1", "encoding": "^0.1.13", - "eslint": "=8.8.0", + "eslint": "^8.57.1", "evalmd": "^0.0.19", "in-publish": "^2.0.1", - "npmignore": "^0.3.1", + "npmignore": "^0.3.5", "nyc": "^10.3.2", "safe-publish-latest": "^2.0.0", "tape": "^5.9.0", diff --git a/node_modules/side-channel-list/test/index.js b/node_modules/side-channel-list/test/index.js index 3ad4368..d1b915d 100644 --- a/node_modules/side-channel-list/test/index.js +++ b/node_modules/side-channel-list/test/index.js @@ -100,5 +100,55 @@ test('getSideChannelList', function (t) { st.end(); }); + t.test('delete: first node in a multi-node list', function (st) { + var channel = getSideChannelList(); + + channel.set('a', 1); + channel.set('b', 2); + + st.equal(channel['delete']('b'), true, 'deleting first data node yields true'); + + st.equal(channel.has('a'), true, 'second node is still present after deleting first'); + st.equal(channel.get('a'), 1, 'second node value is intact after deleting first'); + st.equal(channel.has('b'), false, 'deleted node is gone'); + + st.end(); + }); + + t.test('delete: last remaining node empties the list', function (st) { + var channel = getSideChannelList(); + + channel.set('a', 1); + channel.set('b', 2); + + st.equal(channel['delete']('b'), true, 'delete first node'); + st.equal(channel['delete']('a'), true, 'delete second (last) node'); + + st.equal(channel.has('a'), false, 'a is gone'); + st.equal(channel.has('b'), false, 'b is gone'); + st.equal(channel.get('a'), undefined, 'get a yields undefined'); + + channel.set('c', 3); + st.equal(channel.get('c'), 3, 'can set new values after emptying'); + + st.end(); + }); + + t.test('delete: middle node in a multi-node list', function (st) { + var channel = getSideChannelList(); + + channel.set('a', 1); + channel.set('b', 2); + channel.set('c', 3); + + st.equal(channel['delete']('b'), true, 'deleting middle node yields true'); + + st.equal(channel.get('a'), 1, 'first node still intact'); + st.equal(channel.has('b'), false, 'middle node is gone'); + st.equal(channel.get('c'), 3, 'last node still intact'); + + st.end(); + }); + t.end(); }); diff --git a/node_modules/side-channel/CHANGELOG.md b/node_modules/side-channel/CHANGELOG.md index 58e378c..decafe5 100644 --- a/node_modules/side-channel/CHANGELOG.md +++ b/node_modules/side-channel/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.1.1](https://github.com/ljharb/side-channel/compare/v1.1.0...v1.1.1) - 2026-06-08 + +### Commits + +- [Fix] `assert`: do not observably access object keys when throwing [`fc17361`](https://github.com/ljharb/side-channel/commit/fc173615136e6a6c3194656e6088afbc0bd6f9b8) +- [actions] update workflows [`35b18c0`](https://github.com/ljharb/side-channel/commit/35b18c0bced5769d59226cd44a7e4003ad0aee81) +- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/tape`, `auto-changelog`, `eslint`, `npmignore` [`b456a01`](https://github.com/ljharb/side-channel/commit/b456a01396cfdd028e5d39ea84885fe9178a72cf) +- [Deps] update `object-inspect`, `side-channel-list` [`accf1a1`](https://github.com/ljharb/side-channel/commit/accf1a1a2767a22b1f5eeb5769a1db4c35a78090) +- [readme] replace runkit CI badge with shields.io check-runs badge [`7e0c956`](https://github.com/ljharb/side-channel/commit/7e0c956411cc29267197a49a155a3d9bd01bacac) + ## [v1.1.0](https://github.com/ljharb/side-channel/compare/v1.0.6...v1.1.0) - 2024-12-11 ### Commits diff --git a/node_modules/side-channel/README.md b/node_modules/side-channel/README.md index cc7e103..73ba466 100644 --- a/node_modules/side-channel/README.md +++ b/node_modules/side-channel/README.md @@ -57,5 +57,5 @@ Clone the repo, `npm install`, and run `npm test` [downloads-url]: https://npm-stat.com/charts.html?package=side-channel [codecov-image]: https://codecov.io/gh/ljharb/side-channel/branch/main/graphs/badge.svg [codecov-url]: https://app.codecov.io/gh/ljharb/side-channel/ -[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/side-channel +[actions-image]: https://img.shields.io/github/check-runs/ljharb/side-channel/main [actions-url]: https://github.com/ljharb/side-channel/actions diff --git a/node_modules/side-channel/index.js b/node_modules/side-channel/index.js index a8a9b05..c5fe1fa 100644 --- a/node_modules/side-channel/index.js +++ b/node_modules/side-channel/index.js @@ -18,7 +18,10 @@ module.exports = function getSideChannel() { var channel = { assert: function (key) { if (!channel.has(key)) { - throw new $TypeError('Side channel does not contain ' + inspect(key)); + var keyDesc = key && Object(key) === key + ? 'the given object key' + : inspect(key); + throw new $TypeError('Side channel does not contain ' + keyDesc); } }, 'delete': function (key) { @@ -38,6 +41,6 @@ module.exports = function getSideChannel() { $channelData.set(key, value); } }; - // @ts-expect-error TODO: figure out why this is erroring + return channel; }; diff --git a/node_modules/side-channel/package.json b/node_modules/side-channel/package.json index 30fa42c..e39158e 100644 --- a/node_modules/side-channel/package.json +++ b/node_modules/side-channel/package.json @@ -1,6 +1,6 @@ { "name": "side-channel", - "version": "1.1.0", + "version": "1.1.1", "description": "Store information about any JS value in a side channel. Uses WeakMap if available.", "main": "index.js", "exports": { @@ -44,23 +44,23 @@ "homepage": "https://github.com/ljharb/side-channel#readme", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, "devDependencies": { - "@arethetypeswrong/cli": "^0.17.1", - "@ljharb/eslint-config": "^21.1.1", - "@ljharb/tsconfig": "^0.2.2", + "@arethetypeswrong/cli": "^0.18.3", + "@ljharb/eslint-config": "^22.2.3", + "@ljharb/tsconfig": "^0.3.2", "@types/object-inspect": "^1.13.0", - "@types/tape": "^5.6.5", - "auto-changelog": "^2.5.0", + "@types/tape": "^5.8.1", + "auto-changelog": "^2.6.0", "eclint": "^2.8.1", "encoding": "^0.1.13", - "eslint": "=8.8.0", + "eslint": "^8.57.1", "in-publish": "^2.0.1", - "npmignore": "^0.3.1", + "npmignore": "^0.3.5", "nyc": "^10.3.2", "safe-publish-latest": "^2.0.0", "tape": "^5.9.0", diff --git a/node_modules/side-channel/test/index.js b/node_modules/side-channel/test/index.js index bd1e7c2..5d28efd 100644 --- a/node_modules/side-channel/test/index.js +++ b/node_modules/side-channel/test/index.js @@ -28,6 +28,22 @@ test('getSideChannel', function (t) { channel.set(o, 'data'); st.doesNotThrow(function () { channel.assert(o); }, 'existent value noops'); + var accessed = false; + var trap = {}; + Object.defineProperty(trap, 'foo', { + enumerable: true, + get: function () { + accessed = true; + return 1; + } + }); + st['throws']( + function () { channel.assert(trap); }, + TypeError, + 'missing object key throws' + ); + st.equal(accessed, false, 'a missing object key is not observably accessed'); + st.end(); }); diff --git a/node_modules/type-is/index.js b/node_modules/type-is/index.js index e773845..37d6da3 100644 --- a/node_modules/type-is/index.js +++ b/node_modules/type-is/index.js @@ -42,11 +42,16 @@ module.exports.match = mimeMatch */ function typeis (value, types_) { + // Backward compatibility. TODO: Remove. + if (value && typeof value === 'object') { + value = value.headers['content-type'] + } + var i var types = types_ // remove parameters and normalize - var val = tryNormalizeType(value) + var val = normalizeType(value) // no type or invalid if (!val) { @@ -228,23 +233,8 @@ function mimeMatch (expected, actual) { * @private */ function normalizeType (value) { - // Parse the type - var type = contentType.parse(value).type + if (!value) return null + var type = contentType.parse(value, { parameters: false }).type return typer.test(type) ? type : null } - -/** - * Try to normalize a type and remove parameters. - * - * @param {string} value - * @return {(string|null)} - * @private - */ -function tryNormalizeType (value) { - try { - return value ? normalizeType(value) : null - } catch (err) { - return null - } -} diff --git a/node_modules/type-is/node_modules/content-type/LICENSE b/node_modules/type-is/node_modules/content-type/LICENSE new file mode 100644 index 0000000..34b1a2d --- /dev/null +++ b/node_modules/type-is/node_modules/content-type/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2015 Douglas Christopher Wilson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/type-is/node_modules/content-type/README.md b/node_modules/type-is/node_modules/content-type/README.md new file mode 100644 index 0000000..7f6847d --- /dev/null +++ b/node_modules/type-is/node_modules/content-type/README.md @@ -0,0 +1,69 @@ +# content-type + +[![NPM version][npm-image]][npm-url] +[![NPM downloads][downloads-image]][downloads-url] +[![Build status][build-image]][build-url] +[![Build coverage][coverage-image]][coverage-url] +[![License][license-image]][license-url] + +Create and parse HTTP `Content-Type` header. + +## Installation + +```sh +npm install content-type +``` + +## API + +```js +const contentType = require("content-type"); +``` + +### contentType.parse(string, options?) + +```js +const obj = contentType.parse("image/svg+xml; charset=utf-8"); +``` + +Parse a `Content-Type` header. This will return an object with the following properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`): + +- `type`: The media type. Example: `'image/svg+xml'`. +- `parameters`: An object of the parameters in the media type (parameter name is always lower case). Example: `{charset: 'utf-8'}`. + +The parser is lenient and does not error. You should validate `type` and `parameters` before trusting them. + +#### Options + +- `parameters` (default: `true`): Set to `false` to skip parameters. + +### contentType.format(obj) + +```js +const str = contentType.format({ + type: "image/svg+xml", + parameters: { charset: "utf-8" }, +}); +``` + +Format an object into a `Content-Type` header. This will return a string of the content type for the given object with the following properties (examples are shown that produce the string `'image/svg+xml; charset=utf-8'`): + +- `type`: The media type. Example: `'image/svg+xml'`. +- `parameters`: An optional object of the parameters in the media type. Example: `{charset: 'utf-8'}`. + +Throws a `TypeError` if the object contains an invalid type or parameter names. + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/content-type +[npm-url]: https://npmjs.org/package/content-type +[downloads-image]: https://img.shields.io/npm/dm/content-type +[downloads-url]: https://npmjs.org/package/content-type +[build-image]: https://img.shields.io/github/actions/workflow/status/jshttp/content-type/ci.yml?branch=master +[build-url]: https://github.com/jshttp/content-type/actions/workflows/ci.yml?query=branch%3Amaster +[coverage-image]: https://img.shields.io/codecov/c/gh/jshttp/content-type +[coverage-url]: https://codecov.io/gh/jshttp/content-type +[license-image]: http://img.shields.io/npm/l/content-type.svg?style=flat +[license-url]: LICENSE diff --git a/node_modules/type-is/node_modules/content-type/dist/index.d.ts b/node_modules/type-is/node_modules/content-type/dist/index.d.ts new file mode 100644 index 0000000..7e72898 --- /dev/null +++ b/node_modules/type-is/node_modules/content-type/dist/index.d.ts @@ -0,0 +1,26 @@ +/*! + * content-type + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ +/** + * The content type object contains a type string and optional parameters. + */ +export interface ContentType { + type: string; + parameters: Record; +} +/** + * Format an object into a `Content-Type` header. + */ +export declare function format(obj: Partial): string; +/** + * Options for parsing a `Content-Type` header. + */ +export interface ParseOptions { + parameters?: boolean; +} +/** + * Parse a `Content-Type` header. + */ +export declare function parse(header: string, options?: ParseOptions): ContentType; diff --git a/node_modules/type-is/node_modules/content-type/dist/index.js b/node_modules/type-is/node_modules/content-type/dist/index.js new file mode 100644 index 0000000..4026f97 --- /dev/null +++ b/node_modules/type-is/node_modules/content-type/dist/index.js @@ -0,0 +1,170 @@ +"use strict"; +/*! + * content-type + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.format = format; +exports.parse = parse; +const TEXT_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]*$/; +const TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; +/** + * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4 + */ +const QUOTE_REGEXP = /[\\"]/g; +/** + * RegExp to match type in RFC 9110 sec 8.3.1 + * + * media-type = type "/" subtype + * type = token + * subtype = token + */ +const TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; +/** + * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`. + */ +const NullObject = /* @__PURE__ */ (() => { + const C = function () { }; + C.prototype = Object.create(null); + return C; +})(); +/** + * Format an object into a `Content-Type` header. + */ +function format(obj) { + const { type, parameters } = obj; + if (!type || !TYPE_REGEXP.test(type)) { + throw new TypeError(`Invalid type: ${type}`); + } + let result = type; + if (parameters) { + for (const param of Object.keys(parameters)) { + if (!TOKEN_REGEXP.test(param)) { + throw new TypeError(`Invalid parameter name: ${param}`); + } + result += `; ${param}=${qstring(parameters[param])}`; + } + } + return result; +} +/** + * Parse a `Content-Type` header. + */ +function parse(header, options) { + const len = header.length; + let index = skipOWS(header, 0, len); + const valueStart = index; + index = skipValue(header, index, len); + const valueEnd = trailingOWS(header, valueStart, index); + const type = header.slice(valueStart, valueEnd).toLowerCase(); + const parameters = options?.parameters === false + ? new NullObject() + : parseParameters(header, index, len); + return { type, parameters }; +} +const SP = 32; // " " +const HTAB = 9; // "\t" +const SEMI = 59; // ";" +const EQ = 61; // "=" +const DQUOTE = 34; // '"' +const BSLASH = 92; // "\\" +/** + * Parses the parameters of a `Content-Type` header starting at the given index. + */ +function parseParameters(header, index, len) { + const parameters = new NullObject(); + parameter: while (index < len) { + index = skipOWS(header, index + 1 /* Skip over ; */, len); + const keyStart = index; + while (index < len) { + const code = header.charCodeAt(index); + if (code === SEMI) + continue parameter; + if (code === EQ) { + const keyEnd = trailingOWS(header, keyStart, index); + const key = header.slice(keyStart, keyEnd).toLowerCase(); + index = skipOWS(header, index + 1, len); + if (index < len && header.charCodeAt(index) === DQUOTE) { + index++; + let value = ""; + while (index < len) { + const code = header.charCodeAt(index++); + if (code === DQUOTE) { + index = skipValue(header, index, len); + if (parameters[key] === undefined) + parameters[key] = value; + break; + } + if (code === BSLASH && index < len) { + value += header[index++]; + continue; + } + value += String.fromCharCode(code); + } + continue parameter; + } + const valueStart = index; + index = skipValue(header, index, len); + if (parameters[key] === undefined) { + const valueEnd = trailingOWS(header, valueStart, index); + parameters[key] = header.slice(valueStart, valueEnd); + } + continue parameter; + } + index++; + } + } + return parameters; +} +/** + * Skip over characters until a semicolon. + */ +function skipValue(str, index, len) { + while (index < len) { + const char = str.charCodeAt(index); + if (char === SEMI) + break; + index++; + } + return index; +} +/** + * Skip optional whitespace (OWS) in an HTTP header value. + * + * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t"). + */ +function skipOWS(header, index, len) { + while (index < len) { + const char = header.charCodeAt(index); + if (char !== SP && char !== HTAB) + break; + index++; + } + return index; +} +/** + * Trim optional whitespace (OWS) from the end of a substring. + * + * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t"). + */ +function trailingOWS(header, start, end) { + while (end > start) { + const char = header.charCodeAt(end - 1); + if (char !== SP && char !== HTAB) + break; + end--; + } + return end; +} +/** + * Serialize a parameter value. + */ +function qstring(str) { + if (TOKEN_REGEXP.test(str)) + return str; + if (TEXT_REGEXP.test(str)) + return `"${str.replace(QUOTE_REGEXP, "\\$&")}"`; + throw new TypeError(`Invalid parameter value: ${str}`); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/type-is/node_modules/content-type/dist/index.js.map b/node_modules/type-is/node_modules/content-type/dist/index.js.map new file mode 100644 index 0000000..db5da25 --- /dev/null +++ b/node_modules/type-is/node_modules/content-type/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * content-type\n * Copyright(c) 2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\nconst TEXT_REGEXP = /^[\\u0009\\u0020-\\u007e\\u0080-\\u00ff]*$/;\nconst TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\n\n/**\n * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4\n */\nconst QUOTE_REGEXP = /[\\\\\"]/g;\n\n/**\n * RegExp to match type in RFC 9110 sec 8.3.1\n *\n * media-type = type \"/\" subtype\n * type = token\n * subtype = token\n */\nconst TYPE_REGEXP =\n /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\n\n/**\n * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`.\n */\nconst NullObject = /* @__PURE__ */ (() => {\n const C = function () {};\n C.prototype = Object.create(null);\n return C;\n})() as unknown as { new (): any };\n\n/**\n * The content type object contains a type string and optional parameters.\n */\nexport interface ContentType {\n type: string;\n parameters: Record;\n}\n\n/**\n * Format an object into a `Content-Type` header.\n */\nexport function format(obj: Partial): string {\n const { type, parameters } = obj;\n\n if (!type || !TYPE_REGEXP.test(type)) {\n throw new TypeError(`Invalid type: ${type}`);\n }\n\n let result = type;\n\n if (parameters) {\n for (const param of Object.keys(parameters)) {\n if (!TOKEN_REGEXP.test(param)) {\n throw new TypeError(`Invalid parameter name: ${param}`);\n }\n\n result += `; ${param}=${qstring(parameters[param])}`;\n }\n }\n\n return result;\n}\n\n/**\n * Options for parsing a `Content-Type` header.\n */\nexport interface ParseOptions {\n parameters?: boolean;\n}\n\n/**\n * Parse a `Content-Type` header.\n */\nexport function parse(header: string, options?: ParseOptions): ContentType {\n const len = header.length;\n let index = skipOWS(header, 0, len);\n\n const valueStart = index;\n index = skipValue(header, index, len);\n const valueEnd = trailingOWS(header, valueStart, index);\n const type = header.slice(valueStart, valueEnd).toLowerCase();\n const parameters =\n options?.parameters === false\n ? new NullObject()\n : parseParameters(header, index, len);\n\n return { type, parameters };\n}\n\nconst SP = 32; // \" \"\nconst HTAB = 9; // \"\\t\"\nconst SEMI = 59; // \";\"\nconst EQ = 61; // \"=\"\nconst DQUOTE = 34; // '\"'\nconst BSLASH = 92; // \"\\\\\"\n\n/**\n * Parses the parameters of a `Content-Type` header starting at the given index.\n */\nfunction parseParameters(\n header: string,\n index: number,\n len: number,\n): Record {\n const parameters: Record = new NullObject();\n\n parameter: while (index < len) {\n index = skipOWS(header, index + 1 /* Skip over ; */, len);\n\n const keyStart = index;\n\n while (index < len) {\n const code = header.charCodeAt(index);\n if (code === SEMI) continue parameter;\n\n if (code === EQ) {\n const keyEnd = trailingOWS(header, keyStart, index);\n const key = header.slice(keyStart, keyEnd).toLowerCase();\n\n index = skipOWS(header, index + 1, len);\n\n if (index < len && header.charCodeAt(index) === DQUOTE) {\n index++;\n\n let value = \"\";\n while (index < len) {\n const code = header.charCodeAt(index++);\n if (code === DQUOTE) {\n index = skipValue(header, index, len);\n if (parameters[key] === undefined) parameters[key] = value;\n break;\n }\n\n if (code === BSLASH && index < len) {\n value += header[index++];\n continue;\n }\n\n value += String.fromCharCode(code);\n }\n\n continue parameter;\n }\n\n const valueStart = index;\n index = skipValue(header, index, len);\n\n if (parameters[key] === undefined) {\n const valueEnd = trailingOWS(header, valueStart, index);\n parameters[key] = header.slice(valueStart, valueEnd);\n }\n\n continue parameter;\n }\n\n index++;\n }\n }\n\n return parameters;\n}\n\n/**\n * Skip over characters until a semicolon.\n */\nfunction skipValue(str: string, index: number, len: number): number {\n while (index < len) {\n const char = str.charCodeAt(index);\n if (char === SEMI) break;\n index++;\n }\n return index;\n}\n\n/**\n * Skip optional whitespace (OWS) in an HTTP header value.\n *\n * OWS is defined in RFC 9110 sec 5.6.3 as SP (\" \") or HTAB (\"\\t\").\n */\nfunction skipOWS(header: string, index: number, len: number): number {\n while (index < len) {\n const char = header.charCodeAt(index);\n if (char !== SP && char !== HTAB) break;\n index++;\n }\n return index;\n}\n\n/**\n * Trim optional whitespace (OWS) from the end of a substring.\n *\n * OWS is defined in RFC 9110 sec 5.6.3 as SP (\" \") or HTAB (\"\\t\").\n */\nfunction trailingOWS(header: string, start: number, end: number): number {\n while (end > start) {\n const char = header.charCodeAt(end - 1);\n if (char !== SP && char !== HTAB) break;\n end--;\n }\n return end;\n}\n\n/**\n * Serialize a parameter value.\n */\nfunction qstring(str: string): string {\n if (TOKEN_REGEXP.test(str)) return str;\n if (TEXT_REGEXP.test(str)) return `\"${str.replace(QUOTE_REGEXP, \"\\\\$&\")}\"`;\n\n throw new TypeError(`Invalid parameter value: ${str}`);\n}\n"]} \ No newline at end of file diff --git a/node_modules/type-is/node_modules/content-type/package.json b/node_modules/type-is/node_modules/content-type/package.json new file mode 100644 index 0000000..482cbc8 --- /dev/null +++ b/node_modules/type-is/node_modules/content-type/package.json @@ -0,0 +1,52 @@ +{ + "name": "content-type", + "version": "2.0.0", + "description": "Create and parse HTTP Content-Type header", + "keywords": [ + "content-type", + "http", + "req", + "res", + "rfc7231", + "rfc9110" + ], + "repository": "jshttp/content-type", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + }, + "license": "MIT", + "author": "Douglas Christopher Wilson ", + "type": "commonjs", + "exports": "./dist/index.js", + "main": "./dist/index.js", + "typings": "./dist/index.d.ts", + "files": [ + "dist/" + ], + "scripts": { + "bench": "vitest bench", + "build": "ts-scripts build", + "format": "ts-scripts format", + "prepare": "ts-scripts install && npm run build", + "specs": "ts-scripts specs", + "test": "ts-scripts test" + }, + "devDependencies": { + "@borderless/ts-scripts": "^0.15.0", + "@vitest/coverage-v8": "^3.0.5", + "typescript": "^5.7.3", + "vitest": "^3.2.4" + }, + "engines": { + "node": ">=18" + }, + "ts-scripts": { + "dist": [ + "dist" + ], + "project": [ + "tsconfig.build.json" + ] + } +} diff --git a/node_modules/type-is/package.json b/node_modules/type-is/package.json index 08586d2..07c623f 100644 --- a/node_modules/type-is/package.json +++ b/node_modules/type-is/package.json @@ -1,31 +1,35 @@ { "name": "type-is", "description": "Infer the content-type of a request.", - "version": "2.0.1", + "version": "2.1.0", "contributors": [ "Douglas Christopher Wilson ", "Jonathan Ong (http://jongleberry.com)" ], "license": "MIT", "repository": "jshttp/type-is", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + }, "dependencies": { - "content-type": "^1.0.5", + "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "devDependencies": { "eslint": "7.32.0", "eslint-config-standard": "14.1.1", - "eslint-plugin-import": "2.25.4", + "eslint-plugin-import": "2.31.0", "eslint-plugin-markdown": "2.2.1", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.2.0", "eslint-plugin-standard": "4.1.0", - "mocha": "9.2.1", + "mocha": "9.2.2", "nyc": "15.1.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 18" }, "files": [ "LICENSE", diff --git a/package-lock.json b/package-lock.json index 8b884ca..71b37dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,20 +26,20 @@ } }, "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", - "content-type": "^1.0.5", + "content-type": "^2.0.0", "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" }, "engines": { "node": ">=18" @@ -49,6 +49,19 @@ "url": "https://opencollective.com/express" } }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -201,9 +214,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -380,9 +393,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -561,9 +574,9 @@ } }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", @@ -584,12 +597,13 @@ } }, "node_modules/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -696,14 +710,14 @@ "license": "ISC" }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -715,13 +729,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -786,17 +800,34 @@ } }, "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", "license": "MIT", "dependencies": { - "content-type": "^1.0.5", + "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/unpipe": { diff --git a/rdov_keys.txt b/rdov_keys.txt new file mode 100644 index 0000000..cefde11 --- /dev/null +++ b/rdov_keys.txt @@ -0,0 +1,12 @@ +# RDOV SECRETS + +## Google Gemini (Flash 1.5) +API_KEY: AIzaSyA-YHI7CDp7bAZz-2U9IRjzMrmzhAM7zkA + +## Supabase +URL: https://h0oggskgs0ws0sco8kc4s8ws.supabase.reifonas.cloud +ANON_KEY: (ver src/lib/supabase/client.ts) + +## Proxy Login (Bypass Field) +USER: teste +PASS: teste -> associa-se a admin@tracksteel.com diff --git a/server.log b/server.log new file mode 100644 index 0000000..df15144 --- /dev/null +++ b/server.log @@ -0,0 +1,2 @@ +nohup: ignoring input +VaultUI Server rodando na porta 80