aboutsummaryrefslogtreecommitdiffstats
path: root/node_modules/router
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--node_modules/router/HISTORY.md228
-rw-r--r--node_modules/router/LICENSE23
-rw-r--r--node_modules/router/README.md416
-rw-r--r--node_modules/router/index.js748
-rw-r--r--node_modules/router/lib/layer.js247
-rw-r--r--node_modules/router/lib/route.js242
-rw-r--r--node_modules/router/package.json44
7 files changed, 1948 insertions, 0 deletions
diff --git a/node_modules/router/HISTORY.md b/node_modules/router/HISTORY.md
new file mode 100644
index 0000000..b292257
--- /dev/null
+++ b/node_modules/router/HISTORY.md
@@ -0,0 +1,228 @@
+2.2.0 / 2025-03-26
+==================
+
+* Remove `setImmediate` support check
+* Restore `debug` dependency
+
+2.1.0 / 2025-02-10
+==================
+
+* Updated `engines` field to Node@18 or higher
+* Remove `Object.setPrototypeOf` polyfill
+* Use `Array.flat` instead of `array-flatten` package
+* Replace `methods` dependency with standard library
+* deps: parseurl@^1.3.3
+* deps: is-promise@^4.0.0
+* Replace `utils-merge` dependency with `Object.assign`
+* deps: Remove unused dep `after`
+
+2.0.0 / 2024-09-09
+==================
+
+* Drop support for node <18
+* deps: path-to-regexp@^8.0.0
+ - Drop support for partial capture group `router.route('/user(s?)/:user/:op')` but still have optional non-capture `/user{s}/:user/:op`
+ - `:name?` becomes `{:name}`
+ - `:name*` becomes `*name`.
+ - The splat change also changes splat from strings to an array of strings
+ - Optional splats become `{*name}`
+ - `:name+` becomes `*name` and thus equivalent to `*name` so I dropped those tests
+ - Strings as regular expressions are fully removed, need to be converted to native regular expressions
+
+2.0.0-beta.2 / 2024-03-20
+=========================
+
+This incorporates all changes after 1.3.5 up to 1.3.8.
+
+ * Add support for returned, rejected Promises to `router.param`
+
+2.0.0-beta.1 / 2020-03-29
+=========================
+
+This incorporates all changes after 1.3.3 up to 1.3.5.
+
+ * Internalize private `router.process_params` method
+ * Remove `debug` dependency
+ * deps: array-flatten@3.0.0
+ * deps: parseurl@~1.3.3
+ * deps: path-to-regexp@3.2.0
+ - Add new `?`, `*`, and `+` parameter modifiers.
+ - Matching group expressions are only RegExp syntax.
+ `(*)` is no longer valid and must be written as `(.*)`, for example.
+ - Named matching groups no longer available by position in `req.params`.
+ `/:foo(.*)` only captures as `req.params.foo` and not available as
+ `req.params[0]`.
+ - Regular expressions can only be used in a matching group.
+ `/\\d+` is no longer valid and must be written as `/(\\d+)`.
+ - Matching groups are now literal regular expressions.
+ `:foo` named captures can no longer be included inside a capture group.
+ - Special `*` path segment behavior removed.
+ `/foo/*/bar` will match a literal `*` as the middle segment.
+ * deps: setprototypeof@1.2.0
+
+2.0.0-alpha.1 / 2018-07-27
+==========================
+
+ * Add basic support for returned, rejected Promises
+ - Rejected Promises from middleware functions `next(error)`
+ * Drop support for Node.js below 0.10
+ * deps: debug@3.1.0
+ - Add `DEBUG_HIDE_DATE` environment variable
+ - Change timer to per-namespace instead of global
+ - Change non-TTY date format
+ - Remove `DEBUG_FD` environment variable support
+ - Support 256 namespace colors
+
+1.3.8 / 2023-02-24
+==================
+
+ * Fix routing requests without method
+
+1.3.7 / 2022-04-28
+==================
+
+ * Fix hanging on large stack of sync routes
+
+1.3.6 / 2021-11-15
+==================
+
+ * Fix handling very large stacks of sync middleware
+ * deps: safe-buffer@5.2.1
+
+1.3.5 / 2020-03-24
+==================
+
+ * Fix incorrect middleware execution with unanchored `RegExp`s
+ * perf: use plain object for internal method map
+
+1.3.4 / 2020-01-24
+==================
+
+ * deps: array-flatten@3.0.0
+ * deps: parseurl@~1.3.3
+ * deps: setprototypeof@1.2.0
+
+1.3.3 / 2018-07-06
+==================
+
+ * Fix JSDoc for `Router` constructor
+
+1.3.2 / 2017-09-24
+==================
+
+ * deps: debug@2.6.9
+ * deps: parseurl@~1.3.2
+ - perf: reduce overhead for full URLs
+ - perf: unroll the "fast-path" `RegExp`
+ * deps: setprototypeof@1.1.0
+ * deps: utils-merge@1.0.1
+
+1.3.1 / 2017-05-19
+==================
+
+ * deps: debug@2.6.8
+ - Fix `DEBUG_MAX_ARRAY_LENGTH`
+ - deps: ms@2.0.0
+
+1.3.0 / 2017-02-25
+==================
+
+ * Add `next("router")` to exit from router
+ * Fix case where `router.use` skipped requests routes did not
+ * Use `%o` in path debug to tell types apart
+ * deps: setprototypeof@1.0.3
+ * perf: add fast match path for `*` route
+
+1.2.0 / 2017-02-17
+==================
+
+ * Skip routing when `req.url` is not set
+ * deps: debug@2.6.1
+ - Allow colors in workers
+ - Deprecated `DEBUG_FD` environment variable set to `3` or higher
+ - Fix error when running under React Native
+ - Use same color for same namespace
+ - deps: ms@0.7.2
+
+1.1.5 / 2017-01-28
+==================
+
+ * deps: array-flatten@2.1.1
+ * deps: setprototypeof@1.0.2
+ - Fix using fallback even when native method exists
+
+1.1.4 / 2016-01-21
+==================
+
+ * deps: array-flatten@2.0.0
+ * deps: methods@~1.1.2
+ - perf: enable strict mode
+ * deps: parseurl@~1.3.1
+ - perf: enable strict mode
+
+1.1.3 / 2015-08-02
+==================
+
+ * Fix infinite loop condition using `mergeParams: true`
+ * Fix inner numeric indices incorrectly altering parent `req.params`
+ * deps: array-flatten@1.1.1
+ - perf: enable strict mode
+ * deps: path-to-regexp@0.1.7
+ - Fix regression with escaped round brackets and matching groups
+
+1.1.2 / 2015-07-06
+==================
+
+ * Fix hiding platform issues with `decodeURIComponent`
+ - Only `URIError`s are a 400
+ * Fix using `*` before params in routes
+ * Fix using capture groups before params in routes
+ * deps: path-to-regexp@0.1.6
+ * perf: enable strict mode
+ * perf: remove argument reassignments in routing
+ * perf: skip attempting to decode zero length string
+ * perf: use plain for loops
+
+1.1.1 / 2015-05-25
+==================
+
+ * Fix issue where `next('route')` in `router.param` would incorrectly skip values
+ * deps: array-flatten@1.1.0
+ * deps: debug@~2.2.0
+ - deps: ms@0.7.1
+
+1.1.0 / 2015-04-22
+==================
+
+ * Use `setprototypeof` instead of `__proto__`
+ * deps: debug@~2.1.3
+ - Fix high intensity foreground color for bold
+ - deps: ms@0.7.0
+
+1.0.0 / 2015-01-13
+==================
+
+ * Fix crash from error within `OPTIONS` response handler
+ * deps: array-flatten@1.0.2
+ - Remove redundant code path
+
+1.0.0-beta.3 / 2015-01-11
+=========================
+
+ * Fix duplicate methods appearing in OPTIONS responses
+ * Fix OPTIONS responses to include the HEAD method properly
+ * Remove support for leading colon in `router.param(name, fn)`
+ * Use `array-flatten` for flattening arrays
+ * deps: debug@~2.1.1
+ * deps: methods@~1.1.1
+
+1.0.0-beta.2 / 2014-11-19
+=========================
+
+ * Match routes iteratively to prevent stack overflows
+
+1.0.0-beta.1 / 2014-11-16
+=========================
+
+ * Initial release ported from Express 4.x
+ - Altered to work without Express
diff --git a/node_modules/router/LICENSE b/node_modules/router/LICENSE
new file mode 100644
index 0000000..237e1b6
--- /dev/null
+++ b/node_modules/router/LICENSE
@@ -0,0 +1,23 @@
+(The MIT License)
+
+Copyright (c) 2013 Roman Shtylman
+Copyright (c) 2014-2022 Douglas Christopher Wilson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/router/README.md b/node_modules/router/README.md
new file mode 100644
index 0000000..218fd57
--- /dev/null
+++ b/node_modules/router/README.md
@@ -0,0 +1,416 @@
+# router
+
+[![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]
+
+Simple middleware-style router
+
+## 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):
+
+```bash
+$ npm install router
+```
+
+## API
+
+```js
+var finalhandler = require('finalhandler')
+var http = require('http')
+var Router = require('router')
+
+var router = Router()
+router.get('/', function (req, res) {
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+ res.end('Hello World!')
+})
+
+var server = http.createServer(function (req, res) {
+ router(req, res, finalhandler(req, res))
+})
+
+server.listen(3000)
+```
+
+This module is currently an extracted version from the Express project,
+but with the main change being it can be used with a plain `http.createServer`
+object or other web frameworks by removing Express-specific API calls.
+
+## Router(options)
+
+Options
+
+- `strict` - When `false` trailing slashes are optional (default: `false`)
+- `caseSensitive` - When `true` the routing will be case sensitive. (default: `false`)
+- `mergeParams` - When `true` any `req.params` passed to the router will be
+ merged into the router's `req.params`. (default: `false`) ([example](#example-using-mergeparams))
+
+Returns a function with the signature `router(req, res, callback)` where
+`callback([err])` must be provided to handle errors and fall-through from
+not handling requests.
+
+### router.use([path], ...middleware)
+
+Use the given [middleware function](#middleware) for all http methods on the
+given `path`, defaulting to the root path.
+
+`router` does not automatically see `use` as a handler. As such, it will not
+consider it one for handling `OPTIONS` requests.
+
+* Note: If a `path` is specified, that `path` is stripped from the start of
+ `req.url`.
+
+<!-- eslint-disable no-undef -->
+
+```js
+router.use(function (req, res, next) {
+ // do your things
+
+ // continue to the next middleware
+ // the request will stall if this is not called
+ next()
+
+ // note: you should NOT call `next` if you have begun writing to the response
+})
+```
+
+[Middleware](#middleware) can themselves use `next('router')` at any time to
+exit the current router instance completely, invoking the top-level callback.
+
+### router\[method](path, ...[middleware], handler)
+
+The [http methods](https://github.com/jshttp/methods/blob/master/index.js) provide
+the routing functionality in `router`.
+
+Method middleware and handlers follow usual [middleware](#middleware) behavior,
+except they will only be called when the method and path match the request.
+
+<!-- eslint-disable no-undef -->
+
+```js
+// handle a `GET` request
+router.get('/', function (req, res) {
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+ res.end('Hello World!')
+})
+```
+
+[Middleware](#middleware) given before the handler have one additional trick,
+they may invoke `next('route')`. Calling `next('route')` bypasses the remaining
+middleware and the handler mounted for this route, passing the request to the
+next route suitable for handling this request.
+
+Route handlers and middleware can themselves use `next('router')` at any time
+to exit the current router instance completely, invoking the top-level callback.
+
+### router.param(name, param_middleware)
+
+Maps the specified path parameter `name` to a specialized param-capturing middleware.
+
+This function positions the middleware in the same stack as `.use`.
+
+The function can optionally return a `Promise` object. If a `Promise` object
+is returned from the function, the router will attach an `onRejected` callback
+using `.then`. If the promise is rejected, `next` will be called with the
+rejected value, or an error if the value is falsy.
+
+Parameter mapping is used to provide pre-conditions to routes
+which use normalized placeholders. For example a _:user_id_ parameter
+could automatically load a user's information from the database without
+any additional code:
+
+<!-- eslint-disable no-undef -->
+
+```js
+router.param('user_id', function (req, res, next, id) {
+ User.find(id, function (err, user) {
+ if (err) {
+ return next(err)
+ } else if (!user) {
+ return next(new Error('failed to load user'))
+ }
+ req.user = user
+
+ // continue processing the request
+ next()
+ })
+})
+```
+
+### router.route(path)
+
+Creates an instance of a single `Route` for the given `path`.
+(See `Router.Route` below)
+
+Routes can be used to handle http `methods` with their own, optional middleware.
+
+Using `router.route(path)` is a recommended approach to avoiding duplicate
+route naming and thus typo errors.
+
+<!-- eslint-disable no-undef, no-unused-vars -->
+
+```js
+var api = router.route('/api/')
+```
+
+## Router.Route(path)
+
+Represents a single route as an instance that can be used to handle http
+`methods` with it's own, optional middleware.
+
+### route\[method](handler)
+
+These are functions which you can directly call on a route to register a new
+`handler` for the `method` on the route.
+
+<!-- eslint-disable no-undef -->
+
+```js
+// handle a `GET` request
+var status = router.route('/status')
+
+status.get(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+ res.end('All Systems Green!')
+})
+```
+
+### route.all(handler)
+
+Adds a handler for all HTTP methods to this route.
+
+The handler can behave like middleware and call `next` to continue processing
+rather than responding.
+
+<!-- eslint-disable no-undef -->
+
+```js
+router.route('/')
+ .all(function (req, res, next) {
+ next()
+ })
+ .all(checkSomething)
+ .get(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+ res.end('Hello World!')
+ })
+```
+
+## Middleware
+
+Middleware (and method handlers) are functions that follow specific function
+parameters and have defined behavior when used with `router`. The most common
+format is with three parameters - "req", "res" and "next".
+
+- `req` - This is a [HTTP incoming message](https://nodejs.org/api/http.html#http_http_incomingmessage) instance.
+- `res` - This is a [HTTP server response](https://nodejs.org/api/http.html#http_class_http_serverresponse) instance.
+- `next` - Calling this function that tells `router` to proceed to the next matching middleware or method handler. It accepts an error as the first argument.
+
+The function can optionally return a `Promise` object. If a `Promise` object
+is returned from the function, the router will attach an `onRejected` callback
+using `.then`. If the promise is rejected, `next` will be called with the
+rejected value, or an error if the value is falsy.
+
+Middleware and method handlers can also be defined with four arguments. When
+the function has four parameters defined, the first argument is an error and
+subsequent arguments remain, becoming - "err", "req", "res", "next". These
+functions are "error handling middleware", and can be used for handling
+errors that occurred in previous handlers (E.g. from calling `next(err)`).
+This is most used when you want to define arbitrary rendering of errors.
+
+<!-- eslint-disable no-undef -->
+
+```js
+router.get('/error_route', function (req, res, next) {
+ return next(new Error('Bad Request'))
+})
+
+router.use(function (err, req, res, next) {
+ res.end(err.message) //= > "Bad Request"
+})
+```
+
+Error handling middleware will **only** be invoked when an error was given. As
+long as the error is in the pipeline, normal middleware and handlers will be
+bypassed - only error handling middleware will be invoked with an error.
+
+## Examples
+
+```js
+// import our modules
+var http = require('http')
+var Router = require('router')
+var finalhandler = require('finalhandler')
+var compression = require('compression')
+var bodyParser = require('body-parser')
+
+// store our message to display
+var message = 'Hello World!'
+
+// initialize the router & server and add a final callback.
+var router = Router()
+var server = http.createServer(function onRequest (req, res) {
+ router(req, res, finalhandler(req, res))
+})
+
+// use some middleware and compress all outgoing responses
+router.use(compression())
+
+// handle `GET` requests to `/message`
+router.get('/message', function (req, res) {
+ res.statusCode = 200
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+ res.end(message + '\n')
+})
+
+// create and mount a new router for our API
+var api = Router()
+router.use('/api/', api)
+
+// add a body parsing middleware to our API
+api.use(bodyParser.json())
+
+// handle `PATCH` requests to `/api/set-message`
+api.patch('/set-message', function (req, res) {
+ if (req.body.value) {
+ message = req.body.value
+
+ res.statusCode = 200
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+ res.end(message + '\n')
+ } else {
+ res.statusCode = 400
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+ res.end('Invalid API Syntax\n')
+ }
+})
+
+// make our http server listen to connections
+server.listen(8080)
+```
+
+You can get the message by running this command in your terminal,
+ or navigating to `127.0.0.1:8080` in a web browser.
+```bash
+curl http://127.0.0.1:8080
+```
+
+You can set the message by sending it a `PATCH` request via this command:
+```bash
+curl http://127.0.0.1:8080/api/set-message -X PATCH -H "Content-Type: application/json" -d '{"value":"Cats!"}'
+```
+
+### Example using mergeParams
+
+```js
+var http = require('http')
+var Router = require('router')
+var finalhandler = require('finalhandler')
+
+// this example is about the mergeParams option
+var opts = { mergeParams: true }
+
+// make a router with out special options
+var router = Router(opts)
+var server = http.createServer(function onRequest (req, res) {
+ // set something to be passed into the router
+ req.params = { type: 'kitten' }
+
+ router(req, res, finalhandler(req, res))
+})
+
+router.get('/', function (req, res) {
+ res.statusCode = 200
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+
+ // with respond with the the params that were passed in
+ res.end(req.params.type + '\n')
+})
+
+// make another router with our options
+var handler = Router(opts)
+
+// mount our new router to a route that accepts a param
+router.use('/:path', handler)
+
+handler.get('/', function (req, res) {
+ res.statusCode = 200
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8')
+
+ // will respond with the param of the router's parent route
+ res.end(req.params.path + '\n')
+})
+
+// make our http server listen to connections
+server.listen(8080)
+```
+
+Now you can get the type, or what path you are requesting:
+```bash
+curl http://127.0.0.1:8080
+> kitten
+curl http://127.0.0.1:8080/such_path
+> such_path
+```
+
+### Example of advanced `.route()` usage
+
+This example shows how to implement routes where there is a custom
+handler to execute when the path matched, but no methods matched.
+Without any special handling, this would be treated as just a
+generic non-match by `router` (which typically results in a 404),
+but with a custom handler, a `405 Method Not Allowed` can be sent.
+
+```js
+var http = require('http')
+var finalhandler = require('finalhandler')
+var Router = require('router')
+
+// create the router and server
+var router = new Router()
+var server = http.createServer(function onRequest (req, res) {
+ router(req, res, finalhandler(req, res))
+})
+
+// register a route and add all methods
+router.route('/pet/:id')
+ .get(function (req, res) {
+ // this is GET /pet/:id
+ res.setHeader('Content-Type', 'application/json')
+ res.end(JSON.stringify({ name: 'tobi' }))
+ })
+ .delete(function (req, res) {
+ // this is DELETE /pet/:id
+ res.end()
+ })
+ .all(function (req, res) {
+ // this is called for all other methods not
+ // defined above for /pet/:id
+ res.statusCode = 405
+ res.end()
+ })
+
+// make our http server listen to connections
+server.listen(8080)
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/pillarjs/router/master?label=ci
+[ci-url]: https://github.com/pillarjs/router/actions/workflows/ci.yml
+[npm-image]: https://img.shields.io/npm/v/router.svg
+[npm-url]: https://npmjs.org/package/router
+[node-version-image]: https://img.shields.io/node/v/router.svg
+[node-version-url]: http://nodejs.org/download/
+[coveralls-image]: https://img.shields.io/coveralls/pillarjs/router/master.svg
+[coveralls-url]: https://coveralls.io/r/pillarjs/router?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/router.svg
+[downloads-url]: https://npmjs.org/package/router
diff --git a/node_modules/router/index.js b/node_modules/router/index.js
new file mode 100644
index 0000000..4358aeb
--- /dev/null
+++ b/node_modules/router/index.js
@@ -0,0 +1,748 @@
+/*!
+ * router
+ * Copyright(c) 2013 Roman Shtylman
+ * Copyright(c) 2014-2022 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+const isPromise = require('is-promise')
+const Layer = require('./lib/layer')
+const { METHODS } = require('node:http')
+const parseUrl = require('parseurl')
+const Route = require('./lib/route')
+const debug = require('debug')('router')
+const deprecate = require('depd')('router')
+
+/**
+ * Module variables.
+ * @private
+ */
+
+const slice = Array.prototype.slice
+const flatten = Array.prototype.flat
+const methods = METHODS.map((method) => method.toLowerCase())
+
+/**
+ * Expose `Router`.
+ */
+
+module.exports = Router
+
+/**
+ * Expose `Route`.
+ */
+
+module.exports.Route = Route
+
+/**
+ * Initialize a new `Router` with the given `options`.
+ *
+ * @param {object} [options]
+ * @return {Router} which is a callable function
+ * @public
+ */
+
+function Router (options) {
+ if (!(this instanceof Router)) {
+ return new Router(options)
+ }
+
+ const opts = options || {}
+
+ function router (req, res, next) {
+ router.handle(req, res, next)
+ }
+
+ // inherit from the correct prototype
+ Object.setPrototypeOf(router, this)
+
+ router.caseSensitive = opts.caseSensitive
+ router.mergeParams = opts.mergeParams
+ router.params = {}
+ router.strict = opts.strict
+ router.stack = []
+
+ return router
+}
+
+/**
+ * Router prototype inherits from a Function.
+ */
+
+/* istanbul ignore next */
+Router.prototype = function () {}
+
+/**
+ * Map the given param placeholder `name`(s) to the given callback.
+ *
+ * Parameter mapping is used to provide pre-conditions to routes
+ * which use normalized placeholders. For example a _:user_id_ parameter
+ * could automatically load a user's information from the database without
+ * any additional code.
+ *
+ * The callback uses the same signature as middleware, the only difference
+ * being that the value of the placeholder is passed, in this case the _id_
+ * of the user. Once the `next()` function is invoked, just like middleware
+ * it will continue on to execute the route, or subsequent parameter functions.
+ *
+ * Just like in middleware, you must either respond to the request or call next
+ * to avoid stalling the request.
+ *
+ * router.param('user_id', function(req, res, next, id){
+ * User.find(id, function(err, user){
+ * if (err) {
+ * return next(err)
+ * } else if (!user) {
+ * return next(new Error('failed to load user'))
+ * }
+ * req.user = user
+ * next()
+ * })
+ * })
+ *
+ * @param {string} name
+ * @param {function} fn
+ * @public
+ */
+
+Router.prototype.param = function param (name, fn) {
+ if (!name) {
+ throw new TypeError('argument name is required')
+ }
+
+ if (typeof name !== 'string') {
+ throw new TypeError('argument name must be a string')
+ }
+
+ if (!fn) {
+ throw new TypeError('argument fn is required')
+ }
+
+ if (typeof fn !== 'function') {
+ throw new TypeError('argument fn must be a function')
+ }
+
+ let params = this.params[name]
+
+ if (!params) {
+ params = this.params[name] = []
+ }
+
+ params.push(fn)
+
+ return this
+}
+
+/**
+ * Dispatch a req, res into the router.
+ *
+ * @private
+ */
+
+Router.prototype.handle = function handle (req, res, callback) {
+ if (!callback) {
+ throw new TypeError('argument callback is required')
+ }
+
+ debug('dispatching %s %s', req.method, req.url)
+
+ let idx = 0
+ let methods
+ const protohost = getProtohost(req.url) || ''
+ let removed = ''
+ const self = this
+ let slashAdded = false
+ let sync = 0
+ const paramcalled = {}
+
+ // middleware and routes
+ const stack = this.stack
+
+ // manage inter-router variables
+ const parentParams = req.params
+ const parentUrl = req.baseUrl || ''
+ let done = restore(callback, req, 'baseUrl', 'next', 'params')
+
+ // setup next layer
+ req.next = next
+
+ // for options requests, respond with a default if nothing else responds
+ if (req.method === 'OPTIONS') {
+ methods = []
+ done = wrap(done, generateOptionsResponder(res, methods))
+ }
+
+ // setup basic req values
+ req.baseUrl = parentUrl
+ req.originalUrl = req.originalUrl || req.url
+
+ next()
+
+ function next (err) {
+ let layerError = err === 'route'
+ ? null
+ : err
+
+ // remove added slash
+ if (slashAdded) {
+ req.url = req.url.slice(1)
+ slashAdded = false
+ }
+
+ // restore altered req.url
+ if (removed.length !== 0) {
+ req.baseUrl = parentUrl
+ req.url = protohost + removed + req.url.slice(protohost.length)
+ removed = ''
+ }
+
+ // signal to exit router
+ if (layerError === 'router') {
+ setImmediate(done, null)
+ return
+ }
+
+ // no more matching layers
+ if (idx >= stack.length) {
+ setImmediate(done, layerError)
+ return
+ }
+
+ // max sync stack
+ if (++sync > 100) {
+ return setImmediate(next, err)
+ }
+
+ // get pathname of request
+ const path = getPathname(req)
+
+ if (path == null) {
+ return done(layerError)
+ }
+
+ // find next matching layer
+ let layer
+ let match
+ let route
+
+ while (match !== true && idx < stack.length) {
+ layer = stack[idx++]
+ match = matchLayer(layer, path)
+ route = layer.route
+
+ if (typeof match !== 'boolean') {
+ // hold on to layerError
+ layerError = layerError || match
+ }
+
+ if (match !== true) {
+ continue
+ }
+
+ if (!route) {
+ // process non-route handlers normally
+ continue
+ }
+
+ if (layerError) {
+ // routes do not match with a pending error
+ match = false
+ continue
+ }
+
+ const method = req.method
+ const hasMethod = route._handlesMethod(method)
+
+ // build up automatic options response
+ if (!hasMethod && method === 'OPTIONS' && methods) {
+ methods.push.apply(methods, route._methods())
+ }
+
+ // don't even bother matching route
+ if (!hasMethod && method !== 'HEAD') {
+ match = false
+ }
+ }
+
+ // no match
+ if (match !== true) {
+ return done(layerError)
+ }
+
+ // store route for dispatch on change
+ if (route) {
+ req.route = route
+ }
+
+ // Capture one-time layer values
+ req.params = self.mergeParams
+ ? mergeParams(layer.params, parentParams)
+ : layer.params
+ const layerPath = layer.path
+
+ // this should be done for the layer
+ processParams(self.params, layer, paramcalled, req, res, function (err) {
+ if (err) {
+ next(layerError || err)
+ } else if (route) {
+ layer.handleRequest(req, res, next)
+ } else {
+ trimPrefix(layer, layerError, layerPath, path)
+ }
+
+ sync = 0
+ })
+ }
+
+ function trimPrefix (layer, layerError, layerPath, path) {
+ if (layerPath.length !== 0) {
+ // Validate path is a prefix match
+ if (layerPath !== path.substring(0, layerPath.length)) {
+ next(layerError)
+ return
+ }
+
+ // Validate path breaks on a path separator
+ const c = path[layerPath.length]
+ if (c && c !== '/') {
+ next(layerError)
+ return
+ }
+
+ // Trim off the part of the url that matches the route
+ // middleware (.use stuff) needs to have the path stripped
+ debug('trim prefix (%s) from url %s', layerPath, req.url)
+ removed = layerPath
+ req.url = protohost + req.url.slice(protohost.length + removed.length)
+
+ // Ensure leading slash
+ if (!protohost && req.url[0] !== '/') {
+ req.url = '/' + req.url
+ slashAdded = true
+ }
+
+ // Setup base URL (no trailing slash)
+ req.baseUrl = parentUrl + (removed[removed.length - 1] === '/'
+ ? removed.substring(0, removed.length - 1)
+ : removed)
+ }
+
+ debug('%s %s : %s', layer.name, layerPath, req.originalUrl)
+
+ if (layerError) {
+ layer.handleError(layerError, req, res, next)
+ } else {
+ layer.handleRequest(req, res, next)
+ }
+ }
+}
+
+/**
+ * Use the given middleware function, with optional path, defaulting to "/".
+ *
+ * Use (like `.all`) will run for any http METHOD, but it will not add
+ * handlers for those methods so OPTIONS requests will not consider `.use`
+ * functions even if they could respond.
+ *
+ * The other difference is that _route_ path is stripped and not visible
+ * to the handler function. The main effect of this feature is that mounted
+ * handlers can operate without any code changes regardless of the "prefix"
+ * pathname.
+ *
+ * @public
+ */
+
+Router.prototype.use = function use (handler) {
+ let offset = 0
+ let path = '/'
+
+ // default path to '/'
+ // disambiguate router.use([handler])
+ if (typeof handler !== 'function') {
+ let arg = handler
+
+ while (Array.isArray(arg) && arg.length !== 0) {
+ arg = arg[0]
+ }
+
+ // first arg is the path
+ if (typeof arg !== 'function') {
+ offset = 1
+ path = handler
+ }
+ }
+
+ const callbacks = flatten.call(slice.call(arguments, offset), Infinity)
+
+ if (callbacks.length === 0) {
+ throw new TypeError('argument handler is required')
+ }
+
+ for (let i = 0; i < callbacks.length; i++) {
+ const fn = callbacks[i]
+
+ if (typeof fn !== 'function') {
+ throw new TypeError('argument handler must be a function')
+ }
+
+ // add the middleware
+ debug('use %o %s', path, fn.name || '<anonymous>')
+
+ const layer = new Layer(path, {
+ sensitive: this.caseSensitive,
+ strict: false,
+ end: false
+ }, fn)
+
+ layer.route = undefined
+
+ this.stack.push(layer)
+ }
+
+ return this
+}
+
+/**
+ * Create a new Route for the given path.
+ *
+ * Each route contains a separate middleware stack and VERB handlers.
+ *
+ * See the Route api documentation for details on adding handlers
+ * and middleware to routes.
+ *
+ * @param {string} path
+ * @return {Route}
+ * @public
+ */
+
+Router.prototype.route = function route (path) {
+ const route = new Route(path)
+
+ const layer = new Layer(path, {
+ sensitive: this.caseSensitive,
+ strict: this.strict,
+ end: true
+ }, handle)
+
+ function handle (req, res, next) {
+ route.dispatch(req, res, next)
+ }
+
+ layer.route = route
+
+ this.stack.push(layer)
+ return route
+}
+
+// create Router#VERB functions
+methods.concat('all').forEach(function (method) {
+ Router.prototype[method] = function (path) {
+ const route = this.route(path)
+ route[method].apply(route, slice.call(arguments, 1))
+ return this
+ }
+})
+
+/**
+ * Generate a callback that will make an OPTIONS response.
+ *
+ * @param {OutgoingMessage} res
+ * @param {array} methods
+ * @private
+ */
+
+function generateOptionsResponder (res, methods) {
+ return function onDone (fn, err) {
+ if (err || methods.length === 0) {
+ return fn(err)
+ }
+
+ trySendOptionsResponse(res, methods, fn)
+ }
+}
+
+/**
+ * Get pathname of request.
+ *
+ * @param {IncomingMessage} req
+ * @private
+ */
+
+function getPathname (req) {
+ try {
+ return parseUrl(req).pathname
+ } catch (err) {
+ return undefined
+ }
+}
+
+/**
+ * Get get protocol + host for a URL.
+ *
+ * @param {string} url
+ * @private
+ */
+
+function getProtohost (url) {
+ if (typeof url !== 'string' || url.length === 0 || url[0] === '/') {
+ return undefined
+ }
+
+ const searchIndex = url.indexOf('?')
+ const pathLength = searchIndex !== -1
+ ? searchIndex
+ : url.length
+ const fqdnIndex = url.substring(0, pathLength).indexOf('://')
+
+ return fqdnIndex !== -1
+ ? url.substring(0, url.indexOf('/', 3 + fqdnIndex))
+ : undefined
+}
+
+/**
+ * Match path to a layer.
+ *
+ * @param {Layer} layer
+ * @param {string} path
+ * @private
+ */
+
+function matchLayer (layer, path) {
+ try {
+ return layer.match(path)
+ } catch (err) {
+ return err
+ }
+}
+
+/**
+ * Merge params with parent params
+ *
+ * @private
+ */
+
+function mergeParams (params, parent) {
+ if (typeof parent !== 'object' || !parent) {
+ return params
+ }
+
+ // make copy of parent for base
+ const obj = Object.assign({}, parent)
+
+ // simple non-numeric merging
+ if (!(0 in params) || !(0 in parent)) {
+ return Object.assign(obj, params)
+ }
+
+ let i = 0
+ let o = 0
+
+ // determine numeric gap in params
+ while (i in params) {
+ i++
+ }
+
+ // determine numeric gap in parent
+ while (o in parent) {
+ o++
+ }
+
+ // offset numeric indices in params before merge
+ for (i--; i >= 0; i--) {
+ params[i + o] = params[i]
+
+ // create holes for the merge when necessary
+ if (i < o) {
+ delete params[i]
+ }
+ }
+
+ return Object.assign(obj, params)
+}
+
+/**
+ * Process any parameters for the layer.
+ *
+ * @private
+ */
+
+function processParams (params, layer, called, req, res, done) {
+ // captured parameters from the layer, keys and values
+ const keys = layer.keys
+
+ // fast track
+ if (!keys || keys.length === 0) {
+ return done()
+ }
+
+ let i = 0
+ let paramIndex = 0
+ let key
+ let paramVal
+ let paramCallbacks
+ let paramCalled
+
+ // process params in order
+ // param callbacks can be async
+ function param (err) {
+ if (err) {
+ return done(err)
+ }
+
+ if (i >= keys.length) {
+ return done()
+ }
+
+ paramIndex = 0
+ key = keys[i++]
+ paramVal = req.params[key]
+ paramCallbacks = params[key]
+ paramCalled = called[key]
+
+ if (paramVal === undefined || !paramCallbacks) {
+ return param()
+ }
+
+ // param previously called with same value or error occurred
+ if (paramCalled && (paramCalled.match === paramVal ||
+ (paramCalled.error && paramCalled.error !== 'route'))) {
+ // restore value
+ req.params[key] = paramCalled.value
+
+ // next param
+ return param(paramCalled.error)
+ }
+
+ called[key] = paramCalled = {
+ error: null,
+ match: paramVal,
+ value: paramVal
+ }
+
+ paramCallback()
+ }
+
+ // single param callbacks
+ function paramCallback (err) {
+ const fn = paramCallbacks[paramIndex++]
+
+ // store updated value
+ paramCalled.value = req.params[key]
+
+ if (err) {
+ // store error
+ paramCalled.error = err
+ param(err)
+ return
+ }
+
+ if (!fn) return param()
+
+ try {
+ const ret = fn(req, res, paramCallback, paramVal, key)
+ if (isPromise(ret)) {
+ if (!(ret instanceof Promise)) {
+ deprecate('parameters that are Promise-like are deprecated, use a native Promise instead')
+ }
+
+ ret.then(null, function (error) {
+ paramCallback(error || new Error('Rejected promise'))
+ })
+ }
+ } catch (e) {
+ paramCallback(e)
+ }
+ }
+
+ param()
+}
+
+/**
+ * Restore obj props after function
+ *
+ * @private
+ */
+
+function restore (fn, obj) {
+ const props = new Array(arguments.length - 2)
+ const vals = new Array(arguments.length - 2)
+
+ for (let i = 0; i < props.length; i++) {
+ props[i] = arguments[i + 2]
+ vals[i] = obj[props[i]]
+ }
+
+ return function () {
+ // restore vals
+ for (let i = 0; i < props.length; i++) {
+ obj[props[i]] = vals[i]
+ }
+
+ return fn.apply(this, arguments)
+ }
+}
+
+/**
+ * Send an OPTIONS response.
+ *
+ * @private
+ */
+
+function sendOptionsResponse (res, methods) {
+ const options = Object.create(null)
+
+ // build unique method map
+ for (let i = 0; i < methods.length; i++) {
+ options[methods[i]] = true
+ }
+
+ // construct the allow list
+ const allow = Object.keys(options).sort().join(', ')
+
+ // send response
+ res.setHeader('Allow', allow)
+ res.setHeader('Content-Length', Buffer.byteLength(allow))
+ res.setHeader('Content-Type', 'text/plain')
+ res.setHeader('X-Content-Type-Options', 'nosniff')
+ res.end(allow)
+}
+
+/**
+ * Try to send an OPTIONS response.
+ *
+ * @private
+ */
+
+function trySendOptionsResponse (res, methods, next) {
+ try {
+ sendOptionsResponse(res, methods)
+ } catch (err) {
+ next(err)
+ }
+}
+
+/**
+ * Wrap a function
+ *
+ * @private
+ */
+
+function wrap (old, fn) {
+ return function proxy () {
+ const args = new Array(arguments.length + 1)
+
+ args[0] = old
+ for (let i = 0, len = arguments.length; i < len; i++) {
+ args[i + 1] = arguments[i]
+ }
+
+ fn.apply(this, args)
+ }
+}
diff --git a/node_modules/router/lib/layer.js b/node_modules/router/lib/layer.js
new file mode 100644
index 0000000..6a4408f
--- /dev/null
+++ b/node_modules/router/lib/layer.js
@@ -0,0 +1,247 @@
+/*!
+ * router
+ * Copyright(c) 2013 Roman Shtylman
+ * Copyright(c) 2014-2022 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+const isPromise = require('is-promise')
+const pathRegexp = require('path-to-regexp')
+const debug = require('debug')('router:layer')
+const deprecate = require('depd')('router')
+
+/**
+ * Module variables.
+ * @private
+ */
+
+const TRAILING_SLASH_REGEXP = /\/+$/
+const MATCHING_GROUP_REGEXP = /\((?:\?<(.*?)>)?(?!\?)/g
+
+/**
+ * Expose `Layer`.
+ */
+
+module.exports = Layer
+
+function Layer (path, options, fn) {
+ if (!(this instanceof Layer)) {
+ return new Layer(path, options, fn)
+ }
+
+ debug('new %o', path)
+ const opts = options || {}
+
+ this.handle = fn
+ this.keys = []
+ this.name = fn.name || '<anonymous>'
+ this.params = undefined
+ this.path = undefined
+ this.slash = path === '/' && opts.end === false
+
+ function matcher (_path) {
+ if (_path instanceof RegExp) {
+ const keys = []
+ let name = 0
+ let m
+ // eslint-disable-next-line no-cond-assign
+ while (m = MATCHING_GROUP_REGEXP.exec(_path.source)) {
+ keys.push({
+ name: m[1] || name++,
+ offset: m.index
+ })
+ }
+
+ return function regexpMatcher (p) {
+ const match = _path.exec(p)
+ if (!match) {
+ return false
+ }
+
+ const params = {}
+ for (let i = 1; i < match.length; i++) {
+ const key = keys[i - 1]
+ const prop = key.name
+ const val = decodeParam(match[i])
+
+ if (val !== undefined) {
+ params[prop] = val
+ }
+ }
+
+ return {
+ params,
+ path: match[0]
+ }
+ }
+ }
+
+ return pathRegexp.match((opts.strict ? _path : loosen(_path)), {
+ sensitive: opts.sensitive,
+ end: opts.end,
+ trailing: !opts.strict,
+ decode: decodeParam
+ })
+ }
+ this.matchers = Array.isArray(path) ? path.map(matcher) : [matcher(path)]
+}
+
+/**
+ * Handle the error for the layer.
+ *
+ * @param {Error} error
+ * @param {Request} req
+ * @param {Response} res
+ * @param {function} next
+ * @api private
+ */
+
+Layer.prototype.handleError = function handleError (error, req, res, next) {
+ const fn = this.handle
+
+ if (fn.length !== 4) {
+ // not a standard error handler
+ return next(error)
+ }
+
+ try {
+ // invoke function
+ const ret = fn(error, req, res, next)
+
+ // wait for returned promise
+ if (isPromise(ret)) {
+ if (!(ret instanceof Promise)) {
+ deprecate('handlers that are Promise-like are deprecated, use a native Promise instead')
+ }
+
+ ret.then(null, function (error) {
+ next(error || new Error('Rejected promise'))
+ })
+ }
+ } catch (err) {
+ next(err)
+ }
+}
+
+/**
+ * Handle the request for the layer.
+ *
+ * @param {Request} req
+ * @param {Response} res
+ * @param {function} next
+ * @api private
+ */
+
+Layer.prototype.handleRequest = function handleRequest (req, res, next) {
+ const fn = this.handle
+
+ if (fn.length > 3) {
+ // not a standard request handler
+ return next()
+ }
+
+ try {
+ // invoke function
+ const ret = fn(req, res, next)
+
+ // wait for returned promise
+ if (isPromise(ret)) {
+ if (!(ret instanceof Promise)) {
+ deprecate('handlers that are Promise-like are deprecated, use a native Promise instead')
+ }
+
+ ret.then(null, function (error) {
+ next(error || new Error('Rejected promise'))
+ })
+ }
+ } catch (err) {
+ next(err)
+ }
+}
+
+/**
+ * Check if this route matches `path`, if so
+ * populate `.params`.
+ *
+ * @param {String} path
+ * @return {Boolean}
+ * @api private
+ */
+
+Layer.prototype.match = function match (path) {
+ let match
+
+ if (path != null) {
+ // fast path non-ending match for / (any path matches)
+ if (this.slash) {
+ this.params = {}
+ this.path = ''
+ return true
+ }
+
+ let i = 0
+ while (!match && i < this.matchers.length) {
+ // match the path
+ match = this.matchers[i](path)
+ i++
+ }
+ }
+
+ if (!match) {
+ this.params = undefined
+ this.path = undefined
+ return false
+ }
+
+ // store values
+ this.params = match.params
+ this.path = match.path
+ this.keys = Object.keys(match.params)
+
+ return true
+}
+
+/**
+ * Decode param value.
+ *
+ * @param {string} val
+ * @return {string}
+ * @private
+ */
+
+function decodeParam (val) {
+ if (typeof val !== 'string' || val.length === 0) {
+ return val
+ }
+
+ try {
+ return decodeURIComponent(val)
+ } catch (err) {
+ if (err instanceof URIError) {
+ err.message = 'Failed to decode param \'' + val + '\''
+ err.status = 400
+ }
+
+ throw err
+ }
+}
+
+/**
+ * Loosens the given path for path-to-regexp matching.
+ */
+function loosen (path) {
+ if (path instanceof RegExp || path === '/') {
+ return path
+ }
+
+ return Array.isArray(path)
+ ? path.map(function (p) { return loosen(p) })
+ : String(path).replace(TRAILING_SLASH_REGEXP, '')
+}
diff --git a/node_modules/router/lib/route.js b/node_modules/router/lib/route.js
new file mode 100644
index 0000000..1887d78
--- /dev/null
+++ b/node_modules/router/lib/route.js
@@ -0,0 +1,242 @@
+/*!
+ * router
+ * Copyright(c) 2013 Roman Shtylman
+ * Copyright(c) 2014-2022 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+const debug = require('debug')('router:route')
+const Layer = require('./layer')
+const { METHODS } = require('node:http')
+
+/**
+ * Module variables.
+ * @private
+ */
+
+const slice = Array.prototype.slice
+const flatten = Array.prototype.flat
+const methods = METHODS.map((method) => method.toLowerCase())
+
+/**
+ * Expose `Route`.
+ */
+
+module.exports = Route
+
+/**
+ * Initialize `Route` with the given `path`,
+ *
+ * @param {String} path
+ * @api private
+ */
+
+function Route (path) {
+ debug('new %o', path)
+ this.path = path
+ this.stack = []
+
+ // route handlers for various http methods
+ this.methods = Object.create(null)
+}
+
+/**
+ * @private
+ */
+
+Route.prototype._handlesMethod = function _handlesMethod (method) {
+ if (this.methods._all) {
+ return true
+ }
+
+ // normalize name
+ let name = typeof method === 'string'
+ ? method.toLowerCase()
+ : method
+
+ if (name === 'head' && !this.methods.head) {
+ name = 'get'
+ }
+
+ return Boolean(this.methods[name])
+}
+
+/**
+ * @return {array} supported HTTP methods
+ * @private
+ */
+
+Route.prototype._methods = function _methods () {
+ const methods = Object.keys(this.methods)
+
+ // append automatic head
+ if (this.methods.get && !this.methods.head) {
+ methods.push('head')
+ }
+
+ for (let i = 0; i < methods.length; i++) {
+ // make upper case
+ methods[i] = methods[i].toUpperCase()
+ }
+
+ return methods
+}
+
+/**
+ * dispatch req, res into this route
+ *
+ * @private
+ */
+
+Route.prototype.dispatch = function dispatch (req, res, done) {
+ let idx = 0
+ const stack = this.stack
+ let sync = 0
+
+ if (stack.length === 0) {
+ return done()
+ }
+
+ let method = typeof req.method === 'string'
+ ? req.method.toLowerCase()
+ : req.method
+
+ if (method === 'head' && !this.methods.head) {
+ method = 'get'
+ }
+
+ req.route = this
+
+ next()
+
+ function next (err) {
+ // signal to exit route
+ if (err && err === 'route') {
+ return done()
+ }
+
+ // signal to exit router
+ if (err && err === 'router') {
+ return done(err)
+ }
+
+ // no more matching layers
+ if (idx >= stack.length) {
+ return done(err)
+ }
+
+ // max sync stack
+ if (++sync > 100) {
+ return setImmediate(next, err)
+ }
+
+ let layer
+ let match
+
+ // find next matching layer
+ while (match !== true && idx < stack.length) {
+ layer = stack[idx++]
+ match = !layer.method || layer.method === method
+ }
+
+ // no match
+ if (match !== true) {
+ return done(err)
+ }
+
+ if (err) {
+ layer.handleError(err, req, res, next)
+ } else {
+ layer.handleRequest(req, res, next)
+ }
+
+ sync = 0
+ }
+}
+
+/**
+ * Add a handler for all HTTP verbs to this route.
+ *
+ * Behaves just like middleware and can respond or call `next`
+ * to continue processing.
+ *
+ * You can use multiple `.all` call to add multiple handlers.
+ *
+ * function check_something(req, res, next){
+ * next()
+ * }
+ *
+ * function validate_user(req, res, next){
+ * next()
+ * }
+ *
+ * route
+ * .all(validate_user)
+ * .all(check_something)
+ * .get(function(req, res, next){
+ * res.send('hello world')
+ * })
+ *
+ * @param {array|function} handler
+ * @return {Route} for chaining
+ * @api public
+ */
+
+Route.prototype.all = function all (handler) {
+ const callbacks = flatten.call(slice.call(arguments), Infinity)
+
+ if (callbacks.length === 0) {
+ throw new TypeError('argument handler is required')
+ }
+
+ for (let i = 0; i < callbacks.length; i++) {
+ const fn = callbacks[i]
+
+ if (typeof fn !== 'function') {
+ throw new TypeError('argument handler must be a function')
+ }
+
+ const layer = Layer('/', {}, fn)
+ layer.method = undefined
+
+ this.methods._all = true
+ this.stack.push(layer)
+ }
+
+ return this
+}
+
+methods.forEach(function (method) {
+ Route.prototype[method] = function (handler) {
+ const callbacks = flatten.call(slice.call(arguments), Infinity)
+
+ if (callbacks.length === 0) {
+ throw new TypeError('argument handler is required')
+ }
+
+ for (let i = 0; i < callbacks.length; i++) {
+ const fn = callbacks[i]
+
+ if (typeof fn !== 'function') {
+ throw new TypeError('argument handler must be a function')
+ }
+
+ debug('%s %s', method, this.path)
+
+ const layer = Layer('/', {}, fn)
+ layer.method = method
+
+ this.methods[method] = true
+ this.stack.push(layer)
+ }
+
+ return this
+ }
+})
diff --git a/node_modules/router/package.json b/node_modules/router/package.json
new file mode 100644
index 0000000..123eca2
--- /dev/null
+++ b/node_modules/router/package.json
@@ -0,0 +1,44 @@
+{
+ "name": "router",
+ "description": "Simple middleware-style router",
+ "version": "2.2.0",
+ "author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
+ "contributors": [
+ "Blake Embrey <hello@blakeembrey.com>"
+ ],
+ "license": "MIT",
+ "repository": "pillarjs/router",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "devDependencies": {
+ "finalhandler": "^2.1.0",
+ "mocha": "10.2.0",
+ "nyc": "15.1.0",
+ "run-series": "^1.1.9",
+ "standard": "^17.1.0",
+ "supertest": "6.3.3"
+ },
+ "files": [
+ "lib/",
+ "LICENSE",
+ "HISTORY.md",
+ "README.md",
+ "index.js"
+ ],
+ "engines": {
+ "node": ">= 18"
+ },
+ "scripts": {
+ "lint": "standard",
+ "test": "mocha --reporter spec --bail --check-leaks test/",
+ "test:debug": "mocha --reporter spec --bail --check-leaks test/ --inspect --inspect-brk",
+ "test-ci": "nyc --reporter=lcov --reporter=text npm test",
+ "test-cov": "nyc --reporter=text npm test",
+ "version": "node scripts/version-history.js && git add HISTORY.md"
+ }
+}