This commit is contained in:
2026-03-03 15:23:00 +00:00
parent 5e3726de39
commit 8e223bfbec
3689 changed files with 955330 additions and 1011 deletions

24
node_modules/express/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,24 @@
(The MIT License)
Copyright (c) 2009-2014 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2013-2014 Roman Shtylman <shtylman+expressjs@gmail.com>
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

276
node_modules/express/Readme.md generated vendored Normal file
View File

@@ -0,0 +1,276 @@
[![Express Logo](https://i.cloudup.com/zfY6lL7eFa-3000x3000.png)](https://expressjs.com/)
**Fast, unopinionated, minimalist web framework for [Node.js](https://nodejs.org).**
**This project has a [Code of Conduct].**
## Table of contents
- [Table of contents](#table-of-contents)
- [Installation](#installation)
- [Features](#features)
- [Docs \& Community](#docs--community)
- [Quick Start](#quick-start)
- [Philosophy](#philosophy)
- [Examples](#examples)
- [Contributing](#contributing)
- [Security Issues](#security-issues)
- [Running Tests](#running-tests)
- [Current project team members](#current-project-team-members)
- [TC (Technical Committee)](#tc-technical-committee)
- [TC emeriti members](#tc-emeriti-members)
- [Triagers](#triagers)
- [Emeritus Triagers](#emeritus-triagers)
- [License](#license)
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-downloads-url]
[![Linux Build][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
```js
import express from 'express'
const app = express()
app.get('/', (req, res) => {
res.send('Hello World')
})
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000')
})
```
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/).
Before installing, [download and install Node.js](https://nodejs.org/en/download/).
Node.js 18 or higher is required.
If this is a brand new project, make sure to create a `package.json` first with
the [`npm init` command](https://docs.npmjs.com/creating-a-package-json-file).
Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```bash
npm install express
```
Follow [our installing guide](https://expressjs.com/en/starter/installing.html)
for more information.
## Features
* Robust routing
* Focus on high performance
* Super-high test coverage
* HTTP helpers (redirection, caching, etc)
* View system supporting 14+ template engines
* Content negotiation
* Executable for generating applications quickly
## Docs & Community
* [Website and Documentation](https://expressjs.com/) - [[website repo](https://github.com/expressjs/expressjs.com)]
* [GitHub Organization](https://github.com/expressjs) for Official Middleware & Modules
* [Github Discussions](https://github.com/expressjs/discussions) for discussion on the development and usage of Express
**PROTIP** Be sure to read the [migration guide to v5](https://expressjs.com/en/guide/migrating-5)
## Quick Start
The quickest way to get started with express is to utilize the executable [`express(1)`](https://github.com/expressjs/generator) to generate an application as shown below:
Install the executable. The executable's major version will match Express's:
```bash
npm install -g express-generator@4
```
Create the app:
```bash
express /tmp/foo && cd /tmp/foo
```
Install dependencies:
```bash
npm install
```
Start the server:
```bash
npm start
```
View the website at: http://localhost:3000
## Philosophy
The Express philosophy is to provide small, robust tooling for HTTP servers, making
it a great solution for single page applications, websites, hybrids, or public
HTTP APIs.
Express does not force you to use any specific ORM or template engine. With support for over
14 template engines via [@ladjs/consolidate](https://github.com/ladjs/consolidate),
you can quickly craft your perfect framework.
## Examples
To view the examples, clone the Express repository:
```bash
git clone https://github.com/expressjs/express.git --depth 1 && cd express
```
Then install the dependencies:
```bash
npm install
```
Then run whichever example you want:
```bash
node examples/content-negotiation
```
## Contributing
The Express.js project welcomes all constructive contributions. Contributions take many forms,
from code for bug fixes and enhancements, to additions and fixes to documentation, additional
tests, triaging incoming pull requests and issues, and more!
See the [Contributing Guide] for more technical details on contributing.
### Security Issues
If you discover a security vulnerability in Express, please see [Security Policies and Procedures](SECURITY.md).
### Running Tests
To run the test suite, first install the dependencies:
```bash
npm install
```
Then run `npm test`:
```bash
npm test
```
## Current project team members
For information about the governance of the express.js project, see [GOVERNANCE.md](https://github.com/expressjs/discussions/blob/HEAD/docs/GOVERNANCE.md).
The original author of Express is [TJ Holowaychuk](https://github.com/tj)
[List of all contributors](https://github.com/expressjs/express/graphs/contributors)
### TC (Technical Committee)
* [UlisesGascon](https://github.com/UlisesGascon) - **Ulises Gascón** (he/him)
* [jonchurch](https://github.com/jonchurch) - **Jon Church**
* [wesleytodd](https://github.com/wesleytodd) - **Wes Todd**
* [LinusU](https://github.com/LinusU) - **Linus Unnebäck**
* [blakeembrey](https://github.com/blakeembrey) - **Blake Embrey**
* [sheplu](https://github.com/sheplu) - **Jean Burellier**
* [crandmck](https://github.com/crandmck) - **Rand McKinney**
* [ctcpip](https://github.com/ctcpip) - **Chris de Almeida**
<details>
<summary>TC emeriti members</summary>
#### TC emeriti members
* [dougwilson](https://github.com/dougwilson) - **Douglas Wilson**
* [hacksparrow](https://github.com/hacksparrow) - **Hage Yaapa**
* [jonathanong](https://github.com/jonathanong) - **jongleberry**
* [niftylettuce](https://github.com/niftylettuce) - **niftylettuce**
* [troygoode](https://github.com/troygoode) - **Troy Goode**
</details>
### Triagers
* [aravindvnair99](https://github.com/aravindvnair99) - **Aravind Nair**
* [bjohansebas](https://github.com/bjohansebas) - **Sebastian Beltran**
* [carpasse](https://github.com/carpasse) - **Carlos Serrano**
* [CBID2](https://github.com/CBID2) - **Christine Belzie**
* [UlisesGascon](https://github.com/UlisesGascon) - **Ulises Gascón** (he/him)
* [IamLizu](https://github.com/IamLizu) - **S M Mahmudul Hasan** (he/him)
* [Phillip9587](https://github.com/Phillip9587) - **Phillip Barta**
* [efekrskl](https://github.com/efekrskl) - **Efe Karasakal**
<details>
<summary>Triagers emeriti members</summary>
#### Emeritus Triagers
* [AuggieH](https://github.com/AuggieH) - **Auggie Hudak**
* [G-Rath](https://github.com/G-Rath) - **Gareth Jones**
* [MohammadXroid](https://github.com/MohammadXroid) - **Mohammad Ayashi**
* [NawafSwe](https://github.com/NawafSwe) - **Nawaf Alsharqi**
* [NotMoni](https://github.com/NotMoni) - **Moni**
* [VigneshMurugan](https://github.com/VigneshMurugan) - **Vignesh Murugan**
* [davidmashe](https://github.com/davidmashe) - **David Ashe**
* [digitaIfabric](https://github.com/digitaIfabric) - **David**
* [e-l-i-s-e](https://github.com/e-l-i-s-e) - **Elise Bonner**
* [fed135](https://github.com/fed135) - **Frederic Charette**
* [firmanJS](https://github.com/firmanJS) - **Firman Abdul Hakim**
* [getspooky](https://github.com/getspooky) - **Yasser Ameur**
* [ghinks](https://github.com/ghinks) - **Glenn**
* [ghousemohamed](https://github.com/ghousemohamed) - **Ghouse Mohamed**
* [gireeshpunathil](https://github.com/gireeshpunathil) - **Gireesh Punathil**
* [jake32321](https://github.com/jake32321) - **Jake Reed**
* [jonchurch](https://github.com/jonchurch) - **Jon Church**
* [lekanikotun](https://github.com/lekanikotun) - **Troy Goode**
* [marsonya](https://github.com/marsonya) - **Lekan Ikotun**
* [mastermatt](https://github.com/mastermatt) - **Matt R. Wilson**
* [maxakuru](https://github.com/maxakuru) - **Max Edell**
* [mlrawlings](https://github.com/mlrawlings) - **Michael Rawlings**
* [rodion-arr](https://github.com/rodion-arr) - **Rodion Abdurakhimov**
* [sheplu](https://github.com/sheplu) - **Jean Burellier**
* [tarunyadav1](https://github.com/tarunyadav1) - **Tarun yadav**
* [tunniclm](https://github.com/tunniclm) - **Mike Tunnicliffe**
* [enyoghasim](https://github.com/enyoghasim) - **David Enyoghasim**
* [0ss](https://github.com/0ss) - **Salah**
* [import-brain](https://github.com/import-brain) - **Eric Cheng** (he/him)
* [dakshkhetan](https://github.com/dakshkhetan) - **Daksh Khetan** (he/him)
* [lucasraziel](https://github.com/lucasraziel) - **Lucas Soares Do Rego**
* [mertcanaltin](https://github.com/mertcanaltin) - **Mert Can Altin**
* [dpopp07](https://github.com/dpopp07) - **Dustin Popp**
* [Sushmeet](https://github.com/Sushmeet) - **Sushmeet Sunger**
* [3imed-jaberi](https://github.com/3imed-jaberi) - **Imed Jaberi**
</details>
## License
[MIT](LICENSE)
[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/express?branch=master
[coveralls-url]: https://coveralls.io/r/expressjs/express?branch=master
[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/express/ci.yml?branch=master&label=ci
[github-actions-ci-url]: https://github.com/expressjs/express/actions/workflows/ci.yml
[npm-downloads-image]: https://img.shields.io/npm/dm/express
[npm-downloads-url]: https://npmcharts.com/compare/express?minimal=true
[npm-url]: https://npmjs.org/package/express
[npm-version-image]: https://img.shields.io/npm/v/express
[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/express/badge
[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/express
[Code of Conduct]: https://github.com/expressjs/.github/blob/HEAD/CODE_OF_CONDUCT.md
[Contributing Guide]: https://github.com/expressjs/.github/blob/HEAD/CONTRIBUTING.md

11
node_modules/express/index.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2013 Roman Shtylman
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
module.exports = require('./lib/express');

631
node_modules/express/lib/application.js generated vendored Normal file
View File

@@ -0,0 +1,631 @@
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2013 Roman Shtylman
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
* @private
*/
var finalhandler = require('finalhandler');
var debug = require('debug')('express:application');
var View = require('./view');
var http = require('node:http');
var methods = require('./utils').methods;
var compileETag = require('./utils').compileETag;
var compileQueryParser = require('./utils').compileQueryParser;
var compileTrust = require('./utils').compileTrust;
var resolve = require('node:path').resolve;
var once = require('once')
var Router = require('router');
/**
* Module variables.
* @private
*/
var slice = Array.prototype.slice;
var flatten = Array.prototype.flat;
/**
* Application prototype.
*/
var app = exports = module.exports = {};
/**
* Variable for trust proxy inheritance back-compat
* @private
*/
var trustProxyDefaultSymbol = '@@symbol:trust_proxy_default';
/**
* Initialize the server.
*
* - setup default configuration
* - setup default middleware
* - setup route reflection methods
*
* @private
*/
app.init = function init() {
var router = null;
this.cache = Object.create(null);
this.engines = Object.create(null);
this.settings = Object.create(null);
this.defaultConfiguration();
// Setup getting to lazily add base router
Object.defineProperty(this, 'router', {
configurable: true,
enumerable: true,
get: function getrouter() {
if (router === null) {
router = new Router({
caseSensitive: this.enabled('case sensitive routing'),
strict: this.enabled('strict routing')
});
}
return router;
}
});
};
/**
* Initialize application configuration.
* @private
*/
app.defaultConfiguration = function defaultConfiguration() {
var env = process.env.NODE_ENV || 'development';
// default settings
this.enable('x-powered-by');
this.set('etag', 'weak');
this.set('env', env);
this.set('query parser', 'simple')
this.set('subdomain offset', 2);
this.set('trust proxy', false);
// trust proxy inherit back-compat
Object.defineProperty(this.settings, trustProxyDefaultSymbol, {
configurable: true,
value: true
});
debug('booting in %s mode', env);
this.on('mount', function onmount(parent) {
// inherit trust proxy
if (this.settings[trustProxyDefaultSymbol] === true
&& typeof parent.settings['trust proxy fn'] === 'function') {
delete this.settings['trust proxy'];
delete this.settings['trust proxy fn'];
}
// inherit protos
Object.setPrototypeOf(this.request, parent.request)
Object.setPrototypeOf(this.response, parent.response)
Object.setPrototypeOf(this.engines, parent.engines)
Object.setPrototypeOf(this.settings, parent.settings)
});
// setup locals
this.locals = Object.create(null);
// top-most app is mounted at /
this.mountpath = '/';
// default locals
this.locals.settings = this.settings;
// default configuration
this.set('view', View);
this.set('views', resolve('views'));
this.set('jsonp callback name', 'callback');
if (env === 'production') {
this.enable('view cache');
}
};
/**
* Dispatch a req, res pair into the application. Starts pipeline processing.
*
* If no callback is provided, then default error handlers will respond
* in the event of an error bubbling through the stack.
*
* @private
*/
app.handle = function handle(req, res, callback) {
// final handler
var done = callback || finalhandler(req, res, {
env: this.get('env'),
onerror: logerror.bind(this)
});
// set powered by header
if (this.enabled('x-powered-by')) {
res.setHeader('X-Powered-By', 'Express');
}
// set circular references
req.res = res;
res.req = req;
// alter the prototypes
Object.setPrototypeOf(req, this.request)
Object.setPrototypeOf(res, this.response)
// setup locals
if (!res.locals) {
res.locals = Object.create(null);
}
this.router.handle(req, res, done);
};
/**
* Proxy `Router#use()` to add middleware to the app router.
* See Router#use() documentation for details.
*
* If the _fn_ parameter is an express app, then it will be
* mounted at the _route_ specified.
*
* @public
*/
app.use = function use(fn) {
var offset = 0;
var path = '/';
// default path to '/'
// disambiguate app.use([fn])
if (typeof fn !== 'function') {
var arg = fn;
while (Array.isArray(arg) && arg.length !== 0) {
arg = arg[0];
}
// first arg is the path
if (typeof arg !== 'function') {
offset = 1;
path = fn;
}
}
var fns = flatten.call(slice.call(arguments, offset), Infinity);
if (fns.length === 0) {
throw new TypeError('app.use() requires a middleware function')
}
// get router
var router = this.router;
fns.forEach(function (fn) {
// non-express app
if (!fn || !fn.handle || !fn.set) {
return router.use(path, fn);
}
debug('.use app under %s', path);
fn.mountpath = path;
fn.parent = this;
// restore .app property on req and res
router.use(path, function mounted_app(req, res, next) {
var orig = req.app;
fn.handle(req, res, function (err) {
Object.setPrototypeOf(req, orig.request)
Object.setPrototypeOf(res, orig.response)
next(err);
});
});
// mounted an app
fn.emit('mount', this);
}, this);
return this;
};
/**
* Proxy to the app `Router#route()`
* Returns a new `Route` instance for the _path_.
*
* Routes are isolated middleware stacks for specific paths.
* See the Route api docs for details.
*
* @public
*/
app.route = function route(path) {
return this.router.route(path);
};
/**
* Register the given template engine callback `fn`
* as `ext`.
*
* By default will `require()` the engine based on the
* file extension. For example if you try to render
* a "foo.ejs" file Express will invoke the following internally:
*
* app.engine('ejs', require('ejs').__express);
*
* For engines that do not provide `.__express` out of the box,
* or if you wish to "map" a different extension to the template engine
* you may use this method. For example mapping the EJS template engine to
* ".html" files:
*
* app.engine('html', require('ejs').renderFile);
*
* In this case EJS provides a `.renderFile()` method with
* the same signature that Express expects: `(path, options, callback)`,
* though note that it aliases this method as `ejs.__express` internally
* so if you're using ".ejs" extensions you don't need to do anything.
*
* Some template engines do not follow this convention, the
* [Consolidate.js](https://github.com/tj/consolidate.js)
* library was created to map all of node's popular template
* engines to follow this convention, thus allowing them to
* work seamlessly within Express.
*
* @param {String} ext
* @param {Function} fn
* @return {app} for chaining
* @public
*/
app.engine = function engine(ext, fn) {
if (typeof fn !== 'function') {
throw new Error('callback function required');
}
// get file extension
var extension = ext[0] !== '.'
? '.' + ext
: ext;
// store engine
this.engines[extension] = fn;
return this;
};
/**
* Proxy to `Router#param()` with one added api feature. The _name_ parameter
* can be an array of names.
*
* See the Router#param() docs for more details.
*
* @param {String|Array} name
* @param {Function} fn
* @return {app} for chaining
* @public
*/
app.param = function param(name, fn) {
if (Array.isArray(name)) {
for (var i = 0; i < name.length; i++) {
this.param(name[i], fn);
}
return this;
}
this.router.param(name, fn);
return this;
};
/**
* Assign `setting` to `val`, or return `setting`'s value.
*
* app.set('foo', 'bar');
* app.set('foo');
* // => "bar"
*
* Mounted servers inherit their parent server's settings.
*
* @param {String} setting
* @param {*} [val]
* @return {Server} for chaining
* @public
*/
app.set = function set(setting, val) {
if (arguments.length === 1) {
// app.get(setting)
return this.settings[setting];
}
debug('set "%s" to %o', setting, val);
// set value
this.settings[setting] = val;
// trigger matched settings
switch (setting) {
case 'etag':
this.set('etag fn', compileETag(val));
break;
case 'query parser':
this.set('query parser fn', compileQueryParser(val));
break;
case 'trust proxy':
this.set('trust proxy fn', compileTrust(val));
// trust proxy inherit back-compat
Object.defineProperty(this.settings, trustProxyDefaultSymbol, {
configurable: true,
value: false
});
break;
}
return this;
};
/**
* Return the app's absolute pathname
* based on the parent(s) that have
* mounted it.
*
* For example if the application was
* mounted as "/admin", which itself
* was mounted as "/blog" then the
* return value would be "/blog/admin".
*
* @return {String}
* @private
*/
app.path = function path() {
return this.parent
? this.parent.path() + this.mountpath
: '';
};
/**
* Check if `setting` is enabled (truthy).
*
* app.enabled('foo')
* // => false
*
* app.enable('foo')
* app.enabled('foo')
* // => true
*
* @param {String} setting
* @return {Boolean}
* @public
*/
app.enabled = function enabled(setting) {
return Boolean(this.set(setting));
};
/**
* Check if `setting` is disabled.
*
* app.disabled('foo')
* // => true
*
* app.enable('foo')
* app.disabled('foo')
* // => false
*
* @param {String} setting
* @return {Boolean}
* @public
*/
app.disabled = function disabled(setting) {
return !this.set(setting);
};
/**
* Enable `setting`.
*
* @param {String} setting
* @return {app} for chaining
* @public
*/
app.enable = function enable(setting) {
return this.set(setting, true);
};
/**
* Disable `setting`.
*
* @param {String} setting
* @return {app} for chaining
* @public
*/
app.disable = function disable(setting) {
return this.set(setting, false);
};
/**
* Delegate `.VERB(...)` calls to `router.VERB(...)`.
*/
methods.forEach(function (method) {
app[method] = function (path) {
if (method === 'get' && arguments.length === 1) {
// app.get(setting)
return this.set(path);
}
var route = this.route(path);
route[method].apply(route, slice.call(arguments, 1));
return this;
};
});
/**
* Special-cased "all" method, applying the given route `path`,
* middleware, and callback to _every_ HTTP method.
*
* @param {String} path
* @param {Function} ...
* @return {app} for chaining
* @public
*/
app.all = function all(path) {
var route = this.route(path);
var args = slice.call(arguments, 1);
for (var i = 0; i < methods.length; i++) {
route[methods[i]].apply(route, args);
}
return this;
};
/**
* Render the given view `name` name with `options`
* and a callback accepting an error and the
* rendered template string.
*
* Example:
*
* app.render('email', { name: 'Tobi' }, function(err, html){
* // ...
* })
*
* @param {String} name
* @param {Object|Function} options or fn
* @param {Function} callback
* @public
*/
app.render = function render(name, options, callback) {
var cache = this.cache;
var done = callback;
var engines = this.engines;
var opts = options;
var view;
// support callback function as second arg
if (typeof options === 'function') {
done = options;
opts = {};
}
// merge options
var renderOptions = { ...this.locals, ...opts._locals, ...opts };
// set .cache unless explicitly provided
if (renderOptions.cache == null) {
renderOptions.cache = this.enabled('view cache');
}
// primed cache
if (renderOptions.cache) {
view = cache[name];
}
// view
if (!view) {
var View = this.get('view');
view = new View(name, {
defaultEngine: this.get('view engine'),
root: this.get('views'),
engines: engines
});
if (!view.path) {
var dirs = Array.isArray(view.root) && view.root.length > 1
? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"'
: 'directory "' + view.root + '"'
var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs);
err.view = view;
return done(err);
}
// prime the cache
if (renderOptions.cache) {
cache[name] = view;
}
}
// render
tryRender(view, renderOptions, done);
};
/**
* Listen for connections.
*
* A node `http.Server` is returned, with this
* application (which is a `Function`) as its
* callback. If you wish to create both an HTTP
* and HTTPS server you may do so with the "http"
* and "https" modules as shown here:
*
* var http = require('node:http')
* , https = require('node:https')
* , express = require('express')
* , app = express();
*
* http.createServer(app).listen(80);
* https.createServer({ ... }, app).listen(443);
*
* @return {http.Server}
* @public
*/
app.listen = function listen() {
var server = http.createServer(this)
var args = slice.call(arguments)
if (typeof args[args.length - 1] === 'function') {
var done = args[args.length - 1] = once(args[args.length - 1])
server.once('error', done)
}
return server.listen.apply(server, args)
}
/**
* Log error using console.error.
*
* @param {Error} err
* @private
*/
function logerror(err) {
/* istanbul ignore next */
if (this.get('env') !== 'test') console.error(err.stack || err.toString());
}
/**
* Try rendering a view.
* @private
*/
function tryRender(view, options, callback) {
try {
view.render(options, callback);
} catch (err) {
callback(err);
}
}

81
node_modules/express/lib/express.js generated vendored Normal file
View File

@@ -0,0 +1,81 @@
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2013 Roman Shtylman
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var bodyParser = require('body-parser')
var EventEmitter = require('node:events').EventEmitter;
var mixin = require('merge-descriptors');
var proto = require('./application');
var Router = require('router');
var req = require('./request');
var res = require('./response');
/**
* Expose `createApplication()`.
*/
exports = module.exports = createApplication;
/**
* Create an express application.
*
* @return {Function}
* @api public
*/
function createApplication() {
var app = function(req, res, next) {
app.handle(req, res, next);
};
mixin(app, EventEmitter.prototype, false);
mixin(app, proto, false);
// expose the prototype that will get set on requests
app.request = Object.create(req, {
app: { configurable: true, enumerable: true, writable: true, value: app }
})
// expose the prototype that will get set on responses
app.response = Object.create(res, {
app: { configurable: true, enumerable: true, writable: true, value: app }
})
app.init();
return app;
}
/**
* Expose the prototypes.
*/
exports.application = proto;
exports.request = req;
exports.response = res;
/**
* Expose constructors.
*/
exports.Route = Router.Route;
exports.Router = Router;
/**
* Expose middleware
*/
exports.json = bodyParser.json
exports.raw = bodyParser.raw
exports.static = require('serve-static');
exports.text = bodyParser.text
exports.urlencoded = bodyParser.urlencoded

514
node_modules/express/lib/request.js generated vendored Normal file
View File

@@ -0,0 +1,514 @@
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2013 Roman Shtylman
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
* @private
*/
var accepts = require('accepts');
var isIP = require('node:net').isIP;
var typeis = require('type-is');
var http = require('node:http');
var fresh = require('fresh');
var parseRange = require('range-parser');
var parse = require('parseurl');
var proxyaddr = require('proxy-addr');
/**
* Request prototype.
* @public
*/
var req = Object.create(http.IncomingMessage.prototype)
/**
* Module exports.
* @public
*/
module.exports = req
/**
* Return request header.
*
* The `Referrer` header field is special-cased,
* both `Referrer` and `Referer` are interchangeable.
*
* Examples:
*
* req.get('Content-Type');
* // => "text/plain"
*
* req.get('content-type');
* // => "text/plain"
*
* req.get('Something');
* // => undefined
*
* Aliased as `req.header()`.
*
* @param {String} name
* @return {String}
* @public
*/
req.get =
req.header = function header(name) {
if (!name) {
throw new TypeError('name argument is required to req.get');
}
if (typeof name !== 'string') {
throw new TypeError('name must be a string to req.get');
}
var lc = name.toLowerCase();
switch (lc) {
case 'referer':
case 'referrer':
return this.headers.referrer
|| this.headers.referer;
default:
return this.headers[lc];
}
};
/**
* To do: update docs.
*
* Check if the given `type(s)` is acceptable, returning
* the best match when true, otherwise `undefined`, in which
* case you should respond with 406 "Not Acceptable".
*
* The `type` value may be a single MIME type string
* such as "application/json", an extension name
* such as "json", a comma-delimited list such as "json, html, text/plain",
* an argument list such as `"json", "html", "text/plain"`,
* or an array `["json", "html", "text/plain"]`. When a list
* or array is given, the _best_ match, if any is returned.
*
* Examples:
*
* // Accept: text/html
* req.accepts('html');
* // => "html"
*
* // Accept: text/*, application/json
* req.accepts('html');
* // => "html"
* req.accepts('text/html');
* // => "text/html"
* req.accepts('json, text');
* // => "json"
* req.accepts('application/json');
* // => "application/json"
*
* // Accept: text/*, application/json
* req.accepts('image/png');
* req.accepts('png');
* // => undefined
*
* // Accept: text/*;q=.5, application/json
* req.accepts(['html', 'json']);
* req.accepts('html', 'json');
* req.accepts('html, json');
* // => "json"
*
* @param {String|Array} type(s)
* @return {String|Array|Boolean}
* @public
*/
req.accepts = function(){
var accept = accepts(this);
return accept.types.apply(accept, arguments);
};
/**
* Check if the given `encoding`s are accepted.
*
* @param {String} ...encoding
* @return {String|Array}
* @public
*/
req.acceptsEncodings = function(){
var accept = accepts(this);
return accept.encodings.apply(accept, arguments);
};
/**
* Check if the given `charset`s are acceptable,
* otherwise you should respond with 406 "Not Acceptable".
*
* @param {String} ...charset
* @return {String|Array}
* @public
*/
req.acceptsCharsets = function(){
var accept = accepts(this);
return accept.charsets.apply(accept, arguments);
};
/**
* Check if the given `lang`s are acceptable,
* otherwise you should respond with 406 "Not Acceptable".
*
* @param {String} ...lang
* @return {String|Array}
* @public
*/
req.acceptsLanguages = function(...languages) {
return accepts(this).languages(...languages);
};
/**
* Parse Range header field, capping to the given `size`.
*
* Unspecified ranges such as "0-" require knowledge of your resource length. In
* the case of a byte range this is of course the total number of bytes. If the
* Range header field is not given `undefined` is returned, `-1` when unsatisfiable,
* and `-2` when syntactically invalid.
*
* When ranges are returned, the array has a "type" property which is the type of
* range that is required (most commonly, "bytes"). Each array element is an object
* with a "start" and "end" property for the portion of the range.
*
* The "combine" option can be set to `true` and overlapping & adjacent ranges
* will be combined into a single range.
*
* NOTE: remember that ranges are inclusive, so for example "Range: users=0-3"
* should respond with 4 users when available, not 3.
*
* @param {number} size
* @param {object} [options]
* @param {boolean} [options.combine=false]
* @return {number|array}
* @public
*/
req.range = function range(size, options) {
var range = this.get('Range');
if (!range) return;
return parseRange(size, range, options);
};
/**
* Parse the query string of `req.url`.
*
* This uses the "query parser" setting to parse the raw
* string into an object.
*
* @return {String}
* @api public
*/
defineGetter(req, 'query', function query(){
var queryparse = this.app.get('query parser fn');
if (!queryparse) {
// parsing is disabled
return Object.create(null);
}
var querystring = parse(this).query;
return queryparse(querystring);
});
/**
* Check if the incoming request contains the "Content-Type"
* header field, and it contains the given mime `type`.
*
* Examples:
*
* // With Content-Type: text/html; charset=utf-8
* req.is('html');
* req.is('text/html');
* req.is('text/*');
* // => true
*
* // When Content-Type is application/json
* req.is('json');
* req.is('application/json');
* req.is('application/*');
* // => true
*
* req.is('html');
* // => false
*
* @param {String|Array} types...
* @return {String|false|null}
* @public
*/
req.is = function is(types) {
var arr = types;
// support flattened arguments
if (!Array.isArray(types)) {
arr = new Array(arguments.length);
for (var i = 0; i < arr.length; i++) {
arr[i] = arguments[i];
}
}
return typeis(this, arr);
};
/**
* Return the protocol string "http" or "https"
* when requested with TLS. When the "trust proxy"
* setting trusts the socket address, the
* "X-Forwarded-Proto" header field will be trusted
* and used if present.
*
* If you're running behind a reverse proxy that
* supplies https for you this may be enabled.
*
* @return {String}
* @public
*/
defineGetter(req, 'protocol', function protocol(){
var proto = this.socket.encrypted
? 'https'
: 'http';
var trust = this.app.get('trust proxy fn');
if (!trust(this.socket.remoteAddress, 0)) {
return proto;
}
// Note: X-Forwarded-Proto is normally only ever a
// single value, but this is to be safe.
var header = this.get('X-Forwarded-Proto') || proto
var index = header.indexOf(',')
return index !== -1
? header.substring(0, index).trim()
: header.trim()
});
/**
* Short-hand for:
*
* req.protocol === 'https'
*
* @return {Boolean}
* @public
*/
defineGetter(req, 'secure', function secure(){
return this.protocol === 'https';
});
/**
* Return the remote address from the trusted proxy.
*
* The is the remote address on the socket unless
* "trust proxy" is set.
*
* @return {String}
* @public
*/
defineGetter(req, 'ip', function ip(){
var trust = this.app.get('trust proxy fn');
return proxyaddr(this, trust);
});
/**
* When "trust proxy" is set, trusted proxy addresses + client.
*
* For example if the value were "client, proxy1, proxy2"
* you would receive the array `["client", "proxy1", "proxy2"]`
* where "proxy2" is the furthest down-stream and "proxy1" and
* "proxy2" were trusted.
*
* @return {Array}
* @public
*/
defineGetter(req, 'ips', function ips() {
var trust = this.app.get('trust proxy fn');
var addrs = proxyaddr.all(this, trust);
// reverse the order (to farthest -> closest)
// and remove socket address
addrs.reverse().pop()
return addrs
});
/**
* Return subdomains as an array.
*
* Subdomains are the dot-separated parts of the host before the main domain of
* the app. By default, the domain of the app is assumed to be the last two
* parts of the host. This can be changed by setting "subdomain offset".
*
* For example, if the domain is "tobi.ferrets.example.com":
* If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`.
* If "subdomain offset" is 3, req.subdomains is `["tobi"]`.
*
* @return {Array}
* @public
*/
defineGetter(req, 'subdomains', function subdomains() {
var hostname = this.hostname;
if (!hostname) return [];
var offset = this.app.get('subdomain offset');
var subdomains = !isIP(hostname)
? hostname.split('.').reverse()
: [hostname];
return subdomains.slice(offset);
});
/**
* Short-hand for `url.parse(req.url).pathname`.
*
* @return {String}
* @public
*/
defineGetter(req, 'path', function path() {
return parse(this).pathname;
});
/**
* Parse the "Host" header field to a host.
*
* When the "trust proxy" setting trusts the socket
* address, the "X-Forwarded-Host" header field will
* be trusted.
*
* @return {String}
* @public
*/
defineGetter(req, 'host', function host(){
var trust = this.app.get('trust proxy fn');
var val = this.get('X-Forwarded-Host');
if (!val || !trust(this.socket.remoteAddress, 0)) {
val = this.get('Host');
} else if (val.indexOf(',') !== -1) {
// Note: X-Forwarded-Host is normally only ever a
// single value, but this is to be safe.
val = val.substring(0, val.indexOf(',')).trimRight()
}
return val || undefined;
});
/**
* Parse the "Host" header field to a hostname.
*
* When the "trust proxy" setting trusts the socket
* address, the "X-Forwarded-Host" header field will
* be trusted.
*
* @return {String}
* @api public
*/
defineGetter(req, 'hostname', function hostname(){
var host = this.host;
if (!host) return;
// IPv6 literal support
var offset = host[0] === '['
? host.indexOf(']') + 1
: 0;
var index = host.indexOf(':', offset);
return index !== -1
? host.substring(0, index)
: host;
});
/**
* Check if the request is fresh, aka
* Last-Modified or the ETag
* still match.
*
* @return {Boolean}
* @public
*/
defineGetter(req, 'fresh', function(){
var method = this.method;
var res = this.res
var status = res.statusCode
// GET or HEAD for weak freshness validation only
if ('GET' !== method && 'HEAD' !== method) return false;
// 2xx or 304 as per rfc2616 14.26
if ((status >= 200 && status < 300) || 304 === status) {
return fresh(this.headers, {
'etag': res.get('ETag'),
'last-modified': res.get('Last-Modified')
})
}
return false;
});
/**
* Check if the request is stale, aka
* "Last-Modified" and / or the "ETag" for the
* resource has changed.
*
* @return {Boolean}
* @public
*/
defineGetter(req, 'stale', function stale(){
return !this.fresh;
});
/**
* Check if the request was an _XMLHttpRequest_.
*
* @return {Boolean}
* @public
*/
defineGetter(req, 'xhr', function xhr(){
var val = this.get('X-Requested-With') || '';
return val.toLowerCase() === 'xmlhttprequest';
});
/**
* Helper function for creating a getter on an object.
*
* @param {Object} obj
* @param {String} name
* @param {Function} getter
* @private
*/
function defineGetter(obj, name, getter) {
Object.defineProperty(obj, name, {
configurable: true,
enumerable: true,
get: getter
});
}

1053
node_modules/express/lib/response.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

271
node_modules/express/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,271 @@
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
* @api private
*/
var { METHODS } = require('node:http');
var contentType = require('content-type');
var etag = require('etag');
var mime = require('mime-types')
var proxyaddr = require('proxy-addr');
var qs = require('qs');
var querystring = require('node:querystring');
const { Buffer } = require('node:buffer');
/**
* A list of lowercased HTTP methods that are supported by Node.js.
* @api private
*/
exports.methods = METHODS.map((method) => method.toLowerCase());
/**
* Return strong ETag for `body`.
*
* @param {String|Buffer} body
* @param {String} [encoding]
* @return {String}
* @api private
*/
exports.etag = createETagGenerator({ weak: false })
/**
* Return weak ETag for `body`.
*
* @param {String|Buffer} body
* @param {String} [encoding]
* @return {String}
* @api private
*/
exports.wetag = createETagGenerator({ weak: true })
/**
* Normalize the given `type`, for example "html" becomes "text/html".
*
* @param {String} type
* @return {Object}
* @api private
*/
exports.normalizeType = function(type){
return ~type.indexOf('/')
? acceptParams(type)
: { value: (mime.lookup(type) || 'application/octet-stream'), params: {} }
};
/**
* Normalize `types`, for example "html" becomes "text/html".
*
* @param {Array} types
* @return {Array}
* @api private
*/
exports.normalizeTypes = function(types) {
return types.map(exports.normalizeType);
};
/**
* Parse accept params `str` returning an
* object with `.value`, `.quality` and `.params`.
*
* @param {String} str
* @return {Object}
* @api private
*/
function acceptParams (str) {
var length = str.length;
var colonIndex = str.indexOf(';');
var index = colonIndex === -1 ? length : colonIndex;
var ret = { value: str.slice(0, index).trim(), quality: 1, params: {} };
while (index < length) {
var splitIndex = str.indexOf('=', index);
if (splitIndex === -1) break;
var colonIndex = str.indexOf(';', index);
var endIndex = colonIndex === -1 ? length : colonIndex;
if (splitIndex > endIndex) {
index = str.lastIndexOf(';', splitIndex - 1) + 1;
continue;
}
var key = str.slice(index, splitIndex).trim();
var value = str.slice(splitIndex + 1, endIndex).trim();
if (key === 'q') {
ret.quality = parseFloat(value);
} else {
ret.params[key] = value;
}
index = endIndex + 1;
}
return ret;
}
/**
* Compile "etag" value to function.
*
* @param {Boolean|String|Function} val
* @return {Function}
* @api private
*/
exports.compileETag = function(val) {
var fn;
if (typeof val === 'function') {
return val;
}
switch (val) {
case true:
case 'weak':
fn = exports.wetag;
break;
case false:
break;
case 'strong':
fn = exports.etag;
break;
default:
throw new TypeError('unknown value for etag function: ' + val);
}
return fn;
}
/**
* Compile "query parser" value to function.
*
* @param {String|Function} val
* @return {Function}
* @api private
*/
exports.compileQueryParser = function compileQueryParser(val) {
var fn;
if (typeof val === 'function') {
return val;
}
switch (val) {
case true:
case 'simple':
fn = querystring.parse;
break;
case false:
break;
case 'extended':
fn = parseExtendedQueryString;
break;
default:
throw new TypeError('unknown value for query parser function: ' + val);
}
return fn;
}
/**
* Compile "proxy trust" value to function.
*
* @param {Boolean|String|Number|Array|Function} val
* @return {Function}
* @api private
*/
exports.compileTrust = function(val) {
if (typeof val === 'function') return val;
if (val === true) {
// Support plain true/false
return function(){ return true };
}
if (typeof val === 'number') {
// Support trusting hop count
return function(a, i){ return i < val };
}
if (typeof val === 'string') {
// Support comma-separated values
val = val.split(',')
.map(function (v) { return v.trim() })
}
return proxyaddr.compile(val || []);
}
/**
* Set the charset in a given Content-Type string.
*
* @param {String} type
* @param {String} charset
* @return {String}
* @api private
*/
exports.setCharset = function setCharset(type, charset) {
if (!type || !charset) {
return type;
}
// parse type
var parsed = contentType.parse(type);
// set charset
parsed.parameters.charset = charset;
// format type
return contentType.format(parsed);
};
/**
* Create an ETag generator function, generating ETags with
* the given options.
*
* @param {object} options
* @return {function}
* @private
*/
function createETagGenerator (options) {
return function generateETag (body, encoding) {
var buf = !Buffer.isBuffer(body)
? Buffer.from(body, encoding)
: body
return etag(buf, options)
}
}
/**
* Parse an extended query string with qs.
*
* @param {String} str
* @return {Object}
* @private
*/
function parseExtendedQueryString(str) {
return qs.parse(str, {
allowPrototypes: true
});
}

205
node_modules/express/lib/view.js generated vendored Normal file
View File

@@ -0,0 +1,205 @@
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2013 Roman Shtylman
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
* @private
*/
var debug = require('debug')('express:view');
var path = require('node:path');
var fs = require('node:fs');
/**
* Module variables.
* @private
*/
var dirname = path.dirname;
var basename = path.basename;
var extname = path.extname;
var join = path.join;
var resolve = path.resolve;
/**
* Module exports.
* @public
*/
module.exports = View;
/**
* Initialize a new `View` with the given `name`.
*
* Options:
*
* - `defaultEngine` the default template engine name
* - `engines` template engine require() cache
* - `root` root path for view lookup
*
* @param {string} name
* @param {object} options
* @public
*/
function View(name, options) {
var opts = options || {};
this.defaultEngine = opts.defaultEngine;
this.ext = extname(name);
this.name = name;
this.root = opts.root;
if (!this.ext && !this.defaultEngine) {
throw new Error('No default engine was specified and no extension was provided.');
}
var fileName = name;
if (!this.ext) {
// get extension from default engine name
this.ext = this.defaultEngine[0] !== '.'
? '.' + this.defaultEngine
: this.defaultEngine;
fileName += this.ext;
}
if (!opts.engines[this.ext]) {
// load engine
var mod = this.ext.slice(1)
debug('require "%s"', mod)
// default engine export
var fn = require(mod).__express
if (typeof fn !== 'function') {
throw new Error('Module "' + mod + '" does not provide a view engine.')
}
opts.engines[this.ext] = fn
}
// store loaded engine
this.engine = opts.engines[this.ext];
// lookup path
this.path = this.lookup(fileName);
}
/**
* Lookup view by the given `name`
*
* @param {string} name
* @private
*/
View.prototype.lookup = function lookup(name) {
var path;
var roots = [].concat(this.root);
debug('lookup "%s"', name);
for (var i = 0; i < roots.length && !path; i++) {
var root = roots[i];
// resolve the path
var loc = resolve(root, name);
var dir = dirname(loc);
var file = basename(loc);
// resolve the file
path = this.resolve(dir, file);
}
return path;
};
/**
* Render with the given options.
*
* @param {object} options
* @param {function} callback
* @private
*/
View.prototype.render = function render(options, callback) {
var sync = true;
debug('render "%s"', this.path);
// render, normalizing sync callbacks
this.engine(this.path, options, function onRender() {
if (!sync) {
return callback.apply(this, arguments);
}
// copy arguments
var args = new Array(arguments.length);
var cntx = this;
for (var i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
// force callback to be async
return process.nextTick(function renderTick() {
return callback.apply(cntx, args);
});
});
sync = false;
};
/**
* Resolve the file within the given directory.
*
* @param {string} dir
* @param {string} file
* @private
*/
View.prototype.resolve = function resolve(dir, file) {
var ext = this.ext;
// <path>.<ext>
var path = join(dir, file);
var stat = tryStat(path);
if (stat && stat.isFile()) {
return path;
}
// <path>/index.<ext>
path = join(dir, basename(file, ext), 'index' + ext);
stat = tryStat(path);
if (stat && stat.isFile()) {
return path;
}
};
/**
* Return a stat, maybe.
*
* @param {string} path
* @return {fs.Stats}
* @private
*/
function tryStat(path) {
debug('stat "%s"', path);
try {
return fs.statSync(path);
} catch (e) {
return undefined;
}
}

250
node_modules/express/node_modules/accepts/HISTORY.md generated vendored Normal file
View File

@@ -0,0 +1,250 @@
2.0.0 / 2024-08-31
==================
* Drop node <18 support
* deps: mime-types@^3.0.0
* deps: negotiator@^1.0.0
1.3.8 / 2022-02-02
==================
* deps: mime-types@~2.1.34
- deps: mime-db@~1.51.0
* deps: negotiator@0.6.3
1.3.7 / 2019-04-29
==================
* deps: negotiator@0.6.2
- Fix sorting charset, encoding, and language with extra parameters
1.3.6 / 2019-04-28
==================
* deps: mime-types@~2.1.24
- deps: mime-db@~1.40.0
1.3.5 / 2018-02-28
==================
* deps: mime-types@~2.1.18
- deps: mime-db@~1.33.0
1.3.4 / 2017-08-22
==================
* deps: mime-types@~2.1.16
- deps: mime-db@~1.29.0
1.3.3 / 2016-05-02
==================
* deps: mime-types@~2.1.11
- deps: mime-db@~1.23.0
* deps: negotiator@0.6.1
- perf: improve `Accept` parsing speed
- perf: improve `Accept-Charset` parsing speed
- perf: improve `Accept-Encoding` parsing speed
- perf: improve `Accept-Language` parsing speed
1.3.2 / 2016-03-08
==================
* deps: mime-types@~2.1.10
- Fix extension of `application/dash+xml`
- Update primary extension for `audio/mp4`
- deps: mime-db@~1.22.0
1.3.1 / 2016-01-19
==================
* deps: mime-types@~2.1.9
- deps: mime-db@~1.21.0
1.3.0 / 2015-09-29
==================
* deps: mime-types@~2.1.7
- deps: mime-db@~1.19.0
* deps: negotiator@0.6.0
- Fix including type extensions in parameters in `Accept` parsing
- Fix parsing `Accept` parameters with quoted equals
- Fix parsing `Accept` parameters with quoted semicolons
- Lazy-load modules from main entry point
- perf: delay type concatenation until needed
- perf: enable strict mode
- perf: hoist regular expressions
- perf: remove closures getting spec properties
- perf: remove a closure from media type parsing
- perf: remove property delete from media type parsing
1.2.13 / 2015-09-06
===================
* deps: mime-types@~2.1.6
- deps: mime-db@~1.18.0
1.2.12 / 2015-07-30
===================
* deps: mime-types@~2.1.4
- deps: mime-db@~1.16.0
1.2.11 / 2015-07-16
===================
* deps: mime-types@~2.1.3
- deps: mime-db@~1.15.0
1.2.10 / 2015-07-01
===================
* deps: mime-types@~2.1.2
- deps: mime-db@~1.14.0
1.2.9 / 2015-06-08
==================
* deps: mime-types@~2.1.1
- perf: fix deopt during mapping
1.2.8 / 2015-06-07
==================
* deps: mime-types@~2.1.0
- deps: mime-db@~1.13.0
* perf: avoid argument reassignment & argument slice
* perf: avoid negotiator recursive construction
* perf: enable strict mode
* perf: remove unnecessary bitwise operator
1.2.7 / 2015-05-10
==================
* deps: negotiator@0.5.3
- Fix media type parameter matching to be case-insensitive
1.2.6 / 2015-05-07
==================
* deps: mime-types@~2.0.11
- deps: mime-db@~1.9.1
* deps: negotiator@0.5.2
- Fix comparing media types with quoted values
- Fix splitting media types with quoted commas
1.2.5 / 2015-03-13
==================
* deps: mime-types@~2.0.10
- deps: mime-db@~1.8.0
1.2.4 / 2015-02-14
==================
* Support Node.js 0.6
* deps: mime-types@~2.0.9
- deps: mime-db@~1.7.0
* deps: negotiator@0.5.1
- Fix preference sorting to be stable for long acceptable lists
1.2.3 / 2015-01-31
==================
* deps: mime-types@~2.0.8
- deps: mime-db@~1.6.0
1.2.2 / 2014-12-30
==================
* deps: mime-types@~2.0.7
- deps: mime-db@~1.5.0
1.2.1 / 2014-12-30
==================
* deps: mime-types@~2.0.5
- deps: mime-db@~1.3.1
1.2.0 / 2014-12-19
==================
* deps: negotiator@0.5.0
- Fix list return order when large accepted list
- Fix missing identity encoding when q=0 exists
- Remove dynamic building of Negotiator class
1.1.4 / 2014-12-10
==================
* deps: mime-types@~2.0.4
- deps: mime-db@~1.3.0
1.1.3 / 2014-11-09
==================
* deps: mime-types@~2.0.3
- deps: mime-db@~1.2.0
1.1.2 / 2014-10-14
==================
* deps: negotiator@0.4.9
- Fix error when media type has invalid parameter
1.1.1 / 2014-09-28
==================
* deps: mime-types@~2.0.2
- deps: mime-db@~1.1.0
* deps: negotiator@0.4.8
- Fix all negotiations to be case-insensitive
- Stable sort preferences of same quality according to client order
1.1.0 / 2014-09-02
==================
* update `mime-types`
1.0.7 / 2014-07-04
==================
* Fix wrong type returned from `type` when match after unknown extension
1.0.6 / 2014-06-24
==================
* deps: negotiator@0.4.7
1.0.5 / 2014-06-20
==================
* fix crash when unknown extension given
1.0.4 / 2014-06-19
==================
* use `mime-types`
1.0.3 / 2014-06-11
==================
* deps: negotiator@0.4.6
- Order by specificity when quality is the same
1.0.2 / 2014-05-29
==================
* Fix interpretation when header not in request
* deps: pin negotiator@0.4.5
1.0.1 / 2014-01-18
==================
* Identity encoding isn't always acceptable
* deps: negotiator@~0.4.0
1.0.0 / 2013-12-27
==================
* Genesis

23
node_modules/express/node_modules/accepts/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

140
node_modules/express/node_modules/accepts/README.md generated vendored Normal file
View File

@@ -0,0 +1,140 @@
# accepts
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
In addition to negotiator, it allows:
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
as well as `('text/html', 'application/json')`.
- Allows type shorthands such as `json`.
- Returns `false` when no types match
- Treats non-existent headers as `*`
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install accepts
```
## API
```js
var accepts = require('accepts')
```
### accepts(req)
Create a new `Accepts` object for the given `req`.
#### .charset(charsets)
Return the first accepted charset. If nothing in `charsets` is accepted,
then `false` is returned.
#### .charsets()
Return the charsets that the request accepts, in the order of the client's
preference (most preferred first).
#### .encoding(encodings)
Return the first accepted encoding. If nothing in `encodings` is accepted,
then `false` is returned.
#### .encodings()
Return the encodings that the request accepts, in the order of the client's
preference (most preferred first).
#### .language(languages)
Return the first accepted language. If nothing in `languages` is accepted,
then `false` is returned.
#### .languages()
Return the languages that the request accepts, in the order of the client's
preference (most preferred first).
#### .type(types)
Return the first accepted type (and it is returned as the same text as what
appears in the `types` array). If nothing in `types` is accepted, then `false`
is returned.
The `types` array can contain full MIME types or file extensions. Any value
that is not a full MIME type is passed to `require('mime-types').lookup`.
#### .types()
Return the types that the request accepts, in the order of the client's
preference (most preferred first).
## Examples
### Simple type negotiation
This simple example shows how to use `accepts` to return a different typed
respond body based on what the client wants to accept. The server lists it's
preferences in order and will get back the best match between the client and
server.
```js
var accepts = require('accepts')
var http = require('http')
function app (req, res) {
var accept = accepts(req)
// the order of this list is significant; should be server preferred order
switch (accept.type(['json', 'html'])) {
case 'json':
res.setHeader('Content-Type', 'application/json')
res.write('{"hello":"world!"}')
break
case 'html':
res.setHeader('Content-Type', 'text/html')
res.write('<b>hello, world!</b>')
break
default:
// the fallback is text/plain, so no need to specify it above
res.setHeader('Content-Type', 'text/plain')
res.write('hello, world!')
break
}
res.end()
}
http.createServer(app).listen(3000)
```
You can test this out with the cURL program:
```sh
curl -I -H'Accept: text/html' http://localhost:3000/
```
## License
[MIT](LICENSE)
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci
[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml
[node-version-image]: https://badgen.net/npm/node/accepts
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/accepts
[npm-url]: https://npmjs.org/package/accepts
[npm-version-image]: https://badgen.net/npm/v/accepts

238
node_modules/express/node_modules/accepts/index.js generated vendored Normal file
View File

@@ -0,0 +1,238 @@
/*!
* accepts
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var Negotiator = require('negotiator')
var mime = require('mime-types')
/**
* Module exports.
* @public
*/
module.exports = Accepts
/**
* Create a new Accepts object for the given req.
*
* @param {object} req
* @public
*/
function Accepts (req) {
if (!(this instanceof Accepts)) {
return new Accepts(req)
}
this.headers = req.headers
this.negotiator = new Negotiator(req)
}
/**
* Check if the given `type(s)` is acceptable, returning
* the best match when true, otherwise `undefined`, in which
* case you should respond with 406 "Not Acceptable".
*
* The `type` value may be a single mime type string
* such as "application/json", the extension name
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
* or array is given the _best_ match, if any is returned.
*
* Examples:
*
* // Accept: text/html
* this.types('html');
* // => "html"
*
* // Accept: text/*, application/json
* this.types('html');
* // => "html"
* this.types('text/html');
* // => "text/html"
* this.types('json', 'text');
* // => "json"
* this.types('application/json');
* // => "application/json"
*
* // Accept: text/*, application/json
* this.types('image/png');
* this.types('png');
* // => undefined
*
* // Accept: text/*;q=.5, application/json
* this.types(['html', 'json']);
* this.types('html', 'json');
* // => "json"
*
* @param {String|Array} types...
* @return {String|Array|Boolean}
* @public
*/
Accepts.prototype.type =
Accepts.prototype.types = function (types_) {
var types = types_
// support flattened arguments
if (types && !Array.isArray(types)) {
types = new Array(arguments.length)
for (var i = 0; i < types.length; i++) {
types[i] = arguments[i]
}
}
// no types, return all requested types
if (!types || types.length === 0) {
return this.negotiator.mediaTypes()
}
// no accept header, return first given type
if (!this.headers.accept) {
return types[0]
}
var mimes = types.map(extToMime)
var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
var first = accepts[0]
return first
? types[mimes.indexOf(first)]
: false
}
/**
* Return accepted encodings or best fit based on `encodings`.
*
* Given `Accept-Encoding: gzip, deflate`
* an array sorted by quality is returned:
*
* ['gzip', 'deflate']
*
* @param {String|Array} encodings...
* @return {String|Array}
* @public
*/
Accepts.prototype.encoding =
Accepts.prototype.encodings = function (encodings_) {
var encodings = encodings_
// support flattened arguments
if (encodings && !Array.isArray(encodings)) {
encodings = new Array(arguments.length)
for (var i = 0; i < encodings.length; i++) {
encodings[i] = arguments[i]
}
}
// no encodings, return all requested encodings
if (!encodings || encodings.length === 0) {
return this.negotiator.encodings()
}
return this.negotiator.encodings(encodings)[0] || false
}
/**
* Return accepted charsets or best fit based on `charsets`.
*
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
* an array sorted by quality is returned:
*
* ['utf-8', 'utf-7', 'iso-8859-1']
*
* @param {String|Array} charsets...
* @return {String|Array}
* @public
*/
Accepts.prototype.charset =
Accepts.prototype.charsets = function (charsets_) {
var charsets = charsets_
// support flattened arguments
if (charsets && !Array.isArray(charsets)) {
charsets = new Array(arguments.length)
for (var i = 0; i < charsets.length; i++) {
charsets[i] = arguments[i]
}
}
// no charsets, return all requested charsets
if (!charsets || charsets.length === 0) {
return this.negotiator.charsets()
}
return this.negotiator.charsets(charsets)[0] || false
}
/**
* Return accepted languages or best fit based on `langs`.
*
* Given `Accept-Language: en;q=0.8, es, pt`
* an array sorted by quality is returned:
*
* ['es', 'pt', 'en']
*
* @param {String|Array} langs...
* @return {Array|String}
* @public
*/
Accepts.prototype.lang =
Accepts.prototype.langs =
Accepts.prototype.language =
Accepts.prototype.languages = function (languages_) {
var languages = languages_
// support flattened arguments
if (languages && !Array.isArray(languages)) {
languages = new Array(arguments.length)
for (var i = 0; i < languages.length; i++) {
languages[i] = arguments[i]
}
}
// no languages, return all requested languages
if (!languages || languages.length === 0) {
return this.negotiator.languages()
}
return this.negotiator.languages(languages)[0] || false
}
/**
* Convert extnames to mime.
*
* @param {String} type
* @return {String}
* @private
*/
function extToMime (type) {
return type.indexOf('/') === -1
? mime.lookup(type)
: type
}
/**
* Check if mime is valid.
*
* @param {String} type
* @return {Boolean}
* @private
*/
function validMime (type) {
return typeof type === 'string'
}

View File

@@ -0,0 +1,114 @@
1.0.0 / 2024-08-31
==================
* Drop support for node <18
* Added an option preferred encodings array #59
0.6.3 / 2022-01-22
==================
* Revert "Lazy-load modules from main entry point"
0.6.2 / 2019-04-29
==================
* Fix sorting charset, encoding, and language with extra parameters
0.6.1 / 2016-05-02
==================
* perf: improve `Accept` parsing speed
* perf: improve `Accept-Charset` parsing speed
* perf: improve `Accept-Encoding` parsing speed
* perf: improve `Accept-Language` parsing speed
0.6.0 / 2015-09-29
==================
* Fix including type extensions in parameters in `Accept` parsing
* Fix parsing `Accept` parameters with quoted equals
* Fix parsing `Accept` parameters with quoted semicolons
* Lazy-load modules from main entry point
* perf: delay type concatenation until needed
* perf: enable strict mode
* perf: hoist regular expressions
* perf: remove closures getting spec properties
* perf: remove a closure from media type parsing
* perf: remove property delete from media type parsing
0.5.3 / 2015-05-10
==================
* Fix media type parameter matching to be case-insensitive
0.5.2 / 2015-05-06
==================
* Fix comparing media types with quoted values
* Fix splitting media types with quoted commas
0.5.1 / 2015-02-14
==================
* Fix preference sorting to be stable for long acceptable lists
0.5.0 / 2014-12-18
==================
* Fix list return order when large accepted list
* Fix missing identity encoding when q=0 exists
* Remove dynamic building of Negotiator class
0.4.9 / 2014-10-14
==================
* Fix error when media type has invalid parameter
0.4.8 / 2014-09-28
==================
* Fix all negotiations to be case-insensitive
* Stable sort preferences of same quality according to client order
* Support Node.js 0.6
0.4.7 / 2014-06-24
==================
* Handle invalid provided languages
* Handle invalid provided media types
0.4.6 / 2014-06-11
==================
* Order by specificity when quality is the same
0.4.5 / 2014-05-29
==================
* Fix regression in empty header handling
0.4.4 / 2014-05-29
==================
* Fix behaviors when headers are not present
0.4.3 / 2014-04-16
==================
* Handle slashes on media params correctly
0.4.2 / 2014-02-28
==================
* Fix media type sorting
* Handle media types params strictly
0.4.1 / 2014-01-16
==================
* Use most specific matches
0.4.0 / 2014-01-09
==================
* Remove preferred prefix from methods

View File

@@ -0,0 +1,24 @@
(The MIT License)
Copyright (c) 2012-2014 Federico Romero
Copyright (c) 2012-2014 Isaac Z. Schlueter
Copyright (c) 2014-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.

View File

@@ -0,0 +1,212 @@
# negotiator
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
An HTTP content negotiator for Node.js
## Installation
```sh
$ npm install negotiator
```
## API
```js
var Negotiator = require('negotiator')
```
### Accept Negotiation
```js
availableMediaTypes = ['text/html', 'text/plain', 'application/json']
// The negotiator constructor receives a request object
negotiator = new Negotiator(request)
// Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'
negotiator.mediaTypes()
// -> ['text/html', 'image/jpeg', 'application/*']
negotiator.mediaTypes(availableMediaTypes)
// -> ['text/html', 'application/json']
negotiator.mediaType(availableMediaTypes)
// -> 'text/html'
```
You can check a working example at `examples/accept.js`.
#### Methods
##### mediaType()
Returns the most preferred media type from the client.
##### mediaType(availableMediaType)
Returns the most preferred media type from a list of available media types.
##### mediaTypes()
Returns an array of preferred media types ordered by the client preference.
##### mediaTypes(availableMediaTypes)
Returns an array of preferred media types ordered by priority from a list of
available media types.
### Accept-Language Negotiation
```js
negotiator = new Negotiator(request)
availableLanguages = ['en', 'es', 'fr']
// Let's say Accept-Language header is 'en;q=0.8, es, pt'
negotiator.languages()
// -> ['es', 'pt', 'en']
negotiator.languages(availableLanguages)
// -> ['es', 'en']
language = negotiator.language(availableLanguages)
// -> 'es'
```
You can check a working example at `examples/language.js`.
#### Methods
##### language()
Returns the most preferred language from the client.
##### language(availableLanguages)
Returns the most preferred language from a list of available languages.
##### languages()
Returns an array of preferred languages ordered by the client preference.
##### languages(availableLanguages)
Returns an array of preferred languages ordered by priority from a list of
available languages.
### Accept-Charset Negotiation
```js
availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']
negotiator = new Negotiator(request)
// Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'
negotiator.charsets()
// -> ['utf-8', 'iso-8859-1', 'utf-7']
negotiator.charsets(availableCharsets)
// -> ['utf-8', 'iso-8859-1']
negotiator.charset(availableCharsets)
// -> 'utf-8'
```
You can check a working example at `examples/charset.js`.
#### Methods
##### charset()
Returns the most preferred charset from the client.
##### charset(availableCharsets)
Returns the most preferred charset from a list of available charsets.
##### charsets()
Returns an array of preferred charsets ordered by the client preference.
##### charsets(availableCharsets)
Returns an array of preferred charsets ordered by priority from a list of
available charsets.
### Accept-Encoding Negotiation
```js
availableEncodings = ['identity', 'gzip']
negotiator = new Negotiator(request)
// Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'
negotiator.encodings()
// -> ['gzip', 'identity', 'compress']
negotiator.encodings(availableEncodings)
// -> ['gzip', 'identity']
negotiator.encoding(availableEncodings)
// -> 'gzip'
```
You can check a working example at `examples/encoding.js`.
#### Methods
##### encoding()
Returns the most preferred encoding from the client.
##### encoding(availableEncodings)
Returns the most preferred encoding from a list of available encodings.
##### encoding(availableEncodings, { preferred })
Returns the most preferred encoding from a list of available encodings, while prioritizing based on `preferred` array between same-quality encodings.
##### encodings()
Returns an array of preferred encodings ordered by the client preference.
##### encodings(availableEncodings)
Returns an array of preferred encodings ordered by priority from a list of
available encodings.
##### encodings(availableEncodings, { preferred })
Returns an array of preferred encodings ordered by priority from a list of
available encodings, while prioritizing based on `preferred` array between same-quality encodings.
## See Also
The [accepts](https://npmjs.org/package/accepts#readme) module builds on
this module and provides an alternative interface, mime type validation,
and more.
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/negotiator.svg
[npm-url]: https://npmjs.org/package/negotiator
[node-version-image]: https://img.shields.io/node/v/negotiator.svg
[node-version-url]: https://nodejs.org/en/download/
[coveralls-image]: https://img.shields.io/coveralls/jshttp/negotiator/master.svg
[coveralls-url]: https://coveralls.io/r/jshttp/negotiator?branch=master
[downloads-image]: https://img.shields.io/npm/dm/negotiator.svg
[downloads-url]: https://npmjs.org/package/negotiator
[github-actions-ci-image]: https://img.shields.io/github/workflow/status/jshttp/negotiator/ci/master?label=ci
[github-actions-ci-url]: https://github.com/jshttp/negotiator/actions/workflows/ci.yml

View File

@@ -0,0 +1,83 @@
/*!
* negotiator
* Copyright(c) 2012 Federico Romero
* Copyright(c) 2012-2014 Isaac Z. Schlueter
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
var preferredCharsets = require('./lib/charset')
var preferredEncodings = require('./lib/encoding')
var preferredLanguages = require('./lib/language')
var preferredMediaTypes = require('./lib/mediaType')
/**
* Module exports.
* @public
*/
module.exports = Negotiator;
module.exports.Negotiator = Negotiator;
/**
* Create a Negotiator instance from a request.
* @param {object} request
* @public
*/
function Negotiator(request) {
if (!(this instanceof Negotiator)) {
return new Negotiator(request);
}
this.request = request;
}
Negotiator.prototype.charset = function charset(available) {
var set = this.charsets(available);
return set && set[0];
};
Negotiator.prototype.charsets = function charsets(available) {
return preferredCharsets(this.request.headers['accept-charset'], available);
};
Negotiator.prototype.encoding = function encoding(available, opts) {
var set = this.encodings(available, opts);
return set && set[0];
};
Negotiator.prototype.encodings = function encodings(available, options) {
var opts = options || {};
return preferredEncodings(this.request.headers['accept-encoding'], available, opts.preferred);
};
Negotiator.prototype.language = function language(available) {
var set = this.languages(available);
return set && set[0];
};
Negotiator.prototype.languages = function languages(available) {
return preferredLanguages(this.request.headers['accept-language'], available);
};
Negotiator.prototype.mediaType = function mediaType(available) {
var set = this.mediaTypes(available);
return set && set[0];
};
Negotiator.prototype.mediaTypes = function mediaTypes(available) {
return preferredMediaTypes(this.request.headers.accept, available);
};
// Backwards compatibility
Negotiator.prototype.preferredCharset = Negotiator.prototype.charset;
Negotiator.prototype.preferredCharsets = Negotiator.prototype.charsets;
Negotiator.prototype.preferredEncoding = Negotiator.prototype.encoding;
Negotiator.prototype.preferredEncodings = Negotiator.prototype.encodings;
Negotiator.prototype.preferredLanguage = Negotiator.prototype.language;
Negotiator.prototype.preferredLanguages = Negotiator.prototype.languages;
Negotiator.prototype.preferredMediaType = Negotiator.prototype.mediaType;
Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes;

View File

@@ -0,0 +1,169 @@
/**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredCharsets;
module.exports.preferredCharsets = preferredCharsets;
/**
* Module variables.
* @private
*/
var simpleCharsetRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/;
/**
* Parse the Accept-Charset header.
* @private
*/
function parseAcceptCharset(accept) {
var accepts = accept.split(',');
for (var i = 0, j = 0; i < accepts.length; i++) {
var charset = parseCharset(accepts[i].trim(), i);
if (charset) {
accepts[j++] = charset;
}
}
// trim accepts
accepts.length = j;
return accepts;
}
/**
* Parse a charset from the Accept-Charset header.
* @private
*/
function parseCharset(str, i) {
var match = simpleCharsetRegExp.exec(str);
if (!match) return null;
var charset = match[1];
var q = 1;
if (match[2]) {
var params = match[2].split(';')
for (var j = 0; j < params.length; j++) {
var p = params[j].trim().split('=');
if (p[0] === 'q') {
q = parseFloat(p[1]);
break;
}
}
}
return {
charset: charset,
q: q,
i: i
};
}
/**
* Get the priority of a charset.
* @private
*/
function getCharsetPriority(charset, accepted, index) {
var priority = {o: -1, q: 0, s: 0};
for (var i = 0; i < accepted.length; i++) {
var spec = specify(charset, accepted[i], index);
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
priority = spec;
}
}
return priority;
}
/**
* Get the specificity of the charset.
* @private
*/
function specify(charset, spec, index) {
var s = 0;
if(spec.charset.toLowerCase() === charset.toLowerCase()){
s |= 1;
} else if (spec.charset !== '*' ) {
return null
}
return {
i: index,
o: spec.i,
q: spec.q,
s: s
}
}
/**
* Get the preferred charsets from an Accept-Charset header.
* @public
*/
function preferredCharsets(accept, provided) {
// RFC 2616 sec 14.2: no header = *
var accepts = parseAcceptCharset(accept === undefined ? '*' : accept || '');
if (!provided) {
// sorted list of all charsets
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullCharset);
}
var priorities = provided.map(function getPriority(type, index) {
return getCharsetPriority(type, accepts, index);
});
// sorted list of accepted charsets
return priorities.filter(isQuality).sort(compareSpecs).map(function getCharset(priority) {
return provided[priorities.indexOf(priority)];
});
}
/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
}
/**
* Get full charset string.
* @private
*/
function getFullCharset(spec) {
return spec.charset;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}

View File

@@ -0,0 +1,205 @@
/**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredEncodings;
module.exports.preferredEncodings = preferredEncodings;
/**
* Module variables.
* @private
*/
var simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/;
/**
* Parse the Accept-Encoding header.
* @private
*/
function parseAcceptEncoding(accept) {
var accepts = accept.split(',');
var hasIdentity = false;
var minQuality = 1;
for (var i = 0, j = 0; i < accepts.length; i++) {
var encoding = parseEncoding(accepts[i].trim(), i);
if (encoding) {
accepts[j++] = encoding;
hasIdentity = hasIdentity || specify('identity', encoding);
minQuality = Math.min(minQuality, encoding.q || 1);
}
}
if (!hasIdentity) {
/*
* If identity doesn't explicitly appear in the accept-encoding header,
* it's added to the list of acceptable encoding with the lowest q
*/
accepts[j++] = {
encoding: 'identity',
q: minQuality,
i: i
};
}
// trim accepts
accepts.length = j;
return accepts;
}
/**
* Parse an encoding from the Accept-Encoding header.
* @private
*/
function parseEncoding(str, i) {
var match = simpleEncodingRegExp.exec(str);
if (!match) return null;
var encoding = match[1];
var q = 1;
if (match[2]) {
var params = match[2].split(';');
for (var j = 0; j < params.length; j++) {
var p = params[j].trim().split('=');
if (p[0] === 'q') {
q = parseFloat(p[1]);
break;
}
}
}
return {
encoding: encoding,
q: q,
i: i
};
}
/**
* Get the priority of an encoding.
* @private
*/
function getEncodingPriority(encoding, accepted, index) {
var priority = {encoding: encoding, o: -1, q: 0, s: 0};
for (var i = 0; i < accepted.length; i++) {
var spec = specify(encoding, accepted[i], index);
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
priority = spec;
}
}
return priority;
}
/**
* Get the specificity of the encoding.
* @private
*/
function specify(encoding, spec, index) {
var s = 0;
if(spec.encoding.toLowerCase() === encoding.toLowerCase()){
s |= 1;
} else if (spec.encoding !== '*' ) {
return null
}
return {
encoding: encoding,
i: index,
o: spec.i,
q: spec.q,
s: s
}
};
/**
* Get the preferred encodings from an Accept-Encoding header.
* @public
*/
function preferredEncodings(accept, provided, preferred) {
var accepts = parseAcceptEncoding(accept || '');
var comparator = preferred ? function comparator (a, b) {
if (a.q !== b.q) {
return b.q - a.q // higher quality first
}
var aPreferred = preferred.indexOf(a.encoding)
var bPreferred = preferred.indexOf(b.encoding)
if (aPreferred === -1 && bPreferred === -1) {
// consider the original specifity/order
return (b.s - a.s) || (a.o - b.o) || (a.i - b.i)
}
if (aPreferred !== -1 && bPreferred !== -1) {
return aPreferred - bPreferred // consider the preferred order
}
return aPreferred === -1 ? 1 : -1 // preferred first
} : compareSpecs;
if (!provided) {
// sorted list of all encodings
return accepts
.filter(isQuality)
.sort(comparator)
.map(getFullEncoding);
}
var priorities = provided.map(function getPriority(type, index) {
return getEncodingPriority(type, accepts, index);
});
// sorted list of accepted encodings
return priorities.filter(isQuality).sort(comparator).map(function getEncoding(priority) {
return provided[priorities.indexOf(priority)];
});
}
/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i);
}
/**
* Get full encoding string.
* @private
*/
function getFullEncoding(spec) {
return spec.encoding;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}

View File

@@ -0,0 +1,179 @@
/**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredLanguages;
module.exports.preferredLanguages = preferredLanguages;
/**
* Module variables.
* @private
*/
var simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/;
/**
* Parse the Accept-Language header.
* @private
*/
function parseAcceptLanguage(accept) {
var accepts = accept.split(',');
for (var i = 0, j = 0; i < accepts.length; i++) {
var language = parseLanguage(accepts[i].trim(), i);
if (language) {
accepts[j++] = language;
}
}
// trim accepts
accepts.length = j;
return accepts;
}
/**
* Parse a language from the Accept-Language header.
* @private
*/
function parseLanguage(str, i) {
var match = simpleLanguageRegExp.exec(str);
if (!match) return null;
var prefix = match[1]
var suffix = match[2]
var full = prefix
if (suffix) full += "-" + suffix;
var q = 1;
if (match[3]) {
var params = match[3].split(';')
for (var j = 0; j < params.length; j++) {
var p = params[j].split('=');
if (p[0] === 'q') q = parseFloat(p[1]);
}
}
return {
prefix: prefix,
suffix: suffix,
q: q,
i: i,
full: full
};
}
/**
* Get the priority of a language.
* @private
*/
function getLanguagePriority(language, accepted, index) {
var priority = {o: -1, q: 0, s: 0};
for (var i = 0; i < accepted.length; i++) {
var spec = specify(language, accepted[i], index);
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
priority = spec;
}
}
return priority;
}
/**
* Get the specificity of the language.
* @private
*/
function specify(language, spec, index) {
var p = parseLanguage(language)
if (!p) return null;
var s = 0;
if(spec.full.toLowerCase() === p.full.toLowerCase()){
s |= 4;
} else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) {
s |= 2;
} else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) {
s |= 1;
} else if (spec.full !== '*' ) {
return null
}
return {
i: index,
o: spec.i,
q: spec.q,
s: s
}
};
/**
* Get the preferred languages from an Accept-Language header.
* @public
*/
function preferredLanguages(accept, provided) {
// RFC 2616 sec 14.4: no header = *
var accepts = parseAcceptLanguage(accept === undefined ? '*' : accept || '');
if (!provided) {
// sorted list of all languages
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullLanguage);
}
var priorities = provided.map(function getPriority(type, index) {
return getLanguagePriority(type, accepts, index);
});
// sorted list of accepted languages
return priorities.filter(isQuality).sort(compareSpecs).map(function getLanguage(priority) {
return provided[priorities.indexOf(priority)];
});
}
/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
}
/**
* Get full language string.
* @private
*/
function getFullLanguage(spec) {
return spec.full;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}

View File

@@ -0,0 +1,294 @@
/**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredMediaTypes;
module.exports.preferredMediaTypes = preferredMediaTypes;
/**
* Module variables.
* @private
*/
var simpleMediaTypeRegExp = /^\s*([^\s\/;]+)\/([^;\s]+)\s*(?:;(.*))?$/;
/**
* Parse the Accept header.
* @private
*/
function parseAccept(accept) {
var accepts = splitMediaTypes(accept);
for (var i = 0, j = 0; i < accepts.length; i++) {
var mediaType = parseMediaType(accepts[i].trim(), i);
if (mediaType) {
accepts[j++] = mediaType;
}
}
// trim accepts
accepts.length = j;
return accepts;
}
/**
* Parse a media type from the Accept header.
* @private
*/
function parseMediaType(str, i) {
var match = simpleMediaTypeRegExp.exec(str);
if (!match) return null;
var params = Object.create(null);
var q = 1;
var subtype = match[2];
var type = match[1];
if (match[3]) {
var kvps = splitParameters(match[3]).map(splitKeyValuePair);
for (var j = 0; j < kvps.length; j++) {
var pair = kvps[j];
var key = pair[0].toLowerCase();
var val = pair[1];
// get the value, unwrapping quotes
var value = val && val[0] === '"' && val[val.length - 1] === '"'
? val.slice(1, -1)
: val;
if (key === 'q') {
q = parseFloat(value);
break;
}
// store parameter
params[key] = value;
}
}
return {
type: type,
subtype: subtype,
params: params,
q: q,
i: i
};
}
/**
* Get the priority of a media type.
* @private
*/
function getMediaTypePriority(type, accepted, index) {
var priority = {o: -1, q: 0, s: 0};
for (var i = 0; i < accepted.length; i++) {
var spec = specify(type, accepted[i], index);
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
priority = spec;
}
}
return priority;
}
/**
* Get the specificity of the media type.
* @private
*/
function specify(type, spec, index) {
var p = parseMediaType(type);
var s = 0;
if (!p) {
return null;
}
if(spec.type.toLowerCase() == p.type.toLowerCase()) {
s |= 4
} else if(spec.type != '*') {
return null;
}
if(spec.subtype.toLowerCase() == p.subtype.toLowerCase()) {
s |= 2
} else if(spec.subtype != '*') {
return null;
}
var keys = Object.keys(spec.params);
if (keys.length > 0) {
if (keys.every(function (k) {
return spec.params[k] == '*' || (spec.params[k] || '').toLowerCase() == (p.params[k] || '').toLowerCase();
})) {
s |= 1
} else {
return null
}
}
return {
i: index,
o: spec.i,
q: spec.q,
s: s,
}
}
/**
* Get the preferred media types from an Accept header.
* @public
*/
function preferredMediaTypes(accept, provided) {
// RFC 2616 sec 14.2: no header = */*
var accepts = parseAccept(accept === undefined ? '*/*' : accept || '');
if (!provided) {
// sorted list of all types
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullType);
}
var priorities = provided.map(function getPriority(type, index) {
return getMediaTypePriority(type, accepts, index);
});
// sorted list of accepted types
return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) {
return provided[priorities.indexOf(priority)];
});
}
/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
}
/**
* Get full type string.
* @private
*/
function getFullType(spec) {
return spec.type + '/' + spec.subtype;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}
/**
* Count the number of quotes in a string.
* @private
*/
function quoteCount(string) {
var count = 0;
var index = 0;
while ((index = string.indexOf('"', index)) !== -1) {
count++;
index++;
}
return count;
}
/**
* Split a key value pair.
* @private
*/
function splitKeyValuePair(str) {
var index = str.indexOf('=');
var key;
var val;
if (index === -1) {
key = str;
} else {
key = str.slice(0, index);
val = str.slice(index + 1);
}
return [key, val];
}
/**
* Split an Accept header into media types.
* @private
*/
function splitMediaTypes(accept) {
var accepts = accept.split(',');
for (var i = 1, j = 0; i < accepts.length; i++) {
if (quoteCount(accepts[j]) % 2 == 0) {
accepts[++j] = accepts[i];
} else {
accepts[j] += ',' + accepts[i];
}
}
// trim accepts
accepts.length = j + 1;
return accepts;
}
/**
* Split a string of parameters.
* @private
*/
function splitParameters(str) {
var parameters = str.split(';');
for (var i = 1, j = 0; i < parameters.length; i++) {
if (quoteCount(parameters[j]) % 2 == 0) {
parameters[++j] = parameters[i];
} else {
parameters[j] += ';' + parameters[i];
}
}
// trim parameters
parameters.length = j + 1;
for (var i = 0; i < parameters.length; i++) {
parameters[i] = parameters[i].trim();
}
return parameters;
}

View File

@@ -0,0 +1,43 @@
{
"name": "negotiator",
"description": "HTTP content negotiation",
"version": "1.0.0",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Federico Romero <federico.romero@outboxlabs.com>",
"Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)"
],
"license": "MIT",
"keywords": [
"http",
"content negotiation",
"accept",
"accept-language",
"accept-encoding",
"accept-charset"
],
"repository": "jshttp/negotiator",
"devDependencies": {
"eslint": "7.32.0",
"eslint-plugin-markdown": "2.2.1",
"mocha": "9.1.3",
"nyc": "15.1.0"
},
"files": [
"lib/",
"HISTORY.md",
"LICENSE",
"index.js",
"README.md"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test:debug": "mocha --reporter spec --check-leaks --inspect --inspect-brk test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}

47
node_modules/express/node_modules/accepts/package.json generated vendored Normal file
View File

@@ -0,0 +1,47 @@
{
"name": "accepts",
"description": "Higher-level content negotiation",
"version": "2.0.0",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
],
"license": "MIT",
"repository": "jshttp/accepts",
"dependencies": {
"mime-types": "^3.0.0",
"negotiator": "^1.0.0"
},
"devDependencies": {
"deep-equal": "1.0.1",
"eslint": "7.32.0",
"eslint-config-standard": "14.1.1",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-markdown": "2.2.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "4.3.1",
"eslint-plugin-standard": "4.1.0",
"mocha": "9.2.0",
"nyc": "15.1.0"
},
"files": [
"LICENSE",
"HISTORY.md",
"index.js"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
},
"keywords": [
"content",
"negotiation",
"accept",
"accepts"
]
}

View File

@@ -0,0 +1,72 @@
1.0.1 / 2025-11-18
=================
* Updated `engines` field to Node@18 or higher (fixed reference, see 1.0.0)
* Remove dependency `safe-buffer`
1.0.0 / 2024-08-31
==================
* drop node <18
* allow utf8 as alias for utf-8
0.5.4 / 2021-12-10
==================
* deps: safe-buffer@5.2.1
0.5.3 / 2018-12-17
==================
* Use `safe-buffer` for improved Buffer API
0.5.2 / 2016-12-08
==================
* Fix `parse` to accept any linear whitespace character
0.5.1 / 2016-01-17
==================
* perf: enable strict mode
0.5.0 / 2014-10-11
==================
* Add `parse` function
0.4.0 / 2014-09-21
==================
* Expand non-Unicode `filename` to the full ISO-8859-1 charset
0.3.0 / 2014-09-20
==================
* Add `fallback` option
* Add `type` option
0.2.0 / 2014-09-19
==================
* Reduce ambiguity of file names with hex escape in buggy browsers
0.1.2 / 2014-09-19
==================
* Fix periodic invalid Unicode filename header
0.1.1 / 2014-09-19
==================
* Fix invalid characters appearing in `filename*` parameter
0.1.0 / 2014-09-18
==================
* Make the `filename` argument optional
0.0.0 / 2014-09-18
==================
* Initial release

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014-2017 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.

View File

@@ -0,0 +1,142 @@
# content-disposition
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Create and parse HTTP `Content-Disposition` header
## Installation
```sh
$ npm install content-disposition
```
## API
```js
const contentDisposition = require('content-disposition')
```
### contentDisposition(filename, options)
Create an attachment `Content-Disposition` header value using the given file name,
if supplied. The `filename` is optional and if no file name is desired, but you
want to specify `options`, set `filename` to `undefined`.
```js
res.setHeader('Content-Disposition', contentDisposition('∫ maths.pdf'))
```
**note** HTTP headers are of the ISO-8859-1 character set. If you are writing this
header through a means different from `setHeader` in Node.js, you'll want to specify
the `'binary'` encoding in Node.js.
#### Options
`contentDisposition` accepts these properties in the options object.
##### fallback
If the `filename` option is outside ISO-8859-1, then the file name is actually
stored in a supplemental field for clients that support Unicode file names and
a ISO-8859-1 version of the file name is automatically generated.
This specifies the ISO-8859-1 file name to override the automatic generation or
disables the generation all together, defaults to `true`.
- A string will specify the ISO-8859-1 file name to use in place of automatic
generation.
- `false` will disable including a ISO-8859-1 file name and only include the
Unicode version (unless the file name is already ISO-8859-1).
- `true` will enable automatic generation if the file name is outside ISO-8859-1.
If the `filename` option is ISO-8859-1 and this option is specified and has a
different value, then the `filename` option is encoded in the extended field
and this set as the fallback field, even though they are both ISO-8859-1.
##### type
Specifies the disposition type, defaults to `"attachment"`. This can also be
`"inline"`, or any other value (all values except inline are treated like
`attachment`, but can convey additional information if both parties agree to
it). The type is normalized to lower-case.
### contentDisposition.parse(string)
```js
const disposition = contentDisposition.parse('attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt')
```
Parse a `Content-Disposition` header string. This automatically handles extended
("Unicode") parameters by decoding them and providing them under the standard
parameter name. This will return an object with the following properties (examples
are shown for the string `'attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt'`):
- `type`: The disposition type (always lower case). Example: `'attachment'`
- `parameters`: An object of the parameters in the disposition (name of parameter
always lower case and extended versions replace non-extended versions). Example:
`{filename: "€ rates.txt"}`
## Examples
### Send a file for download
```js
const contentDisposition = require('content-disposition')
const destroy = require('destroy')
const fs = require('fs')
const http = require('http')
const onFinished = require('on-finished')
const filePath = '/path/to/public/plans.pdf'
http.createServer(function onRequest (req, res) {
// set headers
res.setHeader('Content-Type', 'application/pdf')
res.setHeader('Content-Disposition', contentDisposition(filePath))
// send file
const stream = fs.createReadStream(filePath)
stream.pipe(res)
onFinished(res, function () {
destroy(stream)
})
})
```
## Testing
```sh
$ npm test
```
## References
- [RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1][rfc-2616]
- [RFC 5987: Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters][rfc-5987]
- [RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)][rfc-6266]
- [Test Cases for HTTP Content-Disposition header field (RFC 6266) and the Encodings defined in RFCs 2047, 2231 and 5987][tc-2231]
[rfc-2616]: https://tools.ietf.org/html/rfc2616
[rfc-5987]: https://tools.ietf.org/html/rfc5987
[rfc-6266]: https://tools.ietf.org/html/rfc6266
[tc-2231]: http://greenbytes.de/tech/tc2231/
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/content-disposition
[npm-url]: https://npmjs.org/package/content-disposition
[node-version-image]: https://img.shields.io/node/v/content-disposition
[node-version-url]: https://nodejs.org/en/download
[coveralls-image]: https://img.shields.io/coverallsCoverage/github/jshttp/content-disposition
[coveralls-url]: https://coveralls.io/r/jshttp/content-disposition?branch=master
[downloads-image]: https://img.shields.io/npm/dm/content-disposition
[downloads-url]: https://npmjs.org/package/content-disposition
[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/jshttp/content-disposition/ci.yml
[github-actions-ci-url]: https://github.com/jshttp/content-disposition/actions/workflows/ci.yml

View File

@@ -0,0 +1,458 @@
/*!
* content-disposition
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
* @public
*/
module.exports = contentDisposition
module.exports.parse = parse
/**
* Module dependencies.
* @private
*/
var basename = require('path').basename
/**
* RegExp to match non attr-char, *after* encodeURIComponent (i.e. not including "%")
* @private
*/
var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g // eslint-disable-line no-control-regex
/**
* RegExp to match percent encoding escape.
* @private
*/
var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/
var HEX_ESCAPE_REPLACE_REGEXP = /%([0-9A-Fa-f]{2})/g
/**
* RegExp to match non-latin1 characters.
* @private
*/
var NON_LATIN1_REGEXP = /[^\x20-\x7e\xa0-\xff]/g
/**
* RegExp to match quoted-pair in RFC 2616
*
* quoted-pair = "\" CHAR
* CHAR = <any US-ASCII character (octets 0 - 127)>
* @private
*/
var QESC_REGEXP = /\\([\u0000-\u007f])/g // eslint-disable-line no-control-regex
/**
* RegExp to match chars that must be quoted-pair in RFC 2616
* @private
*/
var QUOTE_REGEXP = /([\\"])/g
/**
* RegExp for various RFC 2616 grammar
*
* parameter = token "=" ( token | quoted-string )
* token = 1*<any CHAR except CTLs or separators>
* separators = "(" | ")" | "<" | ">" | "@"
* | "," | ";" | ":" | "\" | <">
* | "/" | "[" | "]" | "?" | "="
* | "{" | "}" | SP | HT
* quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
* qdtext = <any TEXT except <">>
* quoted-pair = "\" CHAR
* CHAR = <any US-ASCII character (octets 0 - 127)>
* TEXT = <any OCTET except CTLs, but including LWS>
* LWS = [CRLF] 1*( SP | HT )
* CRLF = CR LF
* CR = <US-ASCII CR, carriage return (13)>
* LF = <US-ASCII LF, linefeed (10)>
* SP = <US-ASCII SP, space (32)>
* HT = <US-ASCII HT, horizontal-tab (9)>
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
* OCTET = <any 8-bit sequence of data>
* @private
*/
var PARAM_REGEXP = /;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g // eslint-disable-line no-control-regex
var TEXT_REGEXP = /^[\x20-\x7e\x80-\xff]+$/
var TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/
/**
* RegExp for various RFC 5987 grammar
*
* ext-value = charset "'" [ language ] "'" value-chars
* charset = "UTF-8" / "ISO-8859-1" / mime-charset
* mime-charset = 1*mime-charsetc
* mime-charsetc = ALPHA / DIGIT
* / "!" / "#" / "$" / "%" / "&"
* / "+" / "-" / "^" / "_" / "`"
* / "{" / "}" / "~"
* language = ( 2*3ALPHA [ extlang ] )
* / 4ALPHA
* / 5*8ALPHA
* extlang = *3( "-" 3ALPHA )
* value-chars = *( pct-encoded / attr-char )
* pct-encoded = "%" HEXDIG HEXDIG
* attr-char = ALPHA / DIGIT
* / "!" / "#" / "$" / "&" / "+" / "-" / "."
* / "^" / "_" / "`" / "|" / "~"
* @private
*/
var EXT_VALUE_REGEXP = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/
/**
* RegExp for various RFC 6266 grammar
*
* disposition-type = "inline" | "attachment" | disp-ext-type
* disp-ext-type = token
* disposition-parm = filename-parm | disp-ext-parm
* filename-parm = "filename" "=" value
* | "filename*" "=" ext-value
* disp-ext-parm = token "=" value
* | ext-token "=" ext-value
* ext-token = <the characters in token, followed by "*">
* @private
*/
var DISPOSITION_TYPE_REGEXP = /^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/ // eslint-disable-line no-control-regex
/**
* Create an attachment Content-Disposition header.
*
* @param {string} [filename]
* @param {object} [options]
* @param {string} [options.type=attachment]
* @param {string|boolean} [options.fallback=true]
* @return {string}
* @public
*/
function contentDisposition (filename, options) {
var opts = options || {}
// get type
var type = opts.type || 'attachment'
// get parameters
var params = createparams(filename, opts.fallback)
// format into string
return format(new ContentDisposition(type, params))
}
/**
* Create parameters object from filename and fallback.
*
* @param {string} [filename]
* @param {string|boolean} [fallback=true]
* @return {object}
* @private
*/
function createparams (filename, fallback) {
if (filename === undefined) {
return
}
var params = {}
if (typeof filename !== 'string') {
throw new TypeError('filename must be a string')
}
// fallback defaults to true
if (fallback === undefined) {
fallback = true
}
if (typeof fallback !== 'string' && typeof fallback !== 'boolean') {
throw new TypeError('fallback must be a string or boolean')
}
if (typeof fallback === 'string' && NON_LATIN1_REGEXP.test(fallback)) {
throw new TypeError('fallback must be ISO-8859-1 string')
}
// restrict to file base name
var name = basename(filename)
// determine if name is suitable for quoted string
var isQuotedString = TEXT_REGEXP.test(name)
// generate fallback name
var fallbackName = typeof fallback !== 'string'
? fallback && getlatin1(name)
: basename(fallback)
var hasFallback = typeof fallbackName === 'string' && fallbackName !== name
// set extended filename parameter
if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) {
params['filename*'] = name
}
// set filename parameter
if (isQuotedString || hasFallback) {
params.filename = hasFallback
? fallbackName
: name
}
return params
}
/**
* Format object to Content-Disposition header.
*
* @param {object} obj
* @param {string} obj.type
* @param {object} [obj.parameters]
* @return {string}
* @private
*/
function format (obj) {
var parameters = obj.parameters
var type = obj.type
if (!type || typeof type !== 'string' || !TOKEN_REGEXP.test(type)) {
throw new TypeError('invalid type')
}
// start with normalized type
var string = String(type).toLowerCase()
// append parameters
if (parameters && typeof parameters === 'object') {
var param
var params = Object.keys(parameters).sort()
for (var i = 0; i < params.length; i++) {
param = params[i]
var val = param.slice(-1) === '*'
? ustring(parameters[param])
: qstring(parameters[param])
string += '; ' + param + '=' + val
}
}
return string
}
/**
* Decode a RFC 5987 field value (gracefully).
*
* @param {string} str
* @return {string}
* @private
*/
function decodefield (str) {
var match = EXT_VALUE_REGEXP.exec(str)
if (!match) {
throw new TypeError('invalid extended field value')
}
var charset = match[1].toLowerCase()
var encoded = match[2]
var value
// to binary string
var binary = encoded.replace(HEX_ESCAPE_REPLACE_REGEXP, pdecode)
switch (charset) {
case 'iso-8859-1':
value = getlatin1(binary)
break
case 'utf-8':
case 'utf8':
value = Buffer.from(binary, 'binary').toString('utf8')
break
default:
throw new TypeError('unsupported charset in extended field')
}
return value
}
/**
* Get ISO-8859-1 version of string.
*
* @param {string} val
* @return {string}
* @private
*/
function getlatin1 (val) {
// simple Unicode -> ISO-8859-1 transformation
return String(val).replace(NON_LATIN1_REGEXP, '?')
}
/**
* Parse Content-Disposition header string.
*
* @param {string} string
* @return {object}
* @public
*/
function parse (string) {
if (!string || typeof string !== 'string') {
throw new TypeError('argument string is required')
}
var match = DISPOSITION_TYPE_REGEXP.exec(string)
if (!match) {
throw new TypeError('invalid type format')
}
// normalize type
var index = match[0].length
var type = match[1].toLowerCase()
var key
var names = []
var params = {}
var value
// calculate index to start at
index = PARAM_REGEXP.lastIndex = match[0].slice(-1) === ';'
? index - 1
: index
// match parameters
while ((match = PARAM_REGEXP.exec(string))) {
if (match.index !== index) {
throw new TypeError('invalid parameter format')
}
index += match[0].length
key = match[1].toLowerCase()
value = match[2]
if (names.indexOf(key) !== -1) {
throw new TypeError('invalid duplicate parameter')
}
names.push(key)
if (key.indexOf('*') + 1 === key.length) {
// decode extended value
key = key.slice(0, -1)
value = decodefield(value)
// overwrite existing value
params[key] = value
continue
}
if (typeof params[key] === 'string') {
continue
}
if (value[0] === '"') {
// remove quotes and escapes
value = value
.slice(1, -1)
.replace(QESC_REGEXP, '$1')
}
params[key] = value
}
if (index !== -1 && index !== string.length) {
throw new TypeError('invalid parameter format')
}
return new ContentDisposition(type, params)
}
/**
* Percent decode a single character.
*
* @param {string} str
* @param {string} hex
* @return {string}
* @private
*/
function pdecode (str, hex) {
return String.fromCharCode(parseInt(hex, 16))
}
/**
* Percent encode a single character.
*
* @param {string} char
* @return {string}
* @private
*/
function pencode (char) {
return '%' + String(char)
.charCodeAt(0)
.toString(16)
.toUpperCase()
}
/**
* Quote a string for HTTP.
*
* @param {string} val
* @return {string}
* @private
*/
function qstring (val) {
var str = String(val)
return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"'
}
/**
* Encode a Unicode string for HTTP (RFC 5987).
*
* @param {string} val
* @return {string}
* @private
*/
function ustring (val) {
var str = String(val)
// percent encode as UTF-8
var encoded = encodeURIComponent(str)
.replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode)
return 'UTF-8\'\'' + encoded
}
/**
* Class for parsed Content-Disposition header for v8 optimization
*
* @public
* @param {string} type
* @param {object} parameters
* @constructor
*/
function ContentDisposition (type, parameters) {
this.type = type
this.parameters = parameters
}

View File

@@ -0,0 +1,43 @@
{
"name": "content-disposition",
"description": "Create and parse Content-Disposition header",
"version": "1.0.1",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"keywords": [
"content-disposition",
"http",
"rfc6266",
"res"
],
"repository": "jshttp/content-disposition",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
},
"devDependencies": {
"c8": "^10.1.2",
"eslint": "7.32.0",
"eslint-config-standard": "13.0.1",
"eslint-plugin-import": "2.25.3",
"eslint-plugin-markdown": "2.2.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "5.2.0",
"eslint-plugin-standard": "4.1.0"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"engines": {
"node": ">=18"
},
"scripts": {
"lint": "eslint .",
"test": "node --test --test-reporter spec",
"test-ci": "c8 --reporter=lcovonly --reporter=text npm test",
"test-cov": "c8 --reporter=html --reporter=text npm test"
}
}

103
node_modules/express/node_modules/depd/History.md generated vendored Normal file
View File

@@ -0,0 +1,103 @@
2.0.0 / 2018-10-26
==================
* Drop support for Node.js 0.6
* Replace internal `eval` usage with `Function` constructor
* Use instance methods on `process` to check for listeners
1.1.2 / 2018-01-11
==================
* perf: remove argument reassignment
* Support Node.js 0.6 to 9.x
1.1.1 / 2017-07-27
==================
* Remove unnecessary `Buffer` loading
* Support Node.js 0.6 to 8.x
1.1.0 / 2015-09-14
==================
* Enable strict mode in more places
* Support io.js 3.x
* Support io.js 2.x
* Support web browser loading
- Requires bundler like Browserify or webpack
1.0.1 / 2015-04-07
==================
* Fix `TypeError`s when under `'use strict'` code
* Fix useless type name on auto-generated messages
* Support io.js 1.x
* Support Node.js 0.12
1.0.0 / 2014-09-17
==================
* No changes
0.4.5 / 2014-09-09
==================
* Improve call speed to functions using the function wrapper
* Support Node.js 0.6
0.4.4 / 2014-07-27
==================
* Work-around v8 generating empty stack traces
0.4.3 / 2014-07-26
==================
* Fix exception when global `Error.stackTraceLimit` is too low
0.4.2 / 2014-07-19
==================
* Correct call site for wrapped functions and properties
0.4.1 / 2014-07-19
==================
* Improve automatic message generation for function properties
0.4.0 / 2014-07-19
==================
* Add `TRACE_DEPRECATION` environment variable
* Remove non-standard grey color from color output
* Support `--no-deprecation` argument
* Support `--trace-deprecation` argument
* Support `deprecate.property(fn, prop, message)`
0.3.0 / 2014-06-16
==================
* Add `NO_DEPRECATION` environment variable
0.2.0 / 2014-06-15
==================
* Add `deprecate.property(obj, prop, message)`
* Remove `supports-color` dependency for node.js 0.8
0.1.0 / 2014-06-15
==================
* Add `deprecate.function(fn, message)`
* Add `process.on('deprecation', fn)` emitter
* Automatically generate message when omitted from `deprecate()`
0.0.1 / 2014-06-15
==================
* Fix warning for dynamic calls at singe call site
0.0.0 / 2014-06-15
==================
* Initial implementation

22
node_modules/express/node_modules/depd/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014-2018 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.

280
node_modules/express/node_modules/depd/Readme.md generated vendored Normal file
View File

@@ -0,0 +1,280 @@
# depd
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Linux Build][travis-image]][travis-url]
[![Windows Build][appveyor-image]][appveyor-url]
[![Coverage Status][coveralls-image]][coveralls-url]
Deprecate all the things
> With great modules comes great responsibility; mark things deprecated!
## Install
This module is installed directly using `npm`:
```sh
$ npm install depd
```
This module can also be bundled with systems like
[Browserify](http://browserify.org/) or [webpack](https://webpack.github.io/),
though by default this module will alter it's API to no longer display or
track deprecations.
## API
<!-- eslint-disable no-unused-vars -->
```js
var deprecate = require('depd')('my-module')
```
This library allows you to display deprecation messages to your users.
This library goes above and beyond with deprecation warnings by
introspection of the call stack (but only the bits that it is interested
in).
Instead of just warning on the first invocation of a deprecated
function and never again, this module will warn on the first invocation
of a deprecated function per unique call site, making it ideal to alert
users of all deprecated uses across the code base, rather than just
whatever happens to execute first.
The deprecation warnings from this module also include the file and line
information for the call into the module that the deprecated function was
in.
**NOTE** this library has a similar interface to the `debug` module, and
this module uses the calling file to get the boundary for the call stacks,
so you should always create a new `deprecate` object in each file and not
within some central file.
### depd(namespace)
Create a new deprecate function that uses the given namespace name in the
messages and will display the call site prior to the stack entering the
file this function was called from. It is highly suggested you use the
name of your module as the namespace.
### deprecate(message)
Call this function from deprecated code to display a deprecation message.
This message will appear once per unique caller site. Caller site is the
first call site in the stack in a different file from the caller of this
function.
If the message is omitted, a message is generated for you based on the site
of the `deprecate()` call and will display the name of the function called,
similar to the name displayed in a stack trace.
### deprecate.function(fn, message)
Call this function to wrap a given function in a deprecation message on any
call to the function. An optional message can be supplied to provide a custom
message.
### deprecate.property(obj, prop, message)
Call this function to wrap a given property on object in a deprecation message
on any accessing or setting of the property. An optional message can be supplied
to provide a custom message.
The method must be called on the object where the property belongs (not
inherited from the prototype).
If the property is a data descriptor, it will be converted to an accessor
descriptor in order to display the deprecation message.
### process.on('deprecation', fn)
This module will allow easy capturing of deprecation errors by emitting the
errors as the type "deprecation" on the global `process`. If there are no
listeners for this type, the errors are written to STDERR as normal, but if
there are any listeners, nothing will be written to STDERR and instead only
emitted. From there, you can write the errors in a different format or to a
logging source.
The error represents the deprecation and is emitted only once with the same
rules as writing to STDERR. The error has the following properties:
- `message` - This is the message given by the library
- `name` - This is always `'DeprecationError'`
- `namespace` - This is the namespace the deprecation came from
- `stack` - This is the stack of the call to the deprecated thing
Example `error.stack` output:
```
DeprecationError: my-cool-module deprecated oldfunction
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (module.js:456:26)
at evalScript (node.js:532:25)
at startup (node.js:80:7)
at node.js:902:3
```
### process.env.NO_DEPRECATION
As a user of modules that are deprecated, the environment variable `NO_DEPRECATION`
is provided as a quick solution to silencing deprecation warnings from being
output. The format of this is similar to that of `DEBUG`:
```sh
$ NO_DEPRECATION=my-module,othermod node app.js
```
This will suppress deprecations from being output for "my-module" and "othermod".
The value is a list of comma-separated namespaces. To suppress every warning
across all namespaces, use the value `*` for a namespace.
Providing the argument `--no-deprecation` to the `node` executable will suppress
all deprecations (only available in Node.js 0.8 or higher).
**NOTE** This will not suppress the deperecations given to any "deprecation"
event listeners, just the output to STDERR.
### process.env.TRACE_DEPRECATION
As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION`
is provided as a solution to getting more detailed location information in deprecation
warnings by including the entire stack trace. The format of this is the same as
`NO_DEPRECATION`:
```sh
$ TRACE_DEPRECATION=my-module,othermod node app.js
```
This will include stack traces for deprecations being output for "my-module" and
"othermod". The value is a list of comma-separated namespaces. To trace every
warning across all namespaces, use the value `*` for a namespace.
Providing the argument `--trace-deprecation` to the `node` executable will trace
all deprecations (only available in Node.js 0.8 or higher).
**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`.
## Display
![message](files/message.png)
When a user calls a function in your library that you mark deprecated, they
will see the following written to STDERR (in the given colors, similar colors
and layout to the `debug` module):
```
bright cyan bright yellow
| | reset cyan
| | | |
▼ ▼ ▼ ▼
my-cool-module deprecated oldfunction [eval]-wrapper:6:22
▲ ▲ ▲ ▲
| | | |
namespace | | location of mycoolmod.oldfunction() call
| deprecation message
the word "deprecated"
```
If the user redirects their STDERR to a file or somewhere that does not support
colors, they see (similar layout to the `debug` module):
```
Sun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22
▲ ▲ ▲ ▲ ▲
| | | | |
timestamp of message namespace | | location of mycoolmod.oldfunction() call
| deprecation message
the word "deprecated"
```
## Examples
### Deprecating all calls to a function
This will display a deprecated message about "oldfunction" being deprecated
from "my-module" on STDERR.
```js
var deprecate = require('depd')('my-cool-module')
// message automatically derived from function name
// Object.oldfunction
exports.oldfunction = deprecate.function(function oldfunction () {
// all calls to function are deprecated
})
// specific message
exports.oldfunction = deprecate.function(function () {
// all calls to function are deprecated
}, 'oldfunction')
```
### Conditionally deprecating a function call
This will display a deprecated message about "weirdfunction" being deprecated
from "my-module" on STDERR when called with less than 2 arguments.
```js
var deprecate = require('depd')('my-cool-module')
exports.weirdfunction = function () {
if (arguments.length < 2) {
// calls with 0 or 1 args are deprecated
deprecate('weirdfunction args < 2')
}
}
```
When calling `deprecate` as a function, the warning is counted per call site
within your own module, so you can display different deprecations depending
on different situations and the users will still get all the warnings:
```js
var deprecate = require('depd')('my-cool-module')
exports.weirdfunction = function () {
if (arguments.length < 2) {
// calls with 0 or 1 args are deprecated
deprecate('weirdfunction args < 2')
} else if (typeof arguments[0] !== 'string') {
// calls with non-string first argument are deprecated
deprecate('weirdfunction non-string first arg')
}
}
```
### Deprecating property access
This will display a deprecated message about "oldprop" being deprecated
from "my-module" on STDERR when accessed. A deprecation will be displayed
when setting the value and when getting the value.
```js
var deprecate = require('depd')('my-cool-module')
exports.oldprop = 'something'
// message automatically derives from property name
deprecate.property(exports, 'oldprop')
// explicit message
deprecate.property(exports, 'oldprop', 'oldprop >= 0.10')
```
## License
[MIT](LICENSE)
[appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/nodejs-depd/master?label=windows
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd
[coveralls-image]: https://badgen.net/coveralls/c/github/dougwilson/nodejs-depd/master
[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
[node-image]: https://badgen.net/npm/node/depd
[node-url]: https://nodejs.org/en/download/
[npm-downloads-image]: https://badgen.net/npm/dm/depd
[npm-url]: https://npmjs.org/package/depd
[npm-version-image]: https://badgen.net/npm/v/depd
[travis-image]: https://badgen.net/travis/dougwilson/nodejs-depd/master?label=linux
[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd

538
node_modules/express/node_modules/depd/index.js generated vendored Normal file
View File

@@ -0,0 +1,538 @@
/*!
* depd
* Copyright(c) 2014-2018 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module dependencies.
*/
var relative = require('path').relative
/**
* Module exports.
*/
module.exports = depd
/**
* Get the path to base files on.
*/
var basePath = process.cwd()
/**
* Determine if namespace is contained in the string.
*/
function containsNamespace (str, namespace) {
var vals = str.split(/[ ,]+/)
var ns = String(namespace).toLowerCase()
for (var i = 0; i < vals.length; i++) {
var val = vals[i]
// namespace contained
if (val && (val === '*' || val.toLowerCase() === ns)) {
return true
}
}
return false
}
/**
* Convert a data descriptor to accessor descriptor.
*/
function convertDataDescriptorToAccessor (obj, prop, message) {
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
var value = descriptor.value
descriptor.get = function getter () { return value }
if (descriptor.writable) {
descriptor.set = function setter (val) { return (value = val) }
}
delete descriptor.value
delete descriptor.writable
Object.defineProperty(obj, prop, descriptor)
return descriptor
}
/**
* Create arguments string to keep arity.
*/
function createArgumentsString (arity) {
var str = ''
for (var i = 0; i < arity; i++) {
str += ', arg' + i
}
return str.substr(2)
}
/**
* Create stack string from stack.
*/
function createStackString (stack) {
var str = this.name + ': ' + this.namespace
if (this.message) {
str += ' deprecated ' + this.message
}
for (var i = 0; i < stack.length; i++) {
str += '\n at ' + stack[i].toString()
}
return str
}
/**
* Create deprecate for namespace in caller.
*/
function depd (namespace) {
if (!namespace) {
throw new TypeError('argument namespace is required')
}
var stack = getStack()
var site = callSiteLocation(stack[1])
var file = site[0]
function deprecate (message) {
// call to self as log
log.call(deprecate, message)
}
deprecate._file = file
deprecate._ignored = isignored(namespace)
deprecate._namespace = namespace
deprecate._traced = istraced(namespace)
deprecate._warned = Object.create(null)
deprecate.function = wrapfunction
deprecate.property = wrapproperty
return deprecate
}
/**
* Determine if event emitter has listeners of a given type.
*
* The way to do this check is done three different ways in Node.js >= 0.8
* so this consolidates them into a minimal set using instance methods.
*
* @param {EventEmitter} emitter
* @param {string} type
* @returns {boolean}
* @private
*/
function eehaslisteners (emitter, type) {
var count = typeof emitter.listenerCount !== 'function'
? emitter.listeners(type).length
: emitter.listenerCount(type)
return count > 0
}
/**
* Determine if namespace is ignored.
*/
function isignored (namespace) {
if (process.noDeprecation) {
// --no-deprecation support
return true
}
var str = process.env.NO_DEPRECATION || ''
// namespace ignored
return containsNamespace(str, namespace)
}
/**
* Determine if namespace is traced.
*/
function istraced (namespace) {
if (process.traceDeprecation) {
// --trace-deprecation support
return true
}
var str = process.env.TRACE_DEPRECATION || ''
// namespace traced
return containsNamespace(str, namespace)
}
/**
* Display deprecation message.
*/
function log (message, site) {
var haslisteners = eehaslisteners(process, 'deprecation')
// abort early if no destination
if (!haslisteners && this._ignored) {
return
}
var caller
var callFile
var callSite
var depSite
var i = 0
var seen = false
var stack = getStack()
var file = this._file
if (site) {
// provided site
depSite = site
callSite = callSiteLocation(stack[1])
callSite.name = depSite.name
file = callSite[0]
} else {
// get call site
i = 2
depSite = callSiteLocation(stack[i])
callSite = depSite
}
// get caller of deprecated thing in relation to file
for (; i < stack.length; i++) {
caller = callSiteLocation(stack[i])
callFile = caller[0]
if (callFile === file) {
seen = true
} else if (callFile === this._file) {
file = this._file
} else if (seen) {
break
}
}
var key = caller
? depSite.join(':') + '__' + caller.join(':')
: undefined
if (key !== undefined && key in this._warned) {
// already warned
return
}
this._warned[key] = true
// generate automatic message from call site
var msg = message
if (!msg) {
msg = callSite === depSite || !callSite.name
? defaultMessage(depSite)
: defaultMessage(callSite)
}
// emit deprecation if listeners exist
if (haslisteners) {
var err = DeprecationError(this._namespace, msg, stack.slice(i))
process.emit('deprecation', err)
return
}
// format and write message
var format = process.stderr.isTTY
? formatColor
: formatPlain
var output = format.call(this, msg, caller, stack.slice(i))
process.stderr.write(output + '\n', 'utf8')
}
/**
* Get call site location as array.
*/
function callSiteLocation (callSite) {
var file = callSite.getFileName() || '<anonymous>'
var line = callSite.getLineNumber()
var colm = callSite.getColumnNumber()
if (callSite.isEval()) {
file = callSite.getEvalOrigin() + ', ' + file
}
var site = [file, line, colm]
site.callSite = callSite
site.name = callSite.getFunctionName()
return site
}
/**
* Generate a default message from the site.
*/
function defaultMessage (site) {
var callSite = site.callSite
var funcName = site.name
// make useful anonymous name
if (!funcName) {
funcName = '<anonymous@' + formatLocation(site) + '>'
}
var context = callSite.getThis()
var typeName = context && callSite.getTypeName()
// ignore useless type name
if (typeName === 'Object') {
typeName = undefined
}
// make useful type name
if (typeName === 'Function') {
typeName = context.name || typeName
}
return typeName && callSite.getMethodName()
? typeName + '.' + funcName
: funcName
}
/**
* Format deprecation message without color.
*/
function formatPlain (msg, caller, stack) {
var timestamp = new Date().toUTCString()
var formatted = timestamp +
' ' + this._namespace +
' deprecated ' + msg
// add stack trace
if (this._traced) {
for (var i = 0; i < stack.length; i++) {
formatted += '\n at ' + stack[i].toString()
}
return formatted
}
if (caller) {
formatted += ' at ' + formatLocation(caller)
}
return formatted
}
/**
* Format deprecation message with color.
*/
function formatColor (msg, caller, stack) {
var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' + // bold cyan
' \x1b[33;1mdeprecated\x1b[22;39m' + // bold yellow
' \x1b[0m' + msg + '\x1b[39m' // reset
// add stack trace
if (this._traced) {
for (var i = 0; i < stack.length; i++) {
formatted += '\n \x1b[36mat ' + stack[i].toString() + '\x1b[39m' // cyan
}
return formatted
}
if (caller) {
formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
}
return formatted
}
/**
* Format call site location.
*/
function formatLocation (callSite) {
return relative(basePath, callSite[0]) +
':' + callSite[1] +
':' + callSite[2]
}
/**
* Get the stack as array of call sites.
*/
function getStack () {
var limit = Error.stackTraceLimit
var obj = {}
var prep = Error.prepareStackTrace
Error.prepareStackTrace = prepareObjectStackTrace
Error.stackTraceLimit = Math.max(10, limit)
// capture the stack
Error.captureStackTrace(obj)
// slice this function off the top
var stack = obj.stack.slice(1)
Error.prepareStackTrace = prep
Error.stackTraceLimit = limit
return stack
}
/**
* Capture call site stack from v8.
*/
function prepareObjectStackTrace (obj, stack) {
return stack
}
/**
* Return a wrapped function in a deprecation message.
*/
function wrapfunction (fn, message) {
if (typeof fn !== 'function') {
throw new TypeError('argument fn must be a function')
}
var args = createArgumentsString(fn.length)
var stack = getStack()
var site = callSiteLocation(stack[1])
site.name = fn.name
// eslint-disable-next-line no-new-func
var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site',
'"use strict"\n' +
'return function (' + args + ') {' +
'log.call(deprecate, message, site)\n' +
'return fn.apply(this, arguments)\n' +
'}')(fn, log, this, message, site)
return deprecatedfn
}
/**
* Wrap property in a deprecation message.
*/
function wrapproperty (obj, prop, message) {
if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
throw new TypeError('argument obj must be object')
}
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
if (!descriptor) {
throw new TypeError('must call property on owner object')
}
if (!descriptor.configurable) {
throw new TypeError('property must be configurable')
}
var deprecate = this
var stack = getStack()
var site = callSiteLocation(stack[1])
// set site name
site.name = prop
// convert data descriptor
if ('value' in descriptor) {
descriptor = convertDataDescriptorToAccessor(obj, prop, message)
}
var get = descriptor.get
var set = descriptor.set
// wrap getter
if (typeof get === 'function') {
descriptor.get = function getter () {
log.call(deprecate, message, site)
return get.apply(this, arguments)
}
}
// wrap setter
if (typeof set === 'function') {
descriptor.set = function setter () {
log.call(deprecate, message, site)
return set.apply(this, arguments)
}
}
Object.defineProperty(obj, prop, descriptor)
}
/**
* Create DeprecationError for deprecation
*/
function DeprecationError (namespace, message, stack) {
var error = new Error()
var stackString
Object.defineProperty(error, 'constructor', {
value: DeprecationError
})
Object.defineProperty(error, 'message', {
configurable: true,
enumerable: false,
value: message,
writable: true
})
Object.defineProperty(error, 'name', {
enumerable: false,
configurable: true,
value: 'DeprecationError',
writable: true
})
Object.defineProperty(error, 'namespace', {
configurable: true,
enumerable: false,
value: namespace,
writable: true
})
Object.defineProperty(error, 'stack', {
configurable: true,
enumerable: false,
get: function () {
if (stackString !== undefined) {
return stackString
}
// prepare stack trace
return (stackString = createStackString.call(this, stack))
},
set: function setter (val) {
stackString = val
}
})
return error
}

View File

@@ -0,0 +1,77 @@
/*!
* depd
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
* @public
*/
module.exports = depd
/**
* Create deprecate for namespace in caller.
*/
function depd (namespace) {
if (!namespace) {
throw new TypeError('argument namespace is required')
}
function deprecate (message) {
// no-op in browser
}
deprecate._file = undefined
deprecate._ignored = true
deprecate._namespace = namespace
deprecate._traced = false
deprecate._warned = Object.create(null)
deprecate.function = wrapfunction
deprecate.property = wrapproperty
return deprecate
}
/**
* Return a wrapped function in a deprecation message.
*
* This is a no-op version of the wrapper, which does nothing but call
* validation.
*/
function wrapfunction (fn, message) {
if (typeof fn !== 'function') {
throw new TypeError('argument fn must be a function')
}
return fn
}
/**
* Wrap property in a deprecation message.
*
* This is a no-op version of the wrapper, which does nothing but call
* validation.
*/
function wrapproperty (obj, prop, message) {
if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
throw new TypeError('argument obj must be object')
}
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
if (!descriptor) {
throw new TypeError('must call property on owner object')
}
if (!descriptor.configurable) {
throw new TypeError('property must be configurable')
}
}

45
node_modules/express/node_modules/depd/package.json generated vendored Normal file
View File

@@ -0,0 +1,45 @@
{
"name": "depd",
"description": "Deprecate all the things",
"version": "2.0.0",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"keywords": [
"deprecate",
"deprecated"
],
"repository": "dougwilson/nodejs-depd",
"browser": "lib/browser/index.js",
"devDependencies": {
"benchmark": "2.1.4",
"beautify-benchmark": "0.2.4",
"eslint": "5.7.0",
"eslint-config-standard": "12.0.0",
"eslint-plugin-import": "2.14.0",
"eslint-plugin-markdown": "1.0.0-beta.7",
"eslint-plugin-node": "7.0.1",
"eslint-plugin-promise": "4.0.1",
"eslint-plugin-standard": "4.0.0",
"istanbul": "0.4.5",
"mocha": "5.2.0",
"safe-buffer": "5.1.2",
"uid-safe": "2.1.5"
},
"files": [
"lib/",
"History.md",
"LICENSE",
"index.js",
"Readme.md"
],
"engines": {
"node": ">= 0.8"
},
"scripts": {
"bench": "node benchmark/index.js",
"lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --reporter spec --bail test/",
"test-ci": "istanbul cover --print=none node_modules/mocha/bin/_mocha -- --reporter spec test/ && istanbul report lcovonly text-summary",
"test-cov": "istanbul cover --print=none node_modules/mocha/bin/_mocha -- --reporter dot test/ && istanbul report lcov text-summary"
}
}

80
node_modules/express/node_modules/fresh/HISTORY.md generated vendored Normal file
View File

@@ -0,0 +1,80 @@
2.0.0 - 2024-09-04
==========
* Drop support for Node.js <18
1.0.0 - 2024-09-04
==========
* Drop support for Node.js below 0.8
* Fix: Ignore `If-Modified-Since` in the presence of `If-None-Match`, according to [spec](https://www.rfc-editor.org/rfc/rfc9110.html#section-13.1.3-5). Fixes [#35](https://github.com/jshttp/fresh/issues/35)
0.5.2 / 2017-09-13
==================
* Fix regression matching multiple ETags in `If-None-Match`
* perf: improve `If-None-Match` token parsing
0.5.1 / 2017-09-11
==================
* Fix handling of modified headers with invalid dates
* perf: improve ETag match loop
0.5.0 / 2017-02-21
==================
* Fix incorrect result when `If-None-Match` has both `*` and ETags
* Fix weak `ETag` matching to match spec
* perf: delay reading header values until needed
* perf: skip checking modified time if ETag check failed
* perf: skip parsing `If-None-Match` when no `ETag` header
* perf: use `Date.parse` instead of `new Date`
0.4.0 / 2017-02-05
==================
* Fix false detection of `no-cache` request directive
* perf: enable strict mode
* perf: hoist regular expressions
* perf: remove duplicate conditional
* perf: remove unnecessary boolean coercions
0.3.0 / 2015-05-12
==================
* Add weak `ETag` matching support
0.2.4 / 2014-09-07
==================
* Support Node.js 0.6
0.2.3 / 2014-09-07
==================
* Move repository to jshttp
0.2.2 / 2014-02-19
==================
* Revert "Fix for blank page on Safari reload"
0.2.1 / 2014-01-29
==================
* Fix for blank page on Safari reload
0.2.0 / 2013-08-11
==================
* Return stale for `Cache-Control: no-cache`
0.1.0 / 2012-06-15
==================
* Add `If-None-Match: *` support
0.0.1 / 2012-06-10
==================
* Initial release

23
node_modules/express/node_modules/fresh/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2016-2017 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

117
node_modules/express/node_modules/fresh/README.md generated vendored Normal file
View File

@@ -0,0 +1,117 @@
# fresh
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][ci-image]][ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
HTTP response freshness testing
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```
$ npm install fresh
```
## API
```js
var fresh = require('fresh')
```
### fresh(reqHeaders, resHeaders)
Check freshness of the response using request and response headers.
When the response is still "fresh" in the client's cache `true` is
returned, otherwise `false` is returned to indicate that the client
cache is now stale and the full response should be sent.
When a client sends the `Cache-Control: no-cache` request header to
indicate an end-to-end reload request, this module will return `false`
to make handling these requests transparent.
## Known Issues
This module is designed to only follow the HTTP specifications, not
to work-around all kinda of client bugs (especially since this module
typically does not receive enough information to understand what the
client actually is).
There is a known issue that in certain versions of Safari, Safari
will incorrectly make a request that allows this module to validate
freshness of the resource even when Safari does not have a
representation of the resource in the cache. The module
[jumanji](https://www.npmjs.com/package/jumanji) can be used in
an Express application to work-around this issue and also provides
links to further reading on this Safari bug.
## Example
### API usage
<!-- eslint-disable no-redeclare -->
```js
var reqHeaders = { 'if-none-match': '"foo"' }
var resHeaders = { etag: '"bar"' }
fresh(reqHeaders, resHeaders)
// => false
var reqHeaders = { 'if-none-match': '"foo"' }
var resHeaders = { etag: '"foo"' }
fresh(reqHeaders, resHeaders)
// => true
```
### Using with Node.js http server
```js
var fresh = require('fresh')
var http = require('http')
var server = http.createServer(function (req, res) {
// perform server logic
// ... including adding ETag / Last-Modified response headers
if (isFresh(req, res)) {
// client has a fresh copy of resource
res.statusCode = 304
res.end()
return
}
// send the resource
res.statusCode = 200
res.end('hello, world!')
})
function isFresh (req, res) {
return fresh(req.headers, {
etag: res.getHeader('ETag'),
'last-modified': res.getHeader('Last-Modified')
})
}
server.listen(3000)
```
## License
[MIT](LICENSE)
[ci-image]: https://img.shields.io/github/workflow/status/jshttp/fresh/ci/master?label=ci
[ci-url]: https://github.com/jshttp/fresh/actions/workflows/ci.yml
[npm-image]: https://img.shields.io/npm/v/fresh.svg
[npm-url]: https://npmjs.org/package/fresh
[node-version-image]: https://img.shields.io/node/v/fresh.svg
[node-version-url]: https://nodejs.org/en/
[coveralls-image]: https://img.shields.io/coveralls/jshttp/fresh/master.svg
[coveralls-url]: https://coveralls.io/r/jshttp/fresh?branch=master
[downloads-image]: https://img.shields.io/npm/dm/fresh.svg
[downloads-url]: https://npmjs.org/package/fresh

136
node_modules/express/node_modules/fresh/index.js generated vendored Normal file
View File

@@ -0,0 +1,136 @@
/*!
* fresh
* Copyright(c) 2012 TJ Holowaychuk
* Copyright(c) 2016-2017 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* RegExp to check for no-cache token in Cache-Control.
* @private
*/
var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/
/**
* Module exports.
* @public
*/
module.exports = fresh
/**
* Check freshness of the response using request and response headers.
*
* @param {Object} reqHeaders
* @param {Object} resHeaders
* @return {Boolean}
* @public
*/
function fresh (reqHeaders, resHeaders) {
// fields
var modifiedSince = reqHeaders['if-modified-since']
var noneMatch = reqHeaders['if-none-match']
// unconditional request
if (!modifiedSince && !noneMatch) {
return false
}
// Always return stale when Cache-Control: no-cache
// to support end-to-end reload requests
// https://tools.ietf.org/html/rfc2616#section-14.9.4
var cacheControl = reqHeaders['cache-control']
if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) {
return false
}
// if-none-match takes precedent over if-modified-since
if (noneMatch) {
if (noneMatch === '*') {
return true
}
var etag = resHeaders.etag
if (!etag) {
return false
}
var matches = parseTokenList(noneMatch)
for (var i = 0; i < matches.length; i++) {
var match = matches[i]
if (match === etag || match === 'W/' + etag || 'W/' + match === etag) {
return true
}
}
return false
}
// if-modified-since
if (modifiedSince) {
var lastModified = resHeaders['last-modified']
var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince))
if (modifiedStale) {
return false
}
}
return true
}
/**
* Parse an HTTP Date into a number.
*
* @param {string} date
* @private
*/
function parseHttpDate (date) {
var timestamp = date && Date.parse(date)
// istanbul ignore next: guard against date.js Date.parse patching
return typeof timestamp === 'number'
? timestamp
: NaN
}
/**
* Parse a HTTP token list.
*
* @param {string} str
* @private
*/
function parseTokenList (str) {
var end = 0
var list = []
var start = 0
// gather tokens
for (var i = 0, len = str.length; i < len; i++) {
switch (str.charCodeAt(i)) {
case 0x20: /* */
if (start === end) {
start = end = i + 1
}
break
case 0x2c: /* , */
list.push(str.substring(start, end))
start = end = i + 1
break
default:
end = i + 1
break
}
}
// final token
list.push(str.substring(start, end))
return list
}

46
node_modules/express/node_modules/fresh/package.json generated vendored Normal file
View File

@@ -0,0 +1,46 @@
{
"name": "fresh",
"description": "HTTP response freshness testing",
"version": "2.0.0",
"author": "TJ Holowaychuk <tj@vision-media.ca> (http://tjholowaychuk.com)",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
],
"license": "MIT",
"keywords": [
"fresh",
"http",
"conditional",
"cache"
],
"repository": "jshttp/fresh",
"devDependencies": {
"beautify-benchmark": "0.2.4",
"benchmark": "2.1.4",
"eslint": "8.12.0",
"eslint-config-standard": "14.1.1",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-markdown": "2.2.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "6.0.0",
"eslint-plugin-standard": "4.1.0",
"mocha": "9.2.0",
"nyc": "15.1.0"
},
"files": [
"HISTORY.md",
"LICENSE",
"index.js"
],
"engines": {
"node": ">= 0.8"
},
"scripts": {
"bench": "node benchmark/index.js",
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}

View File

@@ -0,0 +1,11 @@
/**
Merges "own" properties from a source to a destination object, including non-enumerable and accessor-defined properties. It retains original values and descriptors, ensuring the destination receives a complete and accurate copy of the source's properties.
@param destination - The object to receive properties.
@param source - The object providing properties.
@param overwrite - Optional boolean to control overwriting of existing properties. Defaults to true.
@returns The modified destination object.
*/
declare function mergeDescriptors<T, U>(destination: T, source: U, overwrite?: boolean): T & U;
export = mergeDescriptors;

View File

@@ -0,0 +1,26 @@
'use strict';
function mergeDescriptors(destination, source, overwrite = true) {
if (!destination) {
throw new TypeError('The `destination` argument is required.');
}
if (!source) {
throw new TypeError('The `source` argument is required.');
}
for (const name of Object.getOwnPropertyNames(source)) {
if (!overwrite && Object.hasOwn(destination, name)) {
// Skip descriptor
continue;
}
// Copy descriptor
const descriptor = Object.getOwnPropertyDescriptor(source, name);
Object.defineProperty(destination, name, descriptor);
}
return destination;
}
module.exports = mergeDescriptors;

View File

@@ -0,0 +1,11 @@
MIT License
Copyright (c) Jonathan Ong <me@jongleberry.com>
Copyright (c) Douglas Christopher Wilson <doug@somethingdoug.com>
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
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.

View File

@@ -0,0 +1,50 @@
{
"name": "merge-descriptors",
"version": "2.0.0",
"description": "Merge objects using their property descriptors",
"license": "MIT",
"repository": "sindresorhus/merge-descriptors",
"funding": "https://github.com/sponsors/sindresorhus",
"contributors": [
"Jonathan Ong <me@jongleberry.com>",
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Mike Grabowski <grabbou@gmail.com>",
"Sindre Sorhus <sindresorhus@gmail.com>"
],
"exports": {
"types": "./index.d.ts",
"default": "./index.js"
},
"main": "./index.js",
"types": "./index.d.ts",
"sideEffects": false,
"engines": {
"node": ">=18"
},
"scripts": {
"test": "xo && ava"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"merge",
"descriptors",
"object",
"property",
"properties",
"merging",
"getter",
"setter"
],
"devDependencies": {
"ava": "^5.3.1",
"xo": "^0.56.0"
},
"xo": {
"rules": {
"unicorn/prefer-module": "off"
}
}
}

View File

@@ -0,0 +1,55 @@
# merge-descriptors
> Merge objects using their property descriptors
## Install
```sh
npm install merge-descriptors
```
## Usage
```js
import mergeDescriptors from 'merge-descriptors';
const thing = {
get name() {
return 'John'
}
}
const animal = {};
mergeDescriptors(animal, thing);
console.log(animal.name);
//=> 'John'
```
## API
### merge(destination, source, overwrite?)
Merges "own" properties from a source to a destination object, including non-enumerable and accessor-defined properties. It retains original values and descriptors, ensuring the destination receives a complete and accurate copy of the source's properties.
Returns the modified destination object.
#### destination
Type: `object`
The object to receive properties.
#### source
Type: `object`
The object providing properties.
#### overwrite
Type: `boolean`\
Default: `true`
A boolean to control overwriting of existing properties.

292
node_modules/express/node_modules/type-is/HISTORY.md generated vendored Normal file
View File

@@ -0,0 +1,292 @@
2.0.1 / 2025-03-27
==========
2.0.0 / 2024-08-31
==========
* Drop node <18
* Use `content-type@^1.0.5` and `media-typer@^1.0.0` for type validation
- No behavior changes, upgrades `media-typer`
* deps: mime-types@^3.0.0
- Add `application/toml` with extension `.toml`
- Add `application/ubjson` with extension `.ubj`
- Add `application/x-keepass2` with extension `.kdbx`
- Add deprecated iWorks mime types and extensions
- Add extension `.amr` to `audio/amr`
- Add extension `.cjs` to `application/node`
- Add extension `.dbf` to `application/vnd.dbf`
- Add extension `.m4s` to `video/iso.segment`
- Add extension `.mvt` to `application/vnd.mapbox-vector-tile`
- Add extension `.mxmf` to `audio/mobile-xmf`
- Add extension `.opus` to `audio/ogg`
- Add extension `.rar` to `application/vnd.rar`
- Add extension `.td` to `application/urc-targetdesc+xml`
- Add extension `.trig` to `application/trig`
- Add extensions from IANA for `application/*+xml` types
- Add `image/avif` with extension `.avif`
- Add `image/ktx2` with extension `.ktx2`
- Add `image/vnd.ms-dds` with extension `.dds`
- Add new upstream MIME types
- Fix extension of `application/vnd.apple.keynote` to be `.key`
- Remove ambigious extensions from IANA for `application/*+xml` types
- Update primary extension to `.es` for `application/ecmascript`
1.6.18 / 2019-04-26
===================
* Fix regression passing request object to `typeis.is`
1.6.17 / 2019-04-25
===================
* deps: mime-types@~2.1.24
- Add Apple file extensions from IANA
- Add extension `.csl` to `application/vnd.citationstyles.style+xml`
- Add extension `.es` to `application/ecmascript`
- Add extension `.nq` to `application/n-quads`
- Add extension `.nt` to `application/n-triples`
- Add extension `.owl` to `application/rdf+xml`
- Add extensions `.siv` and `.sieve` to `application/sieve`
- Add extensions from IANA for `image/*` types
- Add extensions from IANA for `model/*` types
- Add extensions to HEIC image types
- Add new mime types
- Add `text/mdx` with extension `.mdx`
* perf: prevent internal `throw` on invalid type
1.6.16 / 2018-02-16
===================
* deps: mime-types@~2.1.18
- Add `application/raml+yaml` with extension `.raml`
- Add `application/wasm` with extension `.wasm`
- Add `text/shex` with extension `.shex`
- Add extensions for JPEG-2000 images
- Add extensions from IANA for `message/*` types
- Add extension `.mjs` to `application/javascript`
- Add extension `.wadl` to `application/vnd.sun.wadl+xml`
- Add extension `.gz` to `application/gzip`
- Add glTF types and extensions
- Add new mime types
- Update extensions `.md` and `.markdown` to be `text/markdown`
- Update font MIME types
- Update `text/hjson` to registered `application/hjson`
1.6.15 / 2017-03-31
===================
* deps: mime-types@~2.1.15
- Add new mime types
1.6.14 / 2016-11-18
===================
* deps: mime-types@~2.1.13
- Add new mime types
1.6.13 / 2016-05-18
===================
* deps: mime-types@~2.1.11
- Add new mime types
1.6.12 / 2016-02-28
===================
* deps: mime-types@~2.1.10
- Add new mime types
- Fix extension of `application/dash+xml`
- Update primary extension for `audio/mp4`
1.6.11 / 2016-01-29
===================
* deps: mime-types@~2.1.9
- Add new mime types
1.6.10 / 2015-12-01
===================
* deps: mime-types@~2.1.8
- Add new mime types
1.6.9 / 2015-09-27
==================
* deps: mime-types@~2.1.7
- Add new mime types
1.6.8 / 2015-09-04
==================
* deps: mime-types@~2.1.6
- Add new mime types
1.6.7 / 2015-08-20
==================
* Fix type error when given invalid type to match against
* deps: mime-types@~2.1.5
- Add new mime types
1.6.6 / 2015-07-31
==================
* deps: mime-types@~2.1.4
- Add new mime types
1.6.5 / 2015-07-16
==================
* deps: mime-types@~2.1.3
- Add new mime types
1.6.4 / 2015-07-01
==================
* deps: mime-types@~2.1.2
- Add new mime types
* perf: enable strict mode
* perf: remove argument reassignment
1.6.3 / 2015-06-08
==================
* deps: mime-types@~2.1.1
- Add new mime types
* perf: reduce try block size
* perf: remove bitwise operations
1.6.2 / 2015-05-10
==================
* deps: mime-types@~2.0.11
- Add new mime types
1.6.1 / 2015-03-13
==================
* deps: mime-types@~2.0.10
- Add new mime types
1.6.0 / 2015-02-12
==================
* fix false-positives in `hasBody` `Transfer-Encoding` check
* support wildcard for both type and subtype (`*/*`)
1.5.7 / 2015-02-09
==================
* fix argument reassignment
* deps: mime-types@~2.0.9
- Add new mime types
1.5.6 / 2015-01-29
==================
* deps: mime-types@~2.0.8
- Add new mime types
1.5.5 / 2014-12-30
==================
* deps: mime-types@~2.0.7
- Add new mime types
- Fix missing extensions
- Fix various invalid MIME type entries
- Remove example template MIME types
- deps: mime-db@~1.5.0
1.5.4 / 2014-12-10
==================
* deps: mime-types@~2.0.4
- Add new mime types
- deps: mime-db@~1.3.0
1.5.3 / 2014-11-09
==================
* deps: mime-types@~2.0.3
- Add new mime types
- deps: mime-db@~1.2.0
1.5.2 / 2014-09-28
==================
* deps: mime-types@~2.0.2
- Add new mime types
- deps: mime-db@~1.1.0
1.5.1 / 2014-09-07
==================
* Support Node.js 0.6
* deps: media-typer@0.3.0
* deps: mime-types@~2.0.1
- Support Node.js 0.6
1.5.0 / 2014-09-05
==================
* fix `hasbody` to be true for `content-length: 0`
1.4.0 / 2014-09-02
==================
* update mime-types
1.3.2 / 2014-06-24
==================
* use `~` range on mime-types
1.3.1 / 2014-06-19
==================
* fix global variable leak
1.3.0 / 2014-06-19
==================
* improve type parsing
- invalid media type never matches
- media type not case-sensitive
- extra LWS does not affect results
1.2.2 / 2014-06-19
==================
* fix behavior on unknown type argument
1.2.1 / 2014-06-03
==================
* switch dependency from `mime` to `mime-types@1.0.0`
1.2.0 / 2014-05-11
==================
* support suffix matching:
- `+json` matches `application/vnd+json`
- `*/vnd+json` matches `application/vnd+json`
- `application/*+json` matches `application/vnd+json`
1.1.0 / 2014-04-12
==================
* add non-array values support
* expose internal utilities:
- `.is()`
- `.hasBody()`
- `.normalize()`
- `.match()`
1.0.1 / 2014-03-30
==================
* add `multipart` as a shorthand

23
node_modules/express/node_modules/type-is/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

198
node_modules/express/node_modules/type-is/README.md generated vendored Normal file
View File

@@ -0,0 +1,198 @@
# type-is
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][ci-image]][ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Infer the content-type of a request.
## Install
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install type-is
```
## API
```js
var http = require('http')
var typeis = require('type-is')
http.createServer(function (req, res) {
var istext = typeis(req, ['text/*'])
res.end('you ' + (istext ? 'sent' : 'did not send') + ' me text')
})
```
### typeis(request, types)
Checks if the `request` is one of the `types`. If the request has no body,
even if there is a `Content-Type` header, then `null` is returned. If the
`Content-Type` header is invalid or does not matches any of the `types`, then
`false` is returned. Otherwise, a string of the type that matched is returned.
The `request` argument is expected to be a Node.js HTTP request. The `types`
argument is an array of type strings.
Each type in the `types` array can be one of the following:
- A file extension name such as `json`. This name will be returned if matched.
- A mime type such as `application/json`.
- A mime type with a wildcard such as `*/*` or `*/json` or `application/*`.
The full mime type will be returned if matched.
- A suffix such as `+json`. This can be combined with a wildcard such as
`*/vnd+json` or `application/*+json`. The full mime type will be returned
if matched.
Some examples to illustrate the inputs and returned value:
```js
// req.headers.content-type = 'application/json'
typeis(req, ['json']) // => 'json'
typeis(req, ['html', 'json']) // => 'json'
typeis(req, ['application/*']) // => 'application/json'
typeis(req, ['application/json']) // => 'application/json'
typeis(req, ['html']) // => false
```
### typeis.hasBody(request)
Returns a Boolean if the given `request` has a body, regardless of the
`Content-Type` header.
Having a body has no relation to how large the body is (it may be 0 bytes).
This is similar to how file existence works. If a body does exist, then this
indicates that there is data to read from the Node.js request stream.
```js
if (typeis.hasBody(req)) {
// read the body, since there is one
req.on('data', function (chunk) {
// ...
})
}
```
### typeis.is(mediaType, types)
Checks if the `mediaType` is one of the `types`. If the `mediaType` is invalid
or does not matches any of the `types`, then `false` is returned. Otherwise, a
string of the type that matched is returned.
The `mediaType` argument is expected to be a
[media type](https://tools.ietf.org/html/rfc6838) string. The `types` argument
is an array of type strings.
Each type in the `types` array can be one of the following:
- A file extension name such as `json`. This name will be returned if matched.
- A mime type such as `application/json`.
- A mime type with a wildcard such as `*/*` or `*/json` or `application/*`.
The full mime type will be returned if matched.
- A suffix such as `+json`. This can be combined with a wildcard such as
`*/vnd+json` or `application/*+json`. The full mime type will be returned
if matched.
Some examples to illustrate the inputs and returned value:
```js
var mediaType = 'application/json'
typeis.is(mediaType, ['json']) // => 'json'
typeis.is(mediaType, ['html', 'json']) // => 'json'
typeis.is(mediaType, ['application/*']) // => 'application/json'
typeis.is(mediaType, ['application/json']) // => 'application/json'
typeis.is(mediaType, ['html']) // => false
```
### typeis.match(expected, actual)
Match the type string `expected` with `actual`, taking in to account wildcards.
A wildcard can only be in the type of the subtype part of a media type and only
in the `expected` value (as `actual` should be the real media type to match). A
suffix can still be included even with a wildcard subtype. If an input is
malformed, `false` will be returned.
```js
typeis.match('text/html', 'text/html') // => true
typeis.match('*/html', 'text/html') // => true
typeis.match('text/*', 'text/html') // => true
typeis.match('*/*', 'text/html') // => true
typeis.match('*/*+json', 'application/x-custom+json') // => true
```
### typeis.normalize(type)
Normalize a `type` string. This works by performing the following:
- If the `type` is not a string, `false` is returned.
- If the string starts with `+` (so it is a `+suffix` shorthand like `+json`),
then it is expanded to contain the complete wildcard notation of `*/*+suffix`.
- If the string contains a `/`, then it is returned as the type.
- Else the string is assumed to be a file extension and the mapped media type is
returned, or `false` is there is no mapping.
This includes two special mappings:
- `'multipart'` -> `'multipart/*'`
- `'urlencoded'` -> `'application/x-www-form-urlencoded'`
## Examples
### Example body parser
```js
var express = require('express')
var typeis = require('type-is')
var app = express()
app.use(function bodyParser (req, res, next) {
if (!typeis.hasBody(req)) {
return next()
}
switch (typeis(req, ['urlencoded', 'json', 'multipart'])) {
case 'urlencoded':
// parse urlencoded body
throw new Error('implement urlencoded body parsing')
case 'json':
// parse json body
throw new Error('implement json body parsing')
case 'multipart':
// parse multipart body
throw new Error('implement multipart body parsing')
default:
// 415 error code
res.statusCode = 415
res.end()
break
}
})
```
## License
[MIT](LICENSE)
[ci-image]: https://badgen.net/github/checks/jshttp/type-is/master?label=ci
[ci-url]: https://github.com/jshttp/type-is/actions/workflows/ci.yml
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/type-is/master
[coveralls-url]: https://coveralls.io/r/jshttp/type-is?branch=master
[node-version-image]: https://badgen.net/npm/node/type-is
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/type-is
[npm-url]: https://npmjs.org/package/type-is
[npm-version-image]: https://badgen.net/npm/v/type-is
[travis-image]: https://badgen.net/travis/jshttp/type-is/master
[travis-url]: https://travis-ci.org/jshttp/type-is

250
node_modules/express/node_modules/type-is/index.js generated vendored Normal file
View File

@@ -0,0 +1,250 @@
/*!
* type-is
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var contentType = require('content-type')
var mime = require('mime-types')
var typer = require('media-typer')
/**
* Module exports.
* @public
*/
module.exports = typeofrequest
module.exports.is = typeis
module.exports.hasBody = hasbody
module.exports.normalize = normalize
module.exports.match = mimeMatch
/**
* Compare a `value` content-type with `types`.
* Each `type` can be an extension like `html`,
* a special shortcut like `multipart` or `urlencoded`,
* or a mime type.
*
* If no types match, `false` is returned.
* Otherwise, the first `type` that matches is returned.
*
* @param {String} value
* @param {Array} types
* @public
*/
function typeis (value, types_) {
var i
var types = types_
// remove parameters and normalize
var val = tryNormalizeType(value)
// no type or invalid
if (!val) {
return false
}
// support flattened arguments
if (types && !Array.isArray(types)) {
types = new Array(arguments.length - 1)
for (i = 0; i < types.length; i++) {
types[i] = arguments[i + 1]
}
}
// no types, return the content type
if (!types || !types.length) {
return val
}
var type
for (i = 0; i < types.length; i++) {
if (mimeMatch(normalize(type = types[i]), val)) {
return type[0] === '+' || type.indexOf('*') !== -1
? val
: type
}
}
// no matches
return false
}
/**
* Check if a request has a request body.
* A request with a body __must__ either have `transfer-encoding`
* or `content-length` headers set.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
*
* @param {Object} request
* @return {Boolean}
* @public
*/
function hasbody (req) {
return req.headers['transfer-encoding'] !== undefined ||
!isNaN(req.headers['content-length'])
}
/**
* Check if the incoming request contains the "Content-Type"
* header field, and it contains any of the give mime `type`s.
* If there is no request body, `null` is returned.
* If there is no content type, `false` is returned.
* Otherwise, it returns the first `type` that matches.
*
* Examples:
*
* // With Content-Type: text/html; charset=utf-8
* this.is('html'); // => 'html'
* this.is('text/html'); // => 'text/html'
* this.is('text/*', 'application/json'); // => 'text/html'
*
* // When Content-Type is application/json
* this.is('json', 'urlencoded'); // => 'json'
* this.is('application/json'); // => 'application/json'
* this.is('html', 'application/*'); // => 'application/json'
*
* this.is('html'); // => false
*
* @param {Object} req
* @param {(String|Array)} types...
* @return {(String|false|null)}
* @public
*/
function typeofrequest (req, types_) {
// no body
if (!hasbody(req)) return null
// support flattened arguments
var types = arguments.length > 2
? Array.prototype.slice.call(arguments, 1)
: types_
// request content type
var value = req.headers['content-type']
return typeis(value, types)
}
/**
* Normalize a mime type.
* If it's a shorthand, expand it to a valid mime type.
*
* In general, you probably want:
*
* var type = is(req, ['urlencoded', 'json', 'multipart']);
*
* Then use the appropriate body parsers.
* These three are the most common request body types
* and are thus ensured to work.
*
* @param {String} type
* @return {String|false|null}
* @public
*/
function normalize (type) {
if (typeof type !== 'string') {
// invalid type
return false
}
switch (type) {
case 'urlencoded':
return 'application/x-www-form-urlencoded'
case 'multipart':
return 'multipart/*'
}
if (type[0] === '+') {
// "+json" -> "*/*+json" expando
return '*/*' + type
}
return type.indexOf('/') === -1
? mime.lookup(type)
: type
}
/**
* Check if `expected` mime type
* matches `actual` mime type with
* wildcard and +suffix support.
*
* @param {String} expected
* @param {String} actual
* @return {Boolean}
* @public
*/
function mimeMatch (expected, actual) {
// invalid type
if (expected === false) {
return false
}
// split types
var actualParts = actual.split('/')
var expectedParts = expected.split('/')
// invalid format
if (actualParts.length !== 2 || expectedParts.length !== 2) {
return false
}
// validate type
if (expectedParts[0] !== '*' && expectedParts[0] !== actualParts[0]) {
return false
}
// validate suffix wildcard
if (expectedParts[1].slice(0, 2) === '*+') {
return expectedParts[1].length <= actualParts[1].length + 1 &&
expectedParts[1].slice(1) === actualParts[1].slice(1 - expectedParts[1].length)
}
// validate subtype
if (expectedParts[1] !== '*' && expectedParts[1] !== actualParts[1]) {
return false
}
return true
}
/**
* Normalize a type and remove parameters.
*
* @param {string} value
* @return {(string|null)}
* @private
*/
function normalizeType (value) {
// Parse the type
var type = contentType.parse(value).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
}
}

View File

@@ -0,0 +1,50 @@
1.1.0 / 2019-04-24
==================
* Add `test(string)` function
1.0.2 / 2019-04-19
==================
* Fix JSDoc comment for `parse` function
1.0.1 / 2018-10-20
==================
* Remove left over `parameters` property from class
1.0.0 / 2018-10-20
==================
This major release brings the module back to it's RFC 6838 roots. If you want
a module to parse the `Content-Type` or similar HTTP headers, use the
`content-type` module instead.
* Drop support for Node.js below 0.8
* Remove parameter handling, which is outside RFC 6838 scope
* Remove `parse(req)` and `parse(res)` signatures
* perf: enable strict mode
* perf: use a class for object creation
0.3.0 / 2014-09-07
==================
* Support Node.js 0.6
* Throw error when parameter format invalid on parse
0.2.0 / 2014-06-18
==================
* Add `typer.format()` to format media types
0.1.0 / 2014-06-17
==================
* Accept `req` as argument to `parse`
* Accept `res` as argument to `parse`
* Parse media type with extra LWS between type and first parameter
0.0.0 / 2014-06-13
==================
* Initial implementation

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014-2017 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.

View File

@@ -0,0 +1,93 @@
# media-typer
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Simple RFC 6838 media type parser.
This module will parse a given media type into it's component parts, like type,
subtype, and suffix. A formatter is also provided to put them back together and
the two can be combined to normalize media types into a canonical form.
If you are looking to parse the string that represents a media type and it's
parameters in HTTP (for example, the `Content-Type` header), use the
[content-type module](https://www.npmjs.com/package/content-type).
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install media-typer
```
## API
<!-- eslint-disable no-unused-vars -->
```js
var typer = require('media-typer')
```
### typer.parse(string)
<!-- eslint-disable no-undef, no-unused-vars -->
```js
var obj = typer.parse('image/svg+xml')
```
Parse a media type string. This will return an object with the following
properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`):
- `type`: The type of the media type (always lower case). Example: `'image'`
- `subtype`: The subtype of the media type (always lower case). Example: `'svg'`
- `suffix`: The suffix of the media type (always lower case). Example: `'xml'`
If the given type string is invalid, then a `TypeError` is thrown.
### typer.format(obj)
<!-- eslint-disable no-undef, no-unused-vars -->
```js
var obj = typer.format({ type: 'image', subtype: 'svg', suffix: 'xml' })
```
Format an object into a media type string. This will return a string of the
mime type for the given object. For the properties of the object, see the
documentation for `typer.parse(string)`.
If any of the given object values are invalid, then a `TypeError` is thrown.
### typer.test(string)
<!-- eslint-disable no-undef, no-unused-vars -->
```js
var valid = typer.test('image/svg+xml')
```
Validate a media type string. This will return `true` is the string is a well-
formatted media type, or `false` otherwise.
## License
[MIT](LICENSE)
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/media-typer/master
[coveralls-url]: https://coveralls.io/r/jshttp/media-typer?branch=master
[node-version-image]: https://badgen.net/npm/node/media-typer
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/media-typer
[npm-url]: https://npmjs.org/package/media-typer
[npm-version-image]: https://badgen.net/npm/v/media-typer
[travis-image]: https://badgen.net/travis/jshttp/media-typer/master
[travis-url]: https://travis-ci.org/jshttp/media-typer

View File

@@ -0,0 +1,143 @@
/*!
* media-typer
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* RegExp to match type in RFC 6838
*
* type-name = restricted-name
* subtype-name = restricted-name
* restricted-name = restricted-name-first *126restricted-name-chars
* restricted-name-first = ALPHA / DIGIT
* restricted-name-chars = ALPHA / DIGIT / "!" / "#" /
* "$" / "&" / "-" / "^" / "_"
* restricted-name-chars =/ "." ; Characters before first dot always
* ; specify a facet name
* restricted-name-chars =/ "+" ; Characters after last plus always
* ; specify a structured syntax suffix
* ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
* DIGIT = %x30-39 ; 0-9
*/
var SUBTYPE_NAME_REGEXP = /^[A-Za-z0-9][A-Za-z0-9!#$&^_.-]{0,126}$/
var TYPE_NAME_REGEXP = /^[A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126}$/
var TYPE_REGEXP = /^ *([A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126})\/([A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}) *$/
/**
* Module exports.
*/
exports.format = format
exports.parse = parse
exports.test = test
/**
* Format object to media type.
*
* @param {object} obj
* @return {string}
* @public
*/
function format (obj) {
if (!obj || typeof obj !== 'object') {
throw new TypeError('argument obj is required')
}
var subtype = obj.subtype
var suffix = obj.suffix
var type = obj.type
if (!type || !TYPE_NAME_REGEXP.test(type)) {
throw new TypeError('invalid type')
}
if (!subtype || !SUBTYPE_NAME_REGEXP.test(subtype)) {
throw new TypeError('invalid subtype')
}
// format as type/subtype
var string = type + '/' + subtype
// append +suffix
if (suffix) {
if (!TYPE_NAME_REGEXP.test(suffix)) {
throw new TypeError('invalid suffix')
}
string += '+' + suffix
}
return string
}
/**
* Test media type.
*
* @param {string} string
* @return {object}
* @public
*/
function test (string) {
if (!string) {
throw new TypeError('argument string is required')
}
if (typeof string !== 'string') {
throw new TypeError('argument string is required to be a string')
}
return TYPE_REGEXP.test(string.toLowerCase())
}
/**
* Parse media type to object.
*
* @param {string} string
* @return {object}
* @public
*/
function parse (string) {
if (!string) {
throw new TypeError('argument string is required')
}
if (typeof string !== 'string') {
throw new TypeError('argument string is required to be a string')
}
var match = TYPE_REGEXP.exec(string.toLowerCase())
if (!match) {
throw new TypeError('invalid media type')
}
var type = match[1]
var subtype = match[2]
var suffix
// suffix after last +
var index = subtype.lastIndexOf('+')
if (index !== -1) {
suffix = subtype.substr(index + 1)
subtype = subtype.substr(0, index)
}
return new MediaType(type, subtype, suffix)
}
/**
* Class for MediaType object.
* @public
*/
function MediaType (type, subtype, suffix) {
this.type = type
this.subtype = subtype
this.suffix = suffix
}

View File

@@ -0,0 +1,33 @@
{
"name": "media-typer",
"description": "Simple RFC 6838 media type parser and formatter",
"version": "1.1.0",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"repository": "jshttp/media-typer",
"devDependencies": {
"eslint": "5.16.0",
"eslint-config-standard": "12.0.0",
"eslint-plugin-import": "2.17.2",
"eslint-plugin-markdown": "1.0.0",
"eslint-plugin-node": "8.0.1",
"eslint-plugin-promise": "4.1.1",
"eslint-plugin-standard": "4.0.0",
"mocha": "6.1.4",
"nyc": "14.0.0"
},
"files": [
"LICENSE",
"HISTORY.md",
"index.js"
],
"engines": {
"node": ">= 0.8"
},
"scripts": {
"lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"test-travis": "nyc --reporter=text npm test"
}
}

47
node_modules/express/node_modules/type-is/package.json generated vendored Normal file
View File

@@ -0,0 +1,47 @@
{
"name": "type-is",
"description": "Infer the content-type of a request.",
"version": "2.0.1",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
],
"license": "MIT",
"repository": "jshttp/type-is",
"dependencies": {
"content-type": "^1.0.5",
"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-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",
"nyc": "15.1.0"
},
"engines": {
"node": ">= 0.6"
},
"files": [
"LICENSE",
"HISTORY.md",
"index.js"
],
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test:debug": "mocha --reporter spec --check-leaks --inspect --inspect-brk test/",
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
},
"keywords": [
"content",
"type",
"checking"
]
}

99
node_modules/express/package.json generated vendored Normal file
View File

@@ -0,0 +1,99 @@
{
"name": "express",
"description": "Fast, unopinionated, minimalist web framework",
"version": "5.2.1",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
"Ciaran Jessup <ciaranj@gmail.com>",
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Guillermo Rauch <rauchg@gmail.com>",
"Jonathan Ong <me@jongleberry.com>",
"Roman Shtylman <shtylman+expressjs@gmail.com>",
"Young Jae Sim <hanul@hanul.me>"
],
"license": "MIT",
"repository": "expressjs/express",
"homepage": "https://expressjs.com/",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
},
"keywords": [
"express",
"framework",
"sinatra",
"web",
"http",
"rest",
"restful",
"router",
"app",
"api"
],
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.1",
"content-disposition": "^1.0.0",
"content-type": "^1.0.5",
"cookie": "^0.7.1",
"cookie-signature": "^1.2.1",
"debug": "^4.4.0",
"depd": "^2.0.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"finalhandler": "^2.1.0",
"fresh": "^2.0.0",
"http-errors": "^2.0.0",
"merge-descriptors": "^2.0.0",
"mime-types": "^3.0.0",
"on-finished": "^2.4.1",
"once": "^1.4.0",
"parseurl": "^1.3.3",
"proxy-addr": "^2.0.7",
"qs": "^6.14.0",
"range-parser": "^1.2.1",
"router": "^2.2.0",
"send": "^1.1.0",
"serve-static": "^2.2.0",
"statuses": "^2.0.1",
"type-is": "^2.0.1",
"vary": "^1.1.2"
},
"devDependencies": {
"after": "0.8.2",
"connect-redis": "^8.0.1",
"cookie-parser": "1.4.7",
"cookie-session": "2.1.1",
"ejs": "^3.1.10",
"eslint": "8.47.0",
"express-session": "^1.18.1",
"hbs": "4.2.0",
"marked": "^15.0.3",
"method-override": "3.0.0",
"mocha": "^10.7.3",
"morgan": "1.10.1",
"nyc": "^17.1.0",
"pbkdf2-password": "1.2.1",
"supertest": "^6.3.0",
"vhost": "~3.0.2"
},
"engines": {
"node": ">= 18"
},
"files": [
"LICENSE",
"Readme.md",
"index.js",
"lib/"
],
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test": "mocha --require test/support/env --reporter spec --check-leaks test/ test/acceptance/",
"test-ci": "nyc --exclude examples --exclude test --exclude benchmarks --reporter=lcovonly --reporter=text npm test",
"test-cov": "nyc --exclude examples --exclude test --exclude benchmarks --reporter=html --reporter=text npm test",
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
}
}