This commit is contained in:
2025-06-26 03:35:15 +00:00
parent 56fa52fd80
commit 59f287112f
2193 changed files with 289518 additions and 3540 deletions

View File

@@ -0,0 +1,319 @@
'use strict'
const debug = require('../internal/debug')
const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants')
const { safeRe: re, t } = require('../internal/re')
const parseOptions = require('../internal/parse-options')
const { compareIdentifiers } = require('../internal/identifiers')
class SemVer {
constructor (version, options) {
options = parseOptions(options)
if (version instanceof SemVer) {
if (version.loose === !!options.loose &&
version.includePrerelease === !!options.includePrerelease) {
return version
} else {
version = version.version
}
} else if (typeof version !== 'string') {
throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`)
}
if (version.length > MAX_LENGTH) {
throw new TypeError(
`version is longer than ${MAX_LENGTH} characters`
)
}
debug('SemVer', version, options)
this.options = options
this.loose = !!options.loose
// this isn't actually relevant for versions, but keep it so that we
// don't run into trouble passing this.options around.
this.includePrerelease = !!options.includePrerelease
const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])
if (!m) {
throw new TypeError(`Invalid Version: ${version}`)
}
this.raw = version
// these are actually numbers
this.major = +m[1]
this.minor = +m[2]
this.patch = +m[3]
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
throw new TypeError('Invalid major version')
}
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
throw new TypeError('Invalid minor version')
}
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
throw new TypeError('Invalid patch version')
}
// numberify any prerelease numeric ids
if (!m[4]) {
this.prerelease = []
} else {
this.prerelease = m[4].split('.').map((id) => {
if (/^[0-9]+$/.test(id)) {
const num = +id
if (num >= 0 && num < MAX_SAFE_INTEGER) {
return num
}
}
return id
})
}
this.build = m[5] ? m[5].split('.') : []
this.format()
}
format () {
this.version = `${this.major}.${this.minor}.${this.patch}`
if (this.prerelease.length) {
this.version += `-${this.prerelease.join('.')}`
}
return this.version
}
toString () {
return this.version
}
compare (other) {
debug('SemVer.compare', this.version, this.options, other)
if (!(other instanceof SemVer)) {
if (typeof other === 'string' && other === this.version) {
return 0
}
other = new SemVer(other, this.options)
}
if (other.version === this.version) {
return 0
}
return this.compareMain(other) || this.comparePre(other)
}
compareMain (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
return (
compareIdentifiers(this.major, other.major) ||
compareIdentifiers(this.minor, other.minor) ||
compareIdentifiers(this.patch, other.patch)
)
}
comparePre (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
// NOT having a prerelease is > having one
if (this.prerelease.length && !other.prerelease.length) {
return -1
} else if (!this.prerelease.length && other.prerelease.length) {
return 1
} else if (!this.prerelease.length && !other.prerelease.length) {
return 0
}
let i = 0
do {
const a = this.prerelease[i]
const b = other.prerelease[i]
debug('prerelease compare', i, a, b)
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
compareBuild (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
let i = 0
do {
const a = this.build[i]
const b = other.build[i]
debug('build compare', i, a, b)
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
// preminor will bump the version up to the next minor release, and immediately
// down to pre-release. premajor and prepatch work the same way.
inc (release, identifier, identifierBase) {
if (release.startsWith('pre')) {
if (!identifier && identifierBase === false) {
throw new Error('invalid increment argument: identifier is empty')
}
// Avoid an invalid semver results
if (identifier) {
const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE])
if (!match || match[1] !== identifier) {
throw new Error(`invalid identifier: ${identifier}`)
}
}
}
switch (release) {
case 'premajor':
this.prerelease.length = 0
this.patch = 0
this.minor = 0
this.major++
this.inc('pre', identifier, identifierBase)
break
case 'preminor':
this.prerelease.length = 0
this.patch = 0
this.minor++
this.inc('pre', identifier, identifierBase)
break
case 'prepatch':
// If this is already a prerelease, it will bump to the next version
// drop any prereleases that might already exist, since they are not
// relevant at this point.
this.prerelease.length = 0
this.inc('patch', identifier, identifierBase)
this.inc('pre', identifier, identifierBase)
break
// If the input is a non-prerelease version, this acts the same as
// prepatch.
case 'prerelease':
if (this.prerelease.length === 0) {
this.inc('patch', identifier, identifierBase)
}
this.inc('pre', identifier, identifierBase)
break
case 'release':
if (this.prerelease.length === 0) {
throw new Error(`version ${this.raw} is not a prerelease`)
}
this.prerelease.length = 0
break
case 'major':
// If this is a pre-major version, bump up to the same major version.
// Otherwise increment major.
// 1.0.0-5 bumps to 1.0.0
// 1.1.0 bumps to 2.0.0
if (
this.minor !== 0 ||
this.patch !== 0 ||
this.prerelease.length === 0
) {
this.major++
}
this.minor = 0
this.patch = 0
this.prerelease = []
break
case 'minor':
// If this is a pre-minor version, bump up to the same minor version.
// Otherwise increment minor.
// 1.2.0-5 bumps to 1.2.0
// 1.2.1 bumps to 1.3.0
if (this.patch !== 0 || this.prerelease.length === 0) {
this.minor++
}
this.patch = 0
this.prerelease = []
break
case 'patch':
// If this is not a pre-release version, it will increment the patch.
// If it is a pre-release it will bump up to the same patch version.
// 1.2.0-5 patches to 1.2.0
// 1.2.0 patches to 1.2.1
if (this.prerelease.length === 0) {
this.patch++
}
this.prerelease = []
break
// This probably shouldn't be used publicly.
// 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
case 'pre': {
const base = Number(identifierBase) ? 1 : 0
if (this.prerelease.length === 0) {
this.prerelease = [base]
} else {
let i = this.prerelease.length
while (--i >= 0) {
if (typeof this.prerelease[i] === 'number') {
this.prerelease[i]++
i = -2
}
}
if (i === -1) {
// didn't increment anything
if (identifier === this.prerelease.join('.') && identifierBase === false) {
throw new Error('invalid increment argument: identifier already exists')
}
this.prerelease.push(base)
}
}
if (identifier) {
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
let prerelease = [identifier, base]
if (identifierBase === false) {
prerelease = [identifier]
}
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) {
this.prerelease = prerelease
}
} else {
this.prerelease = prerelease
}
}
break
}
default:
throw new Error(`invalid increment argument: ${release}`)
}
this.raw = this.format()
if (this.build.length) {
this.raw += `+${this.build.join('.')}`
}
return this
}
}
module.exports = SemVer

View File

@@ -0,0 +1,177 @@
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var createError = require('http-errors')
var debug = require('debug')('body-parser:urlencoded')
var isFinished = require('on-finished').isFinished
var read = require('../read')
var typeis = require('type-is')
var qs = require('qs')
var { getCharset, normalizeOptions } = require('../utils')
/**
* Module exports.
*/
module.exports = urlencoded
/**
* Create a middleware to parse urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function urlencoded (options) {
var { inflate, limit, verify, shouldParse } = normalizeOptions(options, 'application/x-www-form-urlencoded')
var defaultCharset = options?.defaultCharset || 'utf-8'
if (defaultCharset !== 'utf-8' && defaultCharset !== 'iso-8859-1') {
throw new TypeError('option defaultCharset must be either utf-8 or iso-8859-1')
}
// create the appropriate query parser
var queryparse = createQueryParser(options)
function parse (body, encoding) {
return body.length
? queryparse(body, encoding)
: {}
}
return function urlencodedParser (req, res, next) {
if (isFinished(req)) {
debug('body already parsed')
next()
return
}
if (!('body' in req)) {
req.body = undefined
}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// assert charset
var charset = getCharset(req) || defaultCharset
if (charset !== 'utf-8' && charset !== 'iso-8859-1') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
charset: charset,
type: 'charset.unsupported'
}))
return
}
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate,
limit,
verify
})
}
}
/**
* Get the extended query parser.
*
* @param {object} options
*/
function createQueryParser (options) {
var extended = Boolean(options?.extended)
var 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
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
}
if (isNaN(depth) || depth < 0) {
throw new TypeError('option depth must be a zero or a positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse (body, encoding) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters', {
type: 'parameters.too.many'
})
}
var arrayLimit = extended ? Math.max(100, paramCount) : 0
debug('parse ' + (extended ? 'extended ' : '') + 'urlencoding')
try {
return qs.parse(body, {
allowPrototypes: true,
arrayLimit: arrayLimit,
depth: depth,
charsetSentinel: charsetSentinel,
interpretNumericEntities: interpretNumericEntities,
charset: encoding,
parameterLimit: parameterLimit,
strictDepth: true
})
} catch (err) {
if (err instanceof RangeError) {
throw createError(400, 'The input exceeded the depth', {
type: 'querystring.parse.rangeError'
})
} else {
throw err
}
}
}
}
/**
* Count the number of parameters, stopping once limit reached
*
* @param {string} body
* @param {number} limit
* @api private
*/
function parameterCount (body, limit) {
var len = body.split('&').length
return len > limit ? undefined : len - 1
}

View File

@@ -0,0 +1,40 @@
# hasown <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][npm-badge-png]][package-url]
A robust, ES3 compatible, "has own property" predicate.
## Example
```js
const assert = require('assert');
const hasOwn = require('hasown');
assert.equal(hasOwn({}, 'toString'), false);
assert.equal(hasOwn([], 'length'), true);
assert.equal(hasOwn({ a: 42 }, 'a'), true);
```
## Tests
Simply clone the repo, `npm install`, and run `npm test`
[package-url]: https://npmjs.org/package/hasown
[npm-version-svg]: https://versionbadg.es/inspect-js/hasown.svg
[deps-svg]: https://david-dm.org/inspect-js/hasOwn.svg
[deps-url]: https://david-dm.org/inspect-js/hasOwn
[dev-deps-svg]: https://david-dm.org/inspect-js/hasOwn/dev-status.svg
[dev-deps-url]: https://david-dm.org/inspect-js/hasOwn#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/hasown.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/hasown.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/hasown.svg
[downloads-url]: https://npm-stat.com/charts.html?package=hasown
[codecov-image]: https://codecov.io/gh/inspect-js/hasOwn/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/inspect-js/hasOwn/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/hasOwn
[actions-url]: https://github.com/inspect-js/hasOwn/actions

View File

@@ -0,0 +1,10 @@
{
"root": true,
"extends": "@ljharb",
"rules": {
"id-length": "off",
"sort-keys": "off",
},
}

View File

@@ -0,0 +1,49 @@
{
"name": "body-parser",
"description": "Node.js body parsing middleware",
"version": "2.2.0",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
],
"license": "MIT",
"repository": "expressjs/body-parser",
"dependencies": {
"bytes": "^3.1.2",
"content-type": "^1.0.5",
"debug": "^4.4.0",
"http-errors": "^2.0.0",
"iconv-lite": "^0.6.3",
"on-finished": "^2.4.1",
"qs": "^6.14.0",
"raw-body": "^3.0.0",
"type-is": "^2.0.0"
},
"devDependencies": {
"eslint": "8.34.0",
"eslint-config-standard": "14.1.1",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-markdown": "3.0.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-standard": "4.1.0",
"mocha": "^11.1.0",
"nyc": "^17.1.0",
"supertest": "^7.0.0"
},
"files": [
"lib/",
"LICENSE",
"HISTORY.md",
"index.js"
],
"engines": {
"node": ">=18"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks test/",
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}

View File

@@ -0,0 +1,5 @@
declare function gOPD<O extends object, K extends keyof O>(obj: O, prop: K): PropertyDescriptor | undefined;
declare const fn: typeof gOPD | undefined | null;
export = fn;

View File

@@ -0,0 +1,54 @@
'use strict'
const eq = require('./eq')
const neq = require('./neq')
const gt = require('./gt')
const gte = require('./gte')
const lt = require('./lt')
const lte = require('./lte')
const cmp = (a, op, b, loose) => {
switch (op) {
case '===':
if (typeof a === 'object') {
a = a.version
}
if (typeof b === 'object') {
b = b.version
}
return a === b
case '!==':
if (typeof a === 'object') {
a = a.version
}
if (typeof b === 'object') {
b = b.version
}
return a !== b
case '':
case '=':
case '==':
return eq(a, b, loose)
case '!=':
return neq(a, b, loose)
case '>':
return gt(a, b, loose)
case '>=':
return gte(a, b, loose)
case '<':
return lt(a, b, loose)
case '<=':
return lte(a, b, loose)
default:
throw new TypeError(`Invalid operator: ${op}`)
}
}
module.exports = cmp

View File

@@ -0,0 +1,64 @@
type RemoveFromTuple<
Tuple extends readonly unknown[],
RemoveCount extends number,
Index extends 1[] = []
> = Index["length"] extends RemoveCount
? Tuple
: Tuple extends [infer First, ...infer Rest]
? RemoveFromTuple<Rest, RemoveCount, [...Index, 1]>
: Tuple;
type ConcatTuples<
Prefix extends readonly unknown[],
Suffix extends readonly unknown[]
> = [...Prefix, ...Suffix];
type ExtractFunctionParams<T> = T extends (this: infer TThis, ...args: infer P extends readonly unknown[]) => infer R
? { thisArg: TThis; params: P; returnType: R }
: never;
type BindFunction<
T extends (this: any, ...args: any[]) => any,
TThis,
TBoundArgs extends readonly unknown[],
ReceiverBound extends boolean
> = ExtractFunctionParams<T> extends {
thisArg: infer OrigThis;
params: infer P extends readonly unknown[];
returnType: infer R;
}
? ReceiverBound extends true
? (...args: RemoveFromTuple<P, Extract<TBoundArgs["length"], number>>) => R extends [OrigThis, ...infer Rest]
? [TThis, ...Rest] // Replace `this` with `thisArg`
: R
: <U, RemainingArgs extends RemoveFromTuple<P, Extract<TBoundArgs["length"], number>>>(
thisArg: U,
...args: RemainingArgs
) => R extends [OrigThis, ...infer Rest]
? [U, ...ConcatTuples<TBoundArgs, Rest>] // Preserve bound args in return type
: R
: never;
declare function callBind<
const T extends (this: any, ...args: any[]) => any,
Extracted extends ExtractFunctionParams<T>,
const TBoundArgs extends Partial<Extracted["params"]> & readonly unknown[],
const TThis extends Extracted["thisArg"]
>(
args: [fn: T, thisArg: TThis, ...boundArgs: TBoundArgs]
): BindFunction<T, TThis, TBoundArgs, true>;
declare function callBind<
const T extends (this: any, ...args: any[]) => any,
Extracted extends ExtractFunctionParams<T>,
const TBoundArgs extends Partial<Extracted["params"]> & readonly unknown[]
>(
args: [fn: T, ...boundArgs: TBoundArgs]
): BindFunction<T, Extracted["thisArg"], TBoundArgs, false>;
declare function callBind<const TArgs extends readonly unknown[]>(
args: [fn: Exclude<TArgs[0], Function>, ...rest: TArgs]
): never;
// export as namespace callBind;
export = callBind;

View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/es-errors
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with a single custom sponsorship URL